「达摩院MindOpt」用于多目标规划(目标规划法)

前篇我们讲述了使用加权和法对多目标规划问题的优化,本篇将讲述使用目标规划法。

1. 原理

目标规划法,首先是为每个目标函数设定一个期望值(目标值) g i g_i gi

方案1: 然后构建一个新的目标函数 F ( x ) F(x) F(x),其形式如下:
minimize F ( x ) = ∑ [ w i ∗ ∣ f i ( x ) − g i ∣ ] \text{minimize} \quad F(x) = \sum [w_i * |f_i(x) - g_i|] minimizeF(x)=[wifi(x)gi]
其中, w i w_i wi表示第 i i i个目标函数的权重。通过最小化 F ( x ) F(x) F(x),可以在满足各种约束的同时实现多目标的调和。这个距离也可以通过 L 2 L_2 L2 范数来表达。此方法有些类似加权和法。

方案2:我们还可以把目标设定进约束里(类似层次分析法),将优先级高的目标设置为约束条件,从而降低目标函数的个数。即在约束里面增加 f 1 ( x ) = g 1 f_1(x) = g_1 f1(x)=g1

2.举例子

同样用之前的农场主问题:

假设一个农场主希望优化其土地上的作物种植布局,需要在以下两个目标之间取得平衡:

  • 目标1:最大化农场产值(单位:元);
  • 目标2:最小化化肥使用量(单位:千克)。

农场主有两种作物可以种植:作物A、作物B、作物C。设 x 1 x_1 x1 x 2 x_2 x2 x 3 x_3 x3分别为种植作物A、B、C的面积。

  • 已知A、B、C每亩作物的产值分别为1000元、1200元、1300元。则,目标1的函数: maximize F 1 ( x ) = 1000 ⋅ x 1 + 1200 ⋅ x 2 + 1300 ⋅ x 3 \text{maximize} \quad F_1(x) = 1000 \cdot x_1 + 1200 \cdot x_2 + 1300 \cdot x_3 maximizeF1(x)=1000x1+1200x2+1300x3
  • 每亩A、B、C作物分别需要化肥:20千克、30千克、33千克。则,目标2的函数: minimize F 2 ( x ) = 20 ⋅ x 1 + 30 ⋅ x 2 + 33 ⋅ x 3 \text{minimize} \quad F_2(x) = 20 \cdot x_1 + 30 \cdot x_2 + 33 \cdot x_3 minimizeF2(x)=20x1+30x2+33x3
  • 总种植面积不超过100亩。即, x 1 + x 2 + x 3 ≤ 100 x_1 + x_2 + x_3 \leq 100 x1+x2+x3100
  • 3种作物至少每个需要种10亩。

2.1. 设定目标值

在不清楚设什么目标值时候,我们还可以通过求解各个单目标的最优解,观察值,然后设目标值。

如我们使用 MindOpt APL建模语言对这个问题进行建模,并调用 MindOpt Solver 来求解。代码如下:

# ==================目标1=======================


clear model;

# ------建模-------Start-----
# model_2_1.mapl

# 变量
var x1 >= 10;
var x2 >= 10;
var x3 >= 10;

# 目标
maximize obj: (1000 * x1 + 1200 * x2 + 1300 * x3);

# 定义约束条件
subject to constraint1: x1 + x2 + x3 <= 100;
# ------建模-------End-----

#求解
option solver mindopt;     # (可选)指定求解用的求解器,默认是MindOpt
option mindopt_options 'print=0'; #设置求解器输出级别,减少过程打印
solve;         # 求解

# 结果打印和检查结果
print "-----------------Display---------------";
display; 
print "其中,种", x1,"亩作物A,种",x2,"亩作物B,种",x3,"亩作物C。";
print "对应农场产值:", (1000 * x1 + 1200 * x2 + 1300 * x3),"千克。";

# ==================目标2=======================

clear model;

# ------建模-------Start-----
# model_2_2.mapl

# 变量
var x1 >= 10;
var x2 >= 10;
var x3 >= 10;

# 目标
minimize obj: (20 * x1 + 30 * x2 + 33 * x3);

# 定义约束条件
subject to constraint1: x1 + x2 + x3 <= 100;
# ------建模-------End-----

#求解
option solver mindopt;     # (可选)指定求解用的求解器,默认是MindOpt
option mindopt_options 'print=0'; #设置求解器输出级别,减少过程打印
solve;         # 求解

# 结果打印和检查结果
print "-----------------Display---------------";
display; 
print "其中,种", x1,"亩作物A,种",x2,"亩作物B,种",x3,"亩作物C。";
print "对应化肥使用量:", (20 * x1 + 30 * x2 + 33 * x3),"千克。";

运行以上代码结果如下:

Running mindoptampl
wantsol=1
print=0
MindOpt Version 0.25.1 (Build date: 20230816)
Copyright (c) 2020-2023 Alibaba Cloud.

Start license validation (current time : 13-OCT-2023 15:54:20).
License validation terminated. Time : 0.004s


OPTIMAL; objective 126000.00
0 simplex iterations

Completed.
-----------------Display---------------
Primal Solution:
      x1 = 10.0000000
      x2 = 10.0000000
      x3 = 80.0000000
其中,种10亩作物A,种10亩作物B,种80亩作物C。
对应农场产值:126000千克。
Running mindoptampl
wantsol=1
print=0
MindOpt Version 0.25.1 (Build date: 20230816)
Copyright (c) 2020-2023 Alibaba Cloud.

Start license validation (current time : 13-OCT-2023 15:54:20).
License validation terminated. Time : 0.004s


OPTIMAL; objective 830.00
0 simplex iterations

Completed.
-----------------Display---------------
Primal Solution:
      x1 = 10.0000000
      x2 = 10.0000000
      x3 = 10.0000000
其中,种10亩作物A,种10亩作物B,种10亩作物C。
对应化肥使用量:830千克。

从上面可以看出,目标1的最优值是126000千克,目标2的最优值是不种植多余的,只消耗830千克。接下来我们把这两个数值作为目标。

2.2. 方法1:设定优化目标距离

考虑到变量的取值域,这里我们直接采用(大数-小数)的方式来表示距离。

然后类似加权和法,我们引入两个权重参数 w 1 w_1 w1 w 2 w_2 w2,分别表示农场产值和化肥使用量的重要程度,且满足 w 1 + w 2 = 1 w_1 + w_2 = 1 w1+w2=1,然后考虑两个目标的单位和数据量级不一样,我们引入参数 c c c来给目标2调整数量级。

MAPL代码如下:

# ==================设定目标转换后=======================

clear model;

# ------建模-------Start-----
# model_2_3.mapl

# 变量
var x1 >= 10;
var x2 >= 10;
var x3 >= 10;

# 权重参数
param w1 = 0.7; # 假设农场主更关心农场产值
param w2 = 1 - w1;
param c = 50; # 根据数量级差异 1000/20 = 50来简单预估


# 目标
minimize obj:   w1 *(126000 - (1000 * x1 + 1200 * x2 + 1300 * x3)) + c*w2*((20 * x1 + 30 * x2 + 33 * x3) - 830);

# 定义约束条件
subject to constraint1: x1 + x2 + x3 <= 100;
# ------建模-------End-----

#求解
option solver mindopt;     # (可选)指定求解用的求解器,默认是MindOpt
option mindopt_options 'print=0'; #设置求解器输出级别,减少过程打印
solve;         # 求解

# 结果打印和检查结果
print "-----------------Display---------------";
display;

print "改造的单目标最优是:",w1 *(126000 - (1000 * x1 + 1200 * x2 + 1300 * x3)) + c*w2*((20 * x1 + 30 * x2 + 33 * x3) - 830);
print "其中,种", x1,"亩作物A,种",x2,"亩作物B,种",x3,"亩作物C。";
print "对应农场产值:", (1000 * x1 + 1200 * x2 + 1300 * x3),"元。";
print "对应化肥使用量:", (20 * x1 + 30 * x2 + 33 * x3),"千克。";

运行代码结果如下:

Running mindoptampl
wantsol=1
print=0
MindOpt Version 0.25.1 (Build date: 20230816)
Copyright (c) 2020-2023 Alibaba Cloud.

Start license validation (current time : 13-OCT-2023 15:55:49).
License validation terminated. Time : 0.006s


OPTIMAL; objective 34650.00
0 simplex iterations

Completed.
-----------------Display---------------
Primal Solution:
      x1 = 10.0000000
      x2 = 10.0000000
      x3 = 80.0000000
改造的单目标最优是:34650.00000000001
其中,种10亩作物A,种10亩作物B,种80亩作物C。
对应农场产值:126000元。
对应化肥使用量:3140千克。

从上面可以看出,在本案例里面,目标改造与前面的加权和方法类似。

2.3. 方案2:将目标作为约束来求解最优

除了改造进目标,我们还可以改进约束里。观察上面的目标函数的最优值们:

  • F 1 ( x ) F_1(x) F1(x)最优是:种10亩作物A,种10亩作物B,种80亩作物C。对应农场产值:126000千克。
  • F 2 ( x ) F_2(x) F2(x)最优是:种10亩作物A,种10亩作物B,种10亩作物C。对应化肥使用量:830千克。

这里我们将 F 1 ( x ) F_1(x) F1(x)的最优值作为约束,改造后如下:

# ==================设定目标转换后=======================

clear model;

# ------建模-------Start-----
# model_2_3.mapl

# 变量
var x1 >= 10;
var x2 >= 10;
var x3 >= 10;

# 目标
minimize obj: 20 * x1 + 30 * x2 + 33 * x3; # 仅有F2(x)

# 定义约束条件
subject to constraint1: x1 + x2 + x3 <= 100;

subject to constraint_new: (1000 * x1 + 1200 * x2 + 1300 * x3) == 126000 ;

# ------建模-------End-----

#求解
option solver mindopt;     # (可选)指定求解用的求解器,默认是MindOpt
option mindopt_options 'print=0'; #设置求解器输出级别,减少过程打印
solve;         # 求解

# 结果打印和检查结果
print "-----------------Display---------------";
display;

print "其中,种{:.9g}亩作物A,种{:.9g}亩作物B,种{:.9g}亩作物C。" % x1,x2,x3;
print "对应农场产值:", (1000 * x1 + 1200 * x2 + 1300 * x3),"元。";
print "对应化肥使用量:", (20 * x1 + 30 * x2 + 33 * x3),"千克。";

运行代码结果如下:

Running mindoptampl
wantsol=1
print=0
MindOpt Version 0.25.1 (Build date: 20230816)
Copyright (c) 2020-2023 Alibaba Cloud.

Start license validation (current time : 13-OCT-2023 15:56:49).
License validation terminated. Time : 0.006s


OPTIMAL; objective 3140.00
3 simplex iterations

Completed.
-----------------Display---------------
Primal Solution:
      x1 = 10.0000000
      x2 = 10.0000000
      x3 = 80.0000000
其中,种10亩作物A,种10亩作物B,种80亩作物C。
对应农场产值:126000元。
对应化肥使用量:3140千克。

如果是把第二个目标的最优值设置进约束,结果就有些不合适了。如下:

# ==================设定目标转换后=======================

clear model;

# ------建模-------Start-----
# model_2_3.mapl

# 变量
var x1 >= 10;
var x2 >= 10;
var x3 >= 10;

# 目标
minimize obj:  (1000 * x1 + 1200 * x2 + 1300 * x3); # 仅有F1(x)

# 定义约束条件
subject to constraint1: x1 + x2 + x3 <= 100;

subject to constraint_new: (20 * x1 + 30 * x2 + 33 * x3) == 830 ;

# ------建模-------End-----

#求解
option solver mindopt;     # (可选)指定求解用的求解器,默认是MindOpt
option mindopt_options 'print=0'; #设置求解器输出级别,减少过程打印
solve;         # 求解

# 结果打印和检查结果
print "-----------------Display---------------";
display;

print "其中,种{:.9g}亩作物A,种{:.9g}亩作物B,种{:.9g}亩作物C。" % x1,x2,x3;
print "对应农场产值:", (1000 * x1 + 1200 * x2 + 1300 * x3),"元。";
print "对应化肥使用量:", (20 * x1 + 30 * x2 + 33 * x3),"千克。";

运行结果如下:

Running mindoptampl
wantsol=1
print=0
MindOpt Version 0.25.1 (Build date: 20230816)
Copyright (c) 2020-2023 Alibaba Cloud.

Start license validation (current time : 29-AUG-2023 11:35:49).
License validation terminated. Time : 0.007s


OPTIMAL; objective 35000.00
0 simplex iterations

Completed.
-----------------Display---------------
Primal Solution:
      x1 = 10.0000000
      x2 = 10.0000000
      x3 = 10.0000000
其中,种10亩作物A,种10亩作物B,种10亩作物C。
对应农场产值:35000元。
对应化肥使用量:830千克。

3.分析和改进

从上面可以看到:

  • 直接设置进目标里面,效果会和加权和法类似。
  • 如果设置进约束,是个不一样的思路,也可以得到解。其原理类似设置不同目标的优先级。但是选用不同的目标进约束会导致效果并不合适。

因此多目标转换时候,建议多尝试。可以考虑下述改进思路:

  • 结合其他方法:例如与加权法结合,可以在考虑目标优先级的同时,更好地平衡各个目标之间的权重。
  • 求解多个解决方案:尝试使用不同的目标优先级或权重组合,以生成多个解决方案。这些解决方案可以提供多个选择方向,有助于在实际应用中找到满意的平衡点。
  • 使用交互式方法:在实际应用中,可以使用交互式方法,让决策者参与到优化过程中。在每一轮迭代中,决策者可以根据当前解决方案提供反馈。根据决策者的反馈,可以调整目标优先级或权重,从而在多轮迭代中逐渐找到满意的解决方案。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值