Scipy Optimizer或启发式方法,可选择瓶颈容量

时间:2018-01-14 17:27:12

标签: python optimization scipy

由于复杂的约束条件,我无法将以下问题制定为linprog minimizeB14。所以想检查是否有其他模块允许以下格式的块约束。

here

因为,这也检查瓶颈容量(由Objective中的约束来处理)我的检查是我们是否应该采用直接求解器或采用启发式方法来分配随机数并保持 - 平衡最慢的过程。迭代直到数字似乎收敛?。

问题详情:

Variables:F9,F10,F11各自单独且几乎相同(这是一个约束) - 背景是将p1,p2和p3视为串行进程,因此我希望每个都具有最大吞吐量同样的。(保理瓶颈)

Constraint:C6:E8。这些是百分比分配,因此应该在(0,1)(绑定)

之间

{{1}}:i)在'客观'中提到 - 每个过程的总产出应该是相同的。  即F9 = F10 = F11。

ii)特定机器的分配总和也应为100%。即sum(C6:C8)= 1,sum(D6:D8)= 1且sum(E6:E8)= 1

我在制定第一个约束时需要帮助。如何添加方程式以确保这3个单元格相等(F9:F11)?

1 个答案:

答案 0 :(得分:2)

一般建议

请展示一些尝试,并确保您的问题定义明确!如果没有前者,他们就没有那么积极,因为他们认为你甚至没有尝试过。后者要求解决从未要求的问题!

我假设,您的目标是最大化f9 + f10 + f11

建议第2部分

老实说:在线性编程中,这个问题非常简单,并且没有复杂的约束条件!要解决这些任务,请务必理解standard-form of LPs或多或少你需要做的一切(和linprog的API比真正的标准形式更容易使用)。

码的介绍

如上所述:我们需要做的就是为此建模LP。这里的基本想法是:

  • 引入辅助变量,它们模仿在其他约束中使用的中间值
    • 具有预处理能力的优秀求解器不会受到那些引入变量的影响(这将很容易制定)
    • scipy的linprog有两个不同的求解器:
      • 据我所知:只有IPM-one有(高级)预先决定
      • 但是对于你的模特大小:不需要预先决定:它是微不足道的!

<强>注:

  • 我没有检查结果
    • 也许我换了0/1;但代码将告诉你如何解决这个问题!
  • 我没有检查你的优化问题的一般概念(我认为它有意义!)
  • 如果这是对您的问题的正确解释,您现在也有答案:采取什么方法?因为LP非常快速地解决并且有很多免费软件可用
    • linprog更快&amp;比scipy(更一般的基于非线性的)最小化
    • 更健壮(参见最后的评论)
    • 保证找到最佳解决方案(如果有的话)(与您提到的替代方法形成对比)

代码

import numpy as np
from scipy.optimize import linprog

""" Create LP in (modified) standard-form for linprog-API """

# VARIABLES
# ---------
# vars: 9
# auxiliary/helper-vars: 12 -> c9, c10, c11, ..., f9, f10, f11
# all vars: 21
# layout x VECTOR: c6, c7, c8, d6, d7, d8, e6, e7, e8,
#  continued:      c9, c10, c11, d9, d10, d11, e9, e10, e11, f9, f10, f11

# BOUNDS
# ------
bounds = [(0, 1) for i in range(9)] + \
         [(None, None) for i in range(12)]  # aux-vars
            # depending on assumptions about input / model:
            # more restricted domains possible (e.g. nonnegative)!

# CONSTRAINTS
# -----------
# only equality constraints!

# example:
#     c3=2 * c6      = c9
# <->    2 * c6      = c9
# <->    2 * c6 - c9 = 0

# HANDMADE DENSE-MATRIX
# For more advanced tasks: scipy.sparse based constructions -> observe patterns!
A_eq = np.array([[1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],     # c6 + c7 + c8
                 [0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],     # d6 + d7 + d8
                 [0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0],     # e6 + e7 + e8
                 [2,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0],    # 2*c6 = c9
                 [0,2,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0],    # ...
                 [0,0,4,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0],    # ...
                 [0,0,0,3,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0],    # 3*d6 = d9
                 [0,0,0,0,4,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0],    # ...
                 [0,0,0,0,0,4,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0],    # ...
                 [0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,-1,0,0,0,0,0],    # 2*e6 = e9
                 [0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,-1,0,0,0,0],    # ...
                 [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,-1,0,0,0],    # ...
                 [0,0,0,0,0,0,0,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0],  # f9 = sum(c9, d9, e9)
                 [0,0,0,0,0,0,0,0,0,0,-1,0,0,-1,0,0,-1,0,0,1,0],  # ...
                 [0,0,0,0,0,0,0,0,0,0,0,-1,0,0,-1,0,0,-1,0,0,1],  # ...
                 [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,0],    # f9 = f10
                 [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1]])   # f10 = f11

b_eq = np.array([1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0])

# OBJECTIVE
# ---------
#     max  f9 + f10 + f11
# <-> min -f9 - f10 - f11
c = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1])

# SOLVE
# -----
res = linprog(c, A_eq=A_eq, b_eq=b_eq, bounds=bounds)
print(res)

# GRAB SOL
x = res.x[:9].reshape((3,3), order='F')
print(x)

输出:

fun: -9.3333333333333339
message: 'Optimization terminated successfully.'
nit: 23
slack: array([ 0.77777778,  1.        ,  0.22222222,  0.77777778,  0.22222222,
   1.        ,  0.        ,  1.        ,  1.        ])
status: 0
success: True
  x: array([ 0.22222222,  0.        ,  0.77777778,  0.22222222,  0.77777778,
   0.        ,  1.        ,  0.        ,  0.        ,  0.44444444,
   0.        ,  3.11111111,  0.66666667,  3.11111111,  0.        ,
   2.        ,  0.        ,  0.        ,  3.11111111,  3.11111111,
   3.11111111])
[[ 0.22222222  0.22222222  1.        ]
[ 0.          0.77777778  0.        ]
[ 0.77777778  0.          0.        ]]

建议第3部分

Scipy的linprog(method=’simplex’)对我来说看起来非常错(看问题或其他SO问题)!

如果有可能,我强烈建议使用linprog(method=’interior-point’)(确保理解Simplex和内点方法之间的差异!)。

经过一些研究,您将了解method = IPM的输出:

fun: -9.3333333333174284
message: 'Optimization terminated successfully.'
nit: 6
slack: array([], dtype=float64)
status: 0
success: True
  x: array([  2.22222222e-01,   2.31362354e-14,   7.77777778e-01,
    2.22222222e-01,   7.77777778e-01,   4.90542917e-13,
    1.00000000e+00,   3.30588524e-12,   1.94200136e-12,
    4.44444444e-01,  -3.21898064e-12,   3.11111111e+00,
    6.66666667e-01,   3.11111111e+00,  -4.57278659e-12,
    2.00000000e+00,   1.67288405e-12,   3.06199510e-13,
    3.11111111e+00,   3.11111111e+00,   3.11111111e+00])

建议第4部分

特殊建模系统使这些配方更容易。因此,如果您能够负担得起scipy并使用外部软件(使用更严格的许可证),您可以尝试使用Coin OR的纸浆,Coin OR的pyomo,cvxpy和co。这些在不同的用例中彼此非常不同。