在多目标优化方面gurobi提供了三种求解模式,分别是Blend(合成型)、Hierarchical(分层型)、两者的混合型。所谓合成模式就是将多个目标线性组合加权转化为单目标,在使用时需要为每个目标提供一个权重,作为setObjectiveN的参数。或者,也可以使用ObjNWeight属性和ObjNumber来设置,目标函数的默认权重是1.0。分层法为每个目标分配优先级,并按优先级递减的顺序对目标进行优化。在每次迭代中,它为当前目标找到最佳的解,但只能从那些不会降低高优先级目标质量的解中搜索。在使用时需要为每个目标优先级作为setObjectiveN的参数。或者,也可以使用ObjNPriority属性。值越大表示优先级越高。目标的默认优先级是0。setObjectiveN(expr, index, priority, weight, abstol, reltol, name)的参数说明如下:
expr: 目标函数表达式,如x+ 2y + 3z
index: 目标函数对应的序号(0,1,2,..),即第几个目标,注意目标函数序号应从0开始。prority: 优先级,为整数,值越大表示目标优先级越高。
weight: 权重(浮点数),在合成型多目标解法中使用该参数,表示不同目标之间的组合权重。
abtol: 允许的目标函数值最大的降低量abstol(浮点数),即当前迭代的值相比最优值的可接受劣化程度。
reltol: abstol的百分数表示,如rlol=0.05则表示可接受劣化程度是5%。 name: 目标函数名称。
1 双目标运输问题
在运输问题中,通常只考虑总成本最小的单目标。但在某些实际情况下,也会出现两个及两个以上的目标,例如目标可能是尽量减少总运输成本,减少消耗某些稀缺资源如能源,避免货物在运输过程中变质(时间)。这里以双目标运输问题为例进行模型上的说明,假定有i=1,2,...m个供应方和j=1,2,...n个需求方,定义cij为单位货物从i运输到j所需花费的运输成本,dij为单位货物从i运输到j所可能发生的变质,ai表示供应方i的供给量,bj表示需求方j的需求量,决策变量xij表示从i运输到j的货物量,考虑双目标的运输问题模型如下。
2 求解算法思路及流程
在通常情况下,计算一个多目标问题的帕累托前沿所需的计算工作量是很大的,其计算复杂性的根本原因在于:已有方法都是在解空间(solution space)(这里在文章中实际指决策空间,decision space)中寻找非支配极值点集,但这些极值点通常有很多。本文提出了一种在准则空间(criteria space) (这里在文章中实际指目标空间,objective space)中寻找非支配极值点的方法。算法步骤如下:
Step0: 将非支配点数量k置为1,生成初始的两个非支配点
若两非支配点的值相同则算法终止,表明所有目标均可以同时达到最优,不存在其它非支配点,若不相同同则记录非支配点,k=k+1,定义空列表L=[(1,2)],定义空列表E,然后进入步骤1
Step1: 从列表L中取出元素(r,s)得到新的非支配点
首先根据得到的解计算两个系数:
将求得的解分别代入到原模型的两个目标函数中,若得到的新解与已有的非支配解相同,对列表E进行更新,然后进入步骤2。
若不同则对得到的解进行记录,并更新列表L。
Step2: 更新L并判断终止条件,若L为空则算法终止,否则转向步骤1
算例数据如下表所示,共有三个供应商和四个需求方,表中每个格子中的两个数据第一个表示单位运输成本cij,第二个表示单位变质dij,总的供给量和需求量相等为44。
帕累托最优前沿如下图:
python+gurobi代码实现