【问题标题】:Python linprog minimization--simplex methodPython linprog 最小化--单纯形法
【发布时间】:2018-02-03 01:18:21
【问题描述】:

我正在使用 scipy.optimize.linprog 库来使用单纯形法计算最小化。我正在我的教科书中解决这个问题,我希望有人能指出我正确的方向,因为我没有得到我期望的输出。问题是:

Minimize          w = 10*y1 + 15*y2 + 25*y3
Subject to:       y1 + y2 + y3 >= 1000
                  y1 - 2*y2    >= 0
                            y3 >= 340
with              y1 >= 0, y2 >= 0

我为此编写的代码是:

import numpy as np
import pandas as pd
from scipy.optimize import linprog
A = np.array([
[1, 1, 1],
[1,-2, 0],
[0, 0, 1]])
b = np.array([1000,0,340])
c = np.array([-10,-15,-25])
res = linprog(c, A_ub=A, b_ub=b,
bounds=(0, None))
print('Optimal value:', res.fun, '\nX:', res.x)

它给出了输出:

Optimal value: -18400.0
X: [   0.  660.  340.]

我希望它是:

Optimal value: -15100.0
X: [   660.  0.  340.]

我似乎无法找到与此功能的一致性,但也许这就是我使用它的方式。

【问题讨论】:

    标签: python numpy optimization scipy linear-algebra


    【解决方案1】:

    您的输入设置稍有错误;见the manual。具体来说,您有许多符号错误。

    1. 您的向量c 符号错误; linprog 最小化c x 所以c 应该只是w = c x 中的系数

    2. 您的向量b 和矩阵A 有错误的符号。它们的符号应倒置以从您的约束形式 f(x) >= const 切换到 linprog 方法所需的形式,即小于或等于,即 -f(x) <= - const

    3. 您缺少最后两个约束。

    4. 您建议的最小值 w = 10*x1 + 15*x2 + 25*x3 始终是积极的,您的约束为 x1,x2,x3>=0。

    正确的代码如下:

    import numpy as np
    from scipy.optimize import linprog
    
    A = np.array([[-1, -1, -1], [-1,2, 0], [0, 0, -1], [-1, 0, 0], [0, -1, 0]])
    b = np.array([-1000, 0, -340, 0, 0])
    c = np.array([10,15,25])
    
    res = linprog(c, A_ub=A, b_ub=b,bounds=(0, None))
    
    print('Optimal value:', res.fun, '\nX:', res.x)
    # python2
    # ('Optimal value:', 15100.0, '\nX:', array([ 660.,    0.,  340.]))
    # python3
    # Optimal value: 15099.999961403426 
    # X: [6.59999996e+02 1.00009440e-07 3.40000000e+02]
    

    【讨论】:

    • 这是一个很好的解释——谢谢!!我希望文档有更多示例,并且像这样解释得更好。我最初有带有正确符号的向量 c,但因为没有得到任何输出而切换了它们。就向量 b 和矩阵 A 而言,我应该知道要反转符号——更重要的是,我应该已经意识到所有示例都显示小于或等于并且我需要进行切换。我完全错过了最后两个约束。
    • @R.Cox 对,python2 和 python3 的打印格式似乎略有不同,但结果是一样的,不是吗,上面提到的格式差异?
    【解决方案2】:

    由于在bounds=(0, None)下可以保证y1和y2的正性,简化版代码如下:

    import numpy as np
    from scipy.optimize import linprog
    
    A = np.array([[-1, -1, -1], [-1,2, 0], [0, 0, -1]])
    b = np.array([-1000, 0, -340])
    c = np.array([10,15,25])
    
    res = linprog(c, A_ub=A, b_ub=b,bounds=(0, None))
    print('Optimal value:', res.fun, '\nX:', res.x) 
    

    输出:

    Optimal value: 15099.999961403195 
    
    X: [6.59999996e+02 1.00009440e-07 3.40000000e+02]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-29
      • 2020-08-25
      • 2010-11-18
      • 2022-06-11
      • 2015-07-29
      • 1970-01-01
      相关资源
      最近更新 更多