我一直在努力解决Python中的以下线性问题:
minimize{x1,x2}, such that:
x1+2*x2 = 2
2*x1+3*x2 =2
x1+x2=1
x1>=0
x2>=0
我已经尝试了纸浆和linprog库(from scipy.optimize import linprog
)但我没有任何地方。第一点是这两个库都希望我输入某种“目标函数”来最小化,而我正在寻求最小化我的变量(意味着基本上是为了验证我没有非常多的解决方案)。但是,我试图最小化以下目标函数:
x1 + x2
判断这几乎等于最小化x1和x2,因为它们都大于0.第二点是纸浆和linprog似乎都无法处理“不可行”的情况。这意味着,当这两个库都出现在一个不可行的问题前面时,而不是打印出相关的东西(即:“问题无法解决”),而是开始放弃约束直到得到答案。例如,上述问题是不可行的,因为没有满足所有上述等式的数字x1和x2。现在linprog在这种情况下打印出以下
message: 'Optimization terminated successfully.'
和
x: array([ 0., 0.])
从中我理解解决方案是x1 = 0和x2 = 0,这当然是不正确的。
我的下一步是使用嵌套for循环和条件语句来编写所有内容来描述约束,但我不想去那里。此外,我正在寻找一个可以很容易推广的解决方案,比如说100多个不同的方程(因为我将在实数的n维空间中做东西)和60多个变量(x1,x2,..., X60)。
答案 0 :(得分:3)
这是微不足道的,如果您遇到问题,我不明白为什么您没有显示任何代码:
代码:
import numpy as np
from scipy.optimize import linprog
A_eq = np.array([[1, 2], # x1+2*x2
[2, 3], # 2*x1+3*x2
[1, 1]]) # x1+x2
b_eq = np.array([2,2,1])
c = np.array([1,1]) # min x1 + x2
res = linprog(c, A_eq=A_eq, b_eq=b_eq, method='simplex')
print(res) # fails as expected;
# crypted message (for non-experts)
# scipy >= 1.0 !!!
res = linprog(c, A_eq=A_eq, b_eq=b_eq, method='interior-point')
print(res) # warns about problem-status in presolve
res = linprog(c, A_eq=A_eq, b_eq=b_eq, method='interior-point', options={'presolve': False})
print(res) # declares infeasible
# turning-off presolve sometimes needed
# for more accurate status messages
# (which is documented!)
需要其他信息:
bounds:sequence,optional
x中每个元素的(min,max)对,定义该参数的边界。 当在该方向上没有约束时,使用None作为min或max之一。 默认情况下,边界为(0,无)(非负)如果提供了包含单个元组的序列,则min和max将应用于问题中的所有变量。
这些运行都不会输出status = success! (和某些退出状态对应的标志已设置)
去检查设置了哪些属性。 (我没有显示那些因为我的scipy-install有点自定义一些私有调试打印)
scipy.linprog(method='simplex')
scipy.linprog(method='interior-point')
c
设置为零!这意味着当这两个库都出现在一个不可行的问题前面时,而不是打印出相关的东西(即:"问题无法解决"),他们反而开始放弃约束,直到他们得到一个回答。例如,上述问题是不可行的,因为没有满足所有上述方程的数字x1和x2。
否!。当问题不可行时,没有LP解算器应该返回成功的解决方案(除了说问题是不可行之外的其他问题!)。
此外,大多数LP解算器都支持不可行性检测(所有单纯类型求解器;并非所有类似IPM的求解器,但是scipy都有)并且当问题不可行时将返回可行性证书!
这里只有破解的解算器linprog(method='simplex')
可能很麻烦。
(上述内容适用于并非暗示数值问题的问题,使用有限内存浮点数学总是可行的;除了可能是专门的理性类型求解器。这甚至适用于最先进的商业求解器和这对你的问题不重要)
编辑:使用硬币的方法 pulp:
from pulp import *
prob = LpProblem("problem", LpMinimize)
x1 = LpVariable('x1', lowBound=0., upBound=None, cat='Continuous')
x2 = LpVariable('x2', lowBound=0., upBound=None, cat='Continuous')
# The objective function is added to 'prob' first
prob += 1.*x1 +1.*x2, "min x1 + x2"
# Constraints
prob += 1.*x1 + 2.*x2 == 2, "1*x1 + 2*x2 == 2"
prob += 2.*x1 + 3.*x2 == 2, "2*x1 + 3*x2 == 2"
prob += 1.*x1 + 1.*x2 == 1, "1*x1 + 1*x2 == 1"
# Solve
prob.solve()
print("Status:", LpStatus[prob.status])
for v in prob.variables():
print(v.name, "=", v.varValue)
print("Objective: ", value(prob.objective))
输出:
Status: Infeasible
x1 = 0.0
x2 = 1.0
Objective: 1.0