[英]PuLP doesn't work with one list but works with another. What is the difference between these two?
I'm new to python, picked it up because of Optimization and I've wanted to learn something new.我是 python 的新手,因为优化而选择了它,我想学习一些新东西。 I've made an lp solver program using PyQt5 and PuLP.
我使用 PyQt5 和 PuLP 制作了一个 lp 求解器程序。 The concept is simple: The user types in the Lp problem to a QTextEdit widget clicks the solve button then gets the result in a QTextBrowser.
这个概念很简单:用户在 QTextEdit 小部件中输入 Lp 问题,然后单击求解按钮,然后在 QTextBrowser 中获取结果。
The example exercise I'm using and trying to replicate:我正在使用并尝试复制的示例练习:
prob = LpProblem("LP problem", LpMaximize)
x1 = LpVariable("x1", lowBound=0, cat='Integer') # Integer variable x1 >= 0
x2 = LpVariable("x2", lowBound=0, cat='Integer') # Integer variable x2 >= 0
prob += x2<=4
prob += 4*x1 + 2*x2 <= 20
prob += 1*x1 + 4*x2 <= 12
prob += 4*x1 + 4*x2
prob.solve()
It works like a charm this way.这种方式就像一个魅力。 The function for the button:
按钮的 function:
def textToVar(self):
prob = LpProblem("LP problem", LpMaximize)
x1 = LpVariable("x1", lowBound=0, cat='Integer') # Integer variable x1 >= 0
x2 = LpVariable("x2", lowBound=0, cat='Integer') # Integer variable x2 >= 0
mytext = self.lpInput.toPlainText()
split = mytext.splitlines()
for ele in range(0, len(split)):
prob += split[ele]
prob.solve()
for v in prob.variables():
self.lpOutput.append(str(v.name) + ' = ' + str(v.varValue))
vmax = (value(prob.objective))
self.lpOutput.append('max = ' + str(vmax))
It does not work and I've figured it is because split = mytext.splitlines()
generates ['x2<=4', '4*x1+2*x2<=20', '1*x1+4*x2<=12', '4*x1+4*x2']
instead of [x2<=4, 4*x1+2*x2<=20, 1*x1+4*x2<=12, 4*x1+4*x2]
.它不起作用,我认为这是因为
split = mytext.splitlines()
生成['x2<=4', '4*x1+2*x2<=20', '1*x1+4*x2<=12', '4*x1+4*x2']
而不是[x2<=4, 4*x1+2*x2<=20, 1*x1+4*x2<=12, 4*x1+4*x2]
。 How can I convert my list from the first to the second one?如何将我的列表从第一个转换为第二个? Maybe I could use another method to store the input in a list or variable instead of
splitlines()
?也许我可以使用另一种方法将输入存储在列表或变量中,而不是
splitlines()
?
Thank you in advance!先感谢您!
You could use exec()
, like @AirSquid pointed out in their comment, but that does raise security issues.您可以使用
exec()
,就像@AirSquid 在他们的评论中指出的那样,但这确实会引发安全问题。 Another way would be to parse the strings, since you know what they will contain.另一种方法是解析字符串,因为您知道它们将包含什么。 Then, if something unexpected comes along, you can easily throw an error.
然后,如果出现意外情况,您很容易抛出错误。
import re
import pulp as pl
x1 = pl.LpVariable("x1", lowBound=0, cat='Integer') # Integer variable x1 >= 0
x2 = pl.LpVariable("x2", lowBound=0, cat='Integer') # Integer variable x2 >= 0
def parse_equation(string):
string_parts = re.split("(<=|=|>=)", string)
if len(string_parts) == 1:
# Objective function
return parse_equation_part(string_parts[0])
if len(string_parts) != 3:
raise Exception(f"Unexpected number of parts in {string_parts}")
lhs, comparator, rhs = (
parse_equation_part(string_parts[0]),
string_parts[1],
parse_equation_part(string_parts[2])
)
if comparator == "<=":
return lhs <= rhs
if comparator == ">=":
return lhs >= rhs
return lhs == rhs
def parse_equation_part(string):
addition_parts = re.split("(\+|-)", string)
result = parse_addition_part(addition_parts.pop(0))
while addition_parts:
symbol, addition_part, addition_parts =\
addition_parts[0], addition_parts[1], addition_parts[2:]
part_result = parse_addition_part(addition_part)
if symbol not in ('+', '-'):
raise Exception(f"Unexpected value {symbol}")
if symbol == '-':
result -= part_result
else:
result += part_result
return result
def parse_addition_part(string):
parts = string.split("*")
result = 1
for part in parts:
if part == 'x1':
result *= x1
elif part == 'x2':
result *= x2
elif part.isnumeric():
result *= float(part)
else:
raise Exception(f"Unexpected part {part}, expected number or x1/x2")
return result
for s in ['x2>=4', '4*x1+2*x2=20', '1*x1-4*x2<=12', '4*x1+4*x2']:
print(s.ljust(20, ' '), '->', parse_equation(s))
yields产量
x2>=4 -> x2 >= 4.0
4*x1+2*x2=20 -> 4.0*x1 + 2.0*x2 = 20.0
1*x1-4*x2<=12 -> x1 - 4.0*x2 <= 12.0
4*x1+4*x2 -> 4.0*x1 + 4.0*x2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.