运输最优化python求解

2020-07-03  本文已影响0人  musaly

知识点:pulp库的运用
程序应用python实现如下功能(推荐使用gurobi工具包)

  1. 输入每个地区的优先级
  2. 得出成本最低的配送方案
  3. 得出总的运送成本
  4. 得出每个地区的物资满足率(即四种物质的满足量/需求量的平均值)
  5. 得出24个地区总的物资满足率

main.py

import get_table_data
import optimize

#获取表格中的信息
path='代码(1).docx'
source={}
water_save=[50000,30000,30000,20000,30000,20000]
meal_save=[6000,4000,3000,3000,4000,5000]
bag_save=[3000,2000,2000,1000,2000,3000]
camp_save=get_table_data.get_data(path,1,[6,2],[6,7])[0]
#可以用面向对面方法优化4个物资函数,本次实验尚未优化
water_need=[x[0] for x in get_table_data.get_data(path,2,[2,2],[25,2])]
water_center=get_table_data.get_data(path,3,[3,2],[8,4],'float')
water_area=get_table_data.get_data(path,7,[4,2],[6,25],'float')
water_to_24=[]
for x in range(6):
    water_to_24.append([])
    for y in range(24):
        tmp=[]
        tmp.append(water_center[x][0]+water_area[0][y])
        tmp.append(water_center[x][1]+water_area[1][y])
        tmp.append(water_center[x][2]+water_area[2][y])
        water_to_24[x].append(round(min(tmp),1))


meal_need=[x[0] for x in get_table_data.get_data(path,2,[2,3],[25,3])]
meal_center=get_table_data.get_data(path,4,[3,2],[8,4],'float')
meal_area=get_table_data.get_data(path,7,[8,2],[10,25],'float')
meal_to_24=[]
for x in range(6):
    meal_to_24.append([])

    for y in range(24):
        tmp=[]
        tmp.append(meal_center[x][0]+meal_area[0][y])
        tmp.append(meal_center[x][1]+meal_area[1][y])
        tmp.append(meal_center[x][2]+meal_area[2][y])
        meal_to_24[x].append(round(min(tmp),1))

bag_need=[x[0] for x in get_table_data.get_data(path,2,[2,3],[25,3])]
bag_center=get_table_data.get_data(path,5,[3,2],[8,4],'float')
bag_area=get_table_data.get_data(path,7,[12,2],[14,25],'float')
bag_to_24=[]
for x in range(6):
    bag_to_24.append([])

    for y in range(24):
        tmp=[]
        tmp.append(bag_center[x][0]+bag_area[0][y])
        tmp.append(bag_center[x][1]+bag_area[1][y])
        tmp.append(bag_center[x][2]+bag_area[2][y])
        bag_to_24[x].append(round(min(tmp),1))

camp_need=[2*x[0] for x in get_table_data.get_data(path,2,[2,4],[25,4])]
camp_center=get_table_data.get_data(path,6,[3,2],[8,4],'float')
camp_area=get_table_data.get_data(path,7,[16,2],[18,25],'float')
camp_to_24=[]
for x in range(6):
    camp_to_24.append([])
    for y in range(24):
        tmp=[]
        tmp.append(camp_center[x][0]+camp_area[0][y])
        tmp.append(camp_center[x][1]+camp_area[1][y])
        tmp.append(camp_center[x][2]+camp_area[2][y])
        camp_to_24[x].append(round(min(tmp),1))

'''
每个节点最优组合
'''

priority=[x[0] for x in get_table_data.get_data(path,2,[2,5],[25,5])]

#求四个解决方法
water_deal=optimize.transportation_problem(water_to_24,water_save,water_need)

meal_deal=optimize.transportation_problem_5not4(meal_to_24,meal_save,meal_need)

camp_deal=optimize.transportation_problem_5not4(camp_to_24,camp_save,camp_need)

bag_deal=optimize.transportation_problem_not5(bag_to_24,bag_save,bag_need)

#输出解决方法
for i in range(6):
    print("第%d"%(i+1))
    for j in range(24):
        if water_deal['var'][i][j]:
            print("向第%d的地区提供了"%(j+1)+'%d的water'%(water_deal['var'][i][j]))
        if meal_deal['var'][i][j]!=0:
            print("向第%d的地区提供了"%(j+1)+'%d的meal'%(meal_deal['var'][i][j]))
        if bag_deal['var'][i][j]!=0:
            print("向第%d的地区提供了"%(j+1)+'%d的bag'%(bag_deal['var'][i][j]))
        if camp_deal['var'][i][j]!=0:
            print("向第%d的地区提供了"%(j+1)+'%d的camp'%(camp_deal['var'][i][j]))

