多目标规划

摘要:
多目标规划的模型基础:正负偏差变量即d2+,d2-分别表示决策值超过和未达到目标值的部分。且di+,di-均大于0刚性约束和目标约束多目标规划中,刚性约束中保持˃=/˂=不变。是+di-,-di+,这是因为需要将目标还原回去,使其最接近原来的刚性约束优先因子与权系数对于若干个目标,分出主次和轻重缓急目标规划的目标函数是所有偏差变量的加权和。建立相应的目标规划模型并求解。
  • 多目标规划的模型基础:
  1. 正负偏差变量
    即d2+,d2-分别表示决策值超过和未达到目标值的部分。且di+,di-均大于0

  2. 刚性约束和目标约束(柔性目标约束具有偏差)
    多目标规划中,刚性约束中保持>=/<=不变。约束需要变换为柔性约束时,需要把>=/<=改成=(因为已经有了d2+,d2-用来表示正负偏差),并且追加上(+di-di+)这里注意!是+di-,-di+,这是因为需要将目标还原回去,使其最接近原来的刚性约束

  3. 优先因子与权系数
    对于若干个目标,分出主次和轻重缓急

  4. 目标规划的目标函数
    是所有偏差变量的加权和。值得注意的是该加权和均取min值。且每个不同的等级需求中,并不一定di+、di-都出现。具体分析需要具体看题目
    举例如下:
    题目中说设备B既要求充分利用,又尽可能不加班,那么用时间衡量列出的表达式即为:min z=P3(d3- + d3+)之所以这里用+而不是-d3+的原因是:正负偏差不可能同时存在,必有di+di-=0(因为决策值不可能同时大于目标值又小于目标值),又前面是min,所以就取+,让di+和di-都是正值。故引出如下规则:

多目标规划第1张

  • 最后给出例题,并给出对应的解法:

问题:某企业生产甲、乙两种产品,需要用到 A, B,C 三种设备,关于产品的赢利与使用设备的工时及限制如下表所示。问该企业应如何安排生产,才能达到下列目标:
多目标规划第2张
( 1)力求使利润指标不低于 1500 元;
( 2)考虑到市场需求,甲、乙两种产品的产量比应尽量保持 1:2;
( 3)设备 A 为贵重设备,严格禁止超时使用;
( 4)设备C 可以适当加班,但要控制;设备 B 既要求充分利用,又尽可能不加班。
在重要性上,设备 B 是设备C 的 3 倍。
建立相应的目标规划模型并求解。
解:设该企业生产甲乙两种产品的件数分别为 x1, x2 ,相应的目标规划模型为:
多目标规划第3张

  • 下面采用序贯解法,用lingo求解:

一级目标:

model:
sets:
variable/1..2/:x;!规定变量;
s_con_num/1..4/:g,dplus,dminus;!软约束条件个数(g的个数=dplus个数=dminus个数)以及需要的相关参数;
s_con(s_con_num,variable):c;!软约束系数;
endsets
data:
g=1500 0 16 15;
c=200 300 2 -1 4 0 0 5;
enddata
min=dminus(1);!第一个目标函数;!对应min=z中第一小部分;
2*x(1)+2*x(2)<12;!硬约束;
@for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i)); !利用设置完毕的数据构建软约束的表达式;
!软约束表达式;
@for(variable:@gin(x));!限制变量为整数;
end

此时,第一目标最优值为0,第一级偏差为0,下面进行第二步:
二级目标:

!求得dminus(1)=0,接着求解第二个目标;
model:
sets:
variable/1..2/:x;!规定变量;
s_con_num/1..4/:g,dplus,dminus;!软约束条件个数以及相关参数;
s_con(s_con_num,variable):c;!软约束系数;
endsets
data:
g=1500 0 16 15;
c=200 300 2 -1 4 0 0 5;
enddata
min=dminus(2)+dplus(2);!第二个目标函数;
2*x(1)+2*x(2)<12;!硬约束;
@for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i));
!软约束表达式;
dminus(1)=0;!第一目标结果;
@for(variable:@gin(x));
end

此时,第二目标最优值为0,偏差为0,下面进行第三步:
三级目标:

!求得dminus(2)=0,接着求解第三个目标;
model:
sets:
variable/1..2/:x;!规定变量;
s_con_num/1..4/:g,dplus,dminus;!软约束条件个数以及相关参数;
s_con(s_con_num,variable):c;!软约束系数;
endsets
data:
g=1500 0 16 15;
c=200 300 2 -1 4 0 0 5;
enddata
min=3*dminus(3)+3*dplus(3)+dminus(4);!第三个目标函数;
2*x(1)+2*x(2)<12;!硬约束;
@for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i));
!软约束表达式;
dminus(1)=0;!第一目标约束;
dminus(2)+dplus(2)=0;!二级目标约束;
@for(variable:@gin(x));
end

