在之前负责的风电项目叶片发运过程中,涉及到一些运输问题。恰好最近学习了一点优化方面的知识,这里对叶片的发运问题做一个优化。
问题背景:
当前项目为一个100MW的风电电站,场地位于B国境内。
设计拟选用2MW的风机50台,因此需运输叶片50套(单车可1套3片)。
受到生产日期和船期限制,叶片分别发至B国的1,2两个码头,1码头20套,2码头30套,并由卡车运输至项目地。
综合勘察后,选定施工地点5处,分别为1,2,3,4,5。
各地需要的叶片套数分别为5,6,11,13,15。
考虑到运输距离及路况,1码头向1-5施工地运输单套叶片的费用(美元)分别为:100,200,220,150,130;
2码头向1-5施工地运输单套叶片的费用分别为:80,210,180,120,160。
综合以上信息,提供一个优化的运输方案。
这是一个典型的运输问题。现在处理这种问题的模块很多,由于我一直用python,所以这里我采用其pulp线性优化模块来进行分析。分析的流程如下:
1.构建数据集
导入模块
from pulp import *
创建数据集
#创建一个关于码头的list
ports=[1,2]
#创建一个1,2两码头供应叶片的dict
supply={1:20,2:30}
#创建一个需求节点的dict
sites={'1':5,'2':6,'3':11,'4':13,'5':15}
#创建一个1,2两码头向各场地运输叶片运费的dict
costs = {
1:{'1':100,'2':200,'3':220,'4':150,'5':130},
2:{'1':80,'2':210,'3':180,'4':120,'5':160}
}
2.分析问题与构建模型
2.1明确问题
构建问题
'''显然本问题旨在优化运输路径,使得运费最小,因此是一个最小化的问题'''
prob=LpProblem('Blades transportation',LpMinimize)
构建运输路径
routes=[(i,j) for i in ports for j in sites]
routes运输路径矩阵
构建关于路径的变量
'''由于运输的叶片都是整套,因此这里是个整数问题'''
route_vars=LpVariable.dicts('Route',(ports,sites),0,None,LpInteger)
route_vars构建的运输路径变量
2.2添加目标函数与约束
构建目标函数—总运输成本
prob += lpSum([route_vars[i][j]*costs[i][j] for (i,j) in routes])
增加约束条件
#对码头而言,向5个场地供应的叶片数不应大于其叶片数量
for i in ports:
prob += (lpSum([route_vars[i][j] for j in sites]) <= supply[i])
#对施工场地而言,每个场地的供应数应等于其需求数
for j in sites:
prob +=(lpSum([route_vars[i][j] for i in ports])==sites[j])
上限约束问题说明:
显然,本次分析仅对各路径运输量之和进行了约束,即每次运送叶片数量>=0;
而有的时候,可能会对每条运输路径进行上下限的约束。如此,则有如下形式:
Route_1_1 =LpVariable("Route_1_1", 0, 1) #括号内依次为变量名,下限,上限
约束变量系数不为1情况说明:
本次约束条件各变量系数均为1。但一般问题中,我们必然会遇到大量约束且系数不为1的情况,这种情况可以利用pulp包中的LpDot函数,将变量和系数矩阵相乘计算,如下:
prob += (pulp.lpDot(route_vars, const_mat)=< upbound)
3.计算结果
计算优化的分配结果
'''solve命令可以查看当前问题的方程式;solve()可以进行求解'''
prob.solve()
计算目标运费
print('objective',pulp.value(prob.objective))
# objective 7100.0
获得各变量值
for (i,j) in routes:
a=pulp.value(route_vars[i][j])
b=route_vars[i][j]
print('%s的值是%s'%(b,a))
Route_1_1的值是0.0
Route_1_2的值是5.0
Route_1_3的值是0.0
Route_1_4的值是0.0
Route_1_5的值是15.0
Route_2_1的值是5.0
Route_2_2的值是1.0
Route_2_3的值是11.0
Route_2_4的值是13.0
Route_2_5的值是0.0
感谢阅读!