#输出总的花费
print('一共花费了:')
print(round((camp_deal['objective']+meal_deal['objective']+bag_deal['objective']+camp_deal['objective']),1))
import docx
import numpy
from docx import Document
"""
得到表格内的数据

"""
def get_data(path,num,begin,end,data_type='int'):
    document = Document(path)
    table = document.tables[num-1]
    tmp=[]
    if data_type=='int':
        for x in range(begin[0]-1,end[0]):
            row=[]
            for y in range(begin[1]-1,end[1]):
                row.append(int(table.cell(x,y).text))
            tmp.append(row)

        return tmp


    if data_type=='float':
        for x in range(begin[0]-1,end[0]):
            row=[]
            for y in range(begin[1]-1,end[1]):
                row.append(float(table.cell(x,y).text))
            tmp.append(row)

        return tmp
import pulp
import numpy as np
from pprint import pprint

#   获取供大于求的最优解
def transportation_problem(cost, x_max, y_max):
    #初始化数据信息
    costs = np.array(cost)
    row = len(costs)
    col = len(costs[0])
    #建立问题,求最小值
    prob = pulp.LpProblem('Transportation Problem', sense=pulp.LpMinimize)
    #建立函数
    var = [[pulp.LpVariable(f'x{i}{j}', lowBound=0, cat=pulp.LpInteger) for j in range(col)] for i in range(row)]

    flatten = lambda x: [y for l in x for y in flatten(l)] if type(x) is list else [x]

    prob += pulp.lpDot(flatten(var), costs.flatten())
    #建立约束条件
    for i in range(row):
        prob += (pulp.lpSum(var[i]) <= x_max[i])

    for j in range(col):
        prob += (pulp.lpSum([var[i][j] for i in range(row)]) == y_max[j])
    #求解
    prob.solve()

    return {'objective':pulp.value(prob.objective), 'var': [[pulp.value(var[i][j]) for j in range(col)] for i in range(row)]}

#   获取满足5优先级,不满足4的最优解
def transportation_problem_5not4(cost, x_max, y_max):
    costs = np.array(cost)
    row = len(costs)
    col = len(costs[0])

    prob = pulp.LpProblem('Transportation Problem', sense=pulp.LpMinimize)

    var = [[pulp.LpVariable(f'x{i}{j}', lowBound=0, cat=pulp.LpInteger) for j in range(col)] for i in range(row)]

    flatten = lambda x: [y for l in x for y in flatten(l)] if type(x) is list else [x]

    prob += pulp.lpDot(flatten(var), costs.flatten())

    for i in range(row):
        prob += (pulp.lpSum(var[i]) == x_max[i])

    for j in range(col):
        if j==5 or j==18:
            prob += (pulp.lpSum([var[i][j] for i in range(row)]) == y_max[j])
        elif j==3 or j==4 or j==6 or j==8 or j==17 or j==19 or j==21:
            prob += (pulp.lpSum([var[i][j] for i in range(row)]) <= y_max[j])
        else:
            prob += (pulp.lpSum([var[i][j] for i in range(row)]) == 0)   

    
    prob.solve()

    return {'objective':pulp.value(prob.objective), 'var': [[pulp.value(var[i][j]) for j in range(col)] for i in range(row)]}

#   获取不满足5的最优解
def transportation_problem_not5(cost, x_max, y_max):
    costs = np.array(cost)
    row = len(costs)
    col = len(costs[0])

    prob = pulp.LpProblem('Transportation Problem', sense=pulp.LpMinimize)

    var = [[pulp.LpVariable(f'x{i}{j}', lowBound=0, cat=pulp.LpInteger) for j in range(col)] for i in range(row)]

    flatten = lambda x: [y for l in x for y in flatten(l)] if type(x) is list else [x]

    prob += pulp.lpDot(flatten(var), costs.flatten())

    for i in range(row):
        prob += (pulp.lpSum(var[i]) == x_max[i])
    for j in range(col):
        if j==5 or j==18:
            prob += (pulp.lpSum([var[i][j] for i in range(row)]) <= y_max[j])
        else:
            prob += (pulp.lpSum([var[i][j] for i in range(row)]) == 0)   
    prob.solve()

    return {'objective':pulp.value(prob.objective), 'var': [[pulp.value(var[i][j]) for j in range(col)] for i in range(row)]}

上一篇 下一篇

猜你喜欢

热点阅读