由于复杂的约束条件,我无法将以下问题制定为linprog
minimize
或B14
。所以想检查是否有其他模块允许以下格式的块约束。
因为,这也检查瓶颈容量(由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)?
答案 0 :(得分:2)
请展示一些尝试,并确保您的问题定义明确!如果没有前者,他们就没有那么积极,因为他们认为你甚至没有尝试过。后者要求解决从未要求的问题!
我假设,您的目标是最大化f9 + f10 + f11
。
老实说:在线性编程中,这个问题非常简单,并且没有复杂的约束条件!要解决这些任务,请务必理解standard-form of LPs或多或少你需要做的一切(和linprog的API比真正的标准形式更容易使用)。
如上所述:我们需要做的就是为此建模LP。这里的基本想法是:
<强>注:强>
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. ]]
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])
特殊建模系统使这些配方更容易。因此,如果您能够负担得起scipy并使用外部软件(使用更严格的许可证),您可以尝试使用Coin OR的纸浆,Coin OR的pyomo,cvxpy和co。这些在不同的用例中彼此非常不同。