最终求得x1=2,x2=4,dplus(1)=100,最优利润为1600

由于上面的过程需要编写好几个程序,在使用时不方便,下面给出Lingo编写的一个通用程序,在程序中用到数据段未知数据的编程方法。

!序贯算法的核心就在于按照p的优先级依次视作单目标规划去求解  eg.p1表示优先级为1的,需要第一个计算;
model:
sets:
level/1..3/:p,z,goal;
variable/1..2/:x;
h_con_num/1..1/:b;
s_con_num/1..4/:g,dplus,dminus;
!以上为建立变量;
h_con(h_con_num,variable):a;!构建约束;
s_con(s_con_num,variable):c;!构建约束;
obj(level,s_con_num)/1 1,2 2,3 3,3 4/:wplus,wminus;!定义P(i)与dplus(i)、dminus(i)之间的系数.其中1 1代表P(1)和dplus(1)、dminus(1)的系数;
endsets
data:
ctr=?;	!?表示需要输入;
goal=??0;	!因为是一级一级去求偏差的,所以一共三级时,求解到最后一级时只需要输入前两级的最优偏差约束即可,所以goal是??0;
b=12;
g=1500 0 16 15;
a=2 2;
c=200 300 2 -1 4 0 0 5;
wplus=0 1 3 1;
wminus=1 1 3 0;
enddata
min=@ sum(level:p*z);	!这个是按照一级一级来求的,因为从该行往下第二行可以发现在求该级目标的时候,其他级的系数均置为了0.;
p(ctr)=1;	!p是序贯算法中的表示优先级的因子,不是一个系数。所以这里当作系数运算时令为1,详见下一行注释。序贯算法的核心就在于按照p的优先级依次视作单目标规划去求解  eg.p1表示优先级为1的,需要第一个计算;
@for(level(i)|i#ne#ctr:p(i)=0);!i不等于ctr时,p(i)为0;
@for(level(i):z(i)=@sum(obj(i,j):wplus(i,j)*dplus(j)+wminus(i,j)*dminus(j)));!构建z(i);
@for(h_con_num(i):@sum(variable(j):a(i,j)*x(j))<b(i));!第一个刚性约束;
@for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i));	!柔性约束;
@for(level(i)|i#lt#@ size(level):@ bnd(0,z(i),goal(i)));	!这里是为了带上之前求出来的级别最优偏差的约束:0=<z(i)<=goal(i);
end

当程序运行时,会出现一个对话框。
在做第一级目标计算式,ctr输入1,goal(1),goal(2)输入两个较大的值(goal代表最优偏差),表明这两项约束不起作用。
求的第一级最优偏差为0,进行第二轮的计算。
在第二轮的目标运算中,ctr输入2,由于第一级偏差为0,因此goal(1)的输入值为0。
goal(2)输入一个较大的值,求得第二级的最优偏差仍为0,进行第三级计算。
在第三级计算中,ctr输入3,由于第一级,第二级偏差均为0,因此goal(1),goal(2)输入值均为0.

免责声明:文章转载自《多目标规划》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇本地部署Easy Mockmysql灾备演练问题下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

自己写的一个随机生成ID号的函数(C#)

public string GetRandomNum(int num_down , int num_up){ //传递随机数的上下限 用于限制其长度 注意 num_up的值上限1000000000int re=0; Random ro=new Random(unchecked((int)DateTime.Now.Ticks));re=ro.Next(num...

mssql性能优化

总结下SQL SERVER数据库性能优化相关的注意事项,在网上搜索了一下,发现很多文章,有的都列出了上百条,但是仔细看发现,有很多似是而非或者过时(可能对SQL SERVER6.5以前的版本或者ORACLE是适用的)的信息,只好自己根据以前的经验和测试结果进行总结了。我始终认为,一个系统的性能的提高,不单单是试运行或者维护阶段的性能调优的任务,也不单单是开...

关于OJ上内存问题的试验

char类型占一个字节 int类型占4个字节 如果杭电OJ上给的范围是32678K,那么内存大小就是32678*1024=33554432 那么可以开到多大的数组呢?!可以开到很大,但是可用的就只有33554432/4=838万. 我在杭电上试了一下,num[8000000](八百万),而且给其赋值的话,不会超内存 num[9000000](900万),而...

将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5

    /****************************************************************  将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。 ****************************************************************/#import...

java生成解析xml的另外两种方法JAXB

   JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示...

Scala基础之集合(数组)

集合介绍 Scala的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质。对于几乎所有的集合类,Scala都同时提供了可变和不可变的版本。 集合可变,不可变的区别 Scala默认提供的集合都是不可变。 不可变:增删改 都会返回有个新数组 可变:可增删改  可变: scala.collection.mutable ha...