物流公司经常遇到选址的问题,其实选址主要解决两个问题,1.选哪几个仓库。2.各网点分配至哪个仓库。本文介绍如何建立模型对离散选址问题进行求解。这是一个典型的混合整数规划问题(MIP),该问题在各个领域应用极其广泛。问题描述:有15个需要配送的网点。有三个配送中心可供选择。已知三个配送中心到各个网点的成本(是否货量加权,按实际情况修改数据。)
传入数据
本文使用pulp库进行求解。本例是小规模选址问题,无需调用第三方求解器,若规模较大,建议调用gurobi、cplex或者scip等求解器。
from pulp import * Customer = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]#15个需配送的网点 Facility = ['Fac-1', 'Fac-2', 'Fac-3']#3个备选配送选址点 #从三个备选点运输过去的成本。成本可以是根据距离计算的运费,或者是根据货量计算的加权运费,可自行修改。 transportation_cost = {'Fac-1' : {1 : 4, 2 : 5, 3 : 6, 4 : 8, 5 : 10,6 : 1, 7 : 5, 8 : 1, 9 : 8, 10 : 10,11 : 14, 12 : 1, 13 : 1, 14 : 1, 15 : 1}, 'Fac-2' : {1 : 1, 2 : 1, 3 : 3, 4 : 5, 5 : 8,6 : 2, 7 : 1, 8 : 16, 9 : 1, 10 : 1,11 : 1, 12 : 15, 13 : 1, 14 : 8, 15 : 7}, 'Fac-3' : {1 : 1, 2 : 1, 3 : 1, 4 : 1, 5 : 4,6 : 1, 7 : 12, 8 : 1, 9 : 8, 10 : 1,11 : 14, 12 : 15, 13 : 16, 14 : 1, 15 : 1} } #每个选址点对应的日均成本 fixed_cost = {'Fac-1' : 20, 'Fac-2' : 30, 'Fac-3' : 100}
定义决策变量
决策变量一共有两类。第一类3个,是否选择该选址点。0-1变量。第二类45个,该网点分配到哪个选址点。0-1变量。
# 定义决策变量 use_facility = LpVariable.dicts("Use Facility", Facility, 0, 1, LpBinary)#是否使用该选址点(0-1离散变量) ser_customer = LpVariable.dicts("Service", [(i,j) for i in Customer for j in Facility], 0)#
设定目标函数
目标函数为仓库成本与选址点到各网点的运输成本之和。
# 设定目标函数 cflp += (lpSum(fixed_cost[j]*use_facility[j] for j in Facility) + lpSum(transportation_cost[j][i]*ser_customer[(i,j)] for j in Facility for i in Customer))
设定约束
约束条件主要包括:1.每个网点仅选择一个选址点。2.仓库数量选择。3.仓库是否选择与网点之间的判断关联关系。
# 设定约束 for i in Customer: cflp += lpSum(ser_customer[(i,j)] for j in Facility) == 1#每个网点有且仅有一个选址点服务。 cflp+=lpSum(use_facility[j] for j in Facility) <=3#三个仓库最多选3个, cflp+=lpSum(use_facility[j] for j in Facility) >=1#三个仓库最少选1个, for i in Customer: #若超过1个分配至某个仓库,则需选择该仓库,对应的use_facility[j]取1 for j in Facility: cflp += ser_customer[(i,j)] <= use_facility[j]
求解
找到一个最优解。
打印结果
# 打印结果 Tolerance = 0.0001 for j in Facility: if use_facility[j].varValue > Tolerance: print(use_facility[j].varValue) print("选址点= ", j)
# 打印网点分配结果 for v in cflp.variables(): if v.varValue>0: print(v.name, "=", v.varValue)
#打印目标结果 print("Total Cost = ", value(cflp.objective))
以上是一个经典的多仓库选址的整数规划问题,可衍生至许多复杂的问题建模。比如如果网点数超过1000个,选址点超过100个,增加货量仓库及网点货量需求约束,模型将会变得越来越复杂,但其建模逻辑不会有太大的变化,难点是大规模问题需要使用高效的求解器或启发式算法。