多目标线性规划——pulp

一、背景

因为工作原因需要了解一些运筹优化相关的算法,所以在同事的介绍下找了《运筹学导论(第10版)》(Introduction to Operations Research)看。最近又在微信群中看到有些同学在讨论,于是乎便把用到的相关工具,以及简单用法做一些记录。(后续可能还会逐步更新)

二、多目标优化问题

优化目标1: m a x x 1 , x 2   2 x 1 + 3 x 2 max_{x_1,x_2} \ 2x_1 + 3x_2 maxx1,x2 2x1+3x2
优化目标2: m a x x 1 , x 2   4 x 1 − 2 x 2 max_{x_1,x_2} \ 4x_1 - 2x_2 maxx1,x2 4x12x2
约束:s.t.
x 1 + x 2 ≤ 10 2 x 1 + x 2 ≤ 15 x 1 , x 2 ≥ 0 x_1 + x_2 \le 10 \\ 2x_1 + x_2 \le 15 \\ x_1, x_2 \ge 0 x1+x2102x1+x215x1,x20

三、解

3.1 Pulp包解

3.1.1 两步解

最大化一个目标,然后将其添加为约束并解决另一个目标

import pulp
from pulp import LpVariable, LpProblem, LpMaximize
# 最大化一个目标,然后将其添加为约束并解决另一个目标
linear_prob = LpProblem('为第一目标最大化', LpMaximize)
# variable
x1 = LpVariable('x1', lowBound=0)
x2 = LpVariable('x2', lowBound=0)
# max_target
linear_prob += 2*x1 + 3*x2
# s.t.
linear_prob += x1 + x2 <= 10
linear_prob += 2 * x1 + x2 <= 15
# solve
solution = linear_prob.solve()
print('Obj: {Obj}; \nmax = {max_} \nSolution:  x1={x1} x2={x2}'.format(
        Obj = linear_prob.objective,
        max_=pulp.value(linear_prob.objective),
        x1 = pulp.value(x1),
        x2 = pulp.value(x2)
    )
)
"""
Obj: 2*x1 + 3*x2;
max = 30.0
Solution:  x1=0.0 x2=10.0
"""

基于第一个解,将其作为限制解决第二个目标

linear_prob_sec = LpProblem('为第二目标最大化', LpMaximize)
# max_target
linear_prob_sec += 4*x1 - 2*x2
# s.t.
linear_prob_sec += x1 + x2 <= 10
linear_prob_sec += 2 * x1 + x2 <= 15
linear_prob_sec += 2*x1 + 3*x2 >= 30
# solve
solution = linear_prob_sec.solve()
print('Obj: {Obj}; \nmax = {max_}\nSolution:  x1={x1} x2={x2}'.format(
        Obj = linear_prob_sec.objective,
        max_=pulp.value(linear_prob_sec.objective),
        x1 = pulp.value(x1),
        x2 = pulp.value(x2)
    )
)
"""
Obj: 4*x1 - 2*x2;
max = -19.999999999995993
Solution:  x1=1.0018653e-12 x2=10.0
"""

3.1.2 使用采样的权重和具有定义步长的迭代组合目标

现在的问题是如何选择α。
在这种情况下,典型的方法是确定有效边界。在经济学中,例如被称为“最佳最优”。

问题重构

优化目标: m a x x 1 , x 2   α ( 2 x 1 + 3 x 2 ) + ( 1 − α ) ( 4 x 1 − 2 x 2 ) max_{x_1,x_2} \ \alpha(2x_1 + 3x_2) + (1-\alpha)(4x_1 - 2x_2) maxx1,x2 α(2x1+3x2)+(1α)(4x12x2)
约束:s.t.
x 1 + x 2 ≤ 10 2 x 1 + x 2 ≤ 15 x 1 , x 2 ≥ 0 x_1 + x_2 \le 10 \\ 2x_1 + x_2 \le 15 \\ x_1, x_2 \ge 0 x1+x2102x1+x215x1,x20

import matplotlib.pyplot as plt
import pulp
from pulp import LpVariable, LpProblem, LpMaximize
import numpy as np
import pandas as pd
plt.style.use('ggplot')


x1 = LpVariable('x1', lowBound=0)
x2 = LpVariable('x2', lowBound=0)
step_size = 0.01
sove_df = pd.DataFrame(columns=['alpha', 'x1', 'x2', 'obj_v', 'org_v'])
for i in range(0, 101, int(step_size * 100)):
    lp = LpProblem('多目标优化', LpMaximize)
    # obj
    lp += (i/100)*(2*x1 + 3*x2) + (1 - i/100)*(4*x1 - 2*x2)
    # s.t.
    lp += x1 + x2 <= 10
    lp += 2 * x1 + x2 <= 15
    res = lp.solve()
    x1_, x2_ = pulp.value(x1), pulp.value(x2)
    org_v = (2*x1_ + 3*x2_) + (4*x1_ - 2*x2_)
    sove_df.loc[int(i/(step_size*100))] = [i/100, x1_, x2_, pulp.value(lp.objective), org_v]


sv_max = sove_df['obj_v'].max()
sv_min = sove_df['obj_v'].min()


plt.title('$ \\alpha \  With \  max_{x_1,x_2} \\alpha(2x_1 + 3x_2) + (1-\\alpha)(4x_1 - 2x_2)$')
plt.plot(sove_df["alpha"], sove_df["obj_v"],color="darkred", alpha=0.7, label="obj_v")

for idx, row in sove_df[sove_df['obj_v']==sv_max].iterrows():
    plt.text(row.alpha, row.obj_v, f'alpha={row.alpha:.3f} obj={row.obj_v:.2f}\n(x1={row.x1}, x2={row.x2})')

for idx, row in sove_df[sove_df['obj_v']==sv_min].iterrows():
    plt.text(row.alpha, row.obj_v, f'alpha={row.alpha:.3f} obj={row.obj_v:.2f}\n(x1={row.x1}, x2={row.x2})')


plt.plot(sove_df["alpha"], sove_df["org_v"],color="steelblue", alpha=0.7, linestyle='--', label="org_v")
# plt.ylim(15, 35)
plt.xlim(0, 1.5)
plt.legend()
plt.xlabel("alpha", size=12)
plt.ylabel("obj_value", size=12)
plt.show()

在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Python中,你可以使用线性规划库来解决多目标线性规划问题。一个常用的库是PuLP,它是一个开源的线性规划库,可以用来构建和解决线性规划问题。 以下是一个使用PuLP解决多目标线性规划问题的示例代码: ```pythonfrom pulp import * # 创建问题实例prob = LpProblem("Multi-objective Linear Programming", LpMinimize) # 创建变量x1 = LpVariable("x1", lowBound=0) x2 = LpVariable("x2", lowBound=0) # 定义目标函数prob +=2*x1 +3*x2 # 第一个目标函数prob +=4*x1 +2*x2 # 第二个目标函数# 添加约束条件prob += x1 + x2 <=5prob +=2*x1 + x2 >=4# 求解问题prob.solve() # 输出结果print("Optimization status:", LpStatus[prob.status]) print("Optimal solution:") for v in prob.variables(): print(v.name, "=", v.varValue) print("Optimal objective function values:") for i, obj in enumerate(prob.objectives()): print("Objective", i+1, "=", value(obj)) ``` 在这个示例中,我们使用了`LpProblem`来创建了一个名为"Multi-objective Linear Programming"的问题实例。然后,我们使用`LpVariable`创建了两个变量`x1`和`x2`。接下来,我们定义了两个目标函数,并使用`+=`语法将它们添加到问题中。我们还通过`+=`语法添加了两个约束条件。最后,我们使用`prob.solve()`来求解问题,并使用`LpStatus`来打印求解状态。最优解和目标函数值可以通过遍历变量和目标函数来获取。 希望这个示例能帮助你开始解决多目标线性规划问题!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Scc_hy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值