简体   繁体   English

PuLP 不适用于一个列表,但适用于另一个列表。 这两者有什么区别?

[英]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.

相关问题 这两个简单的python代码有什么区别? (一个有效,另一个无效) - what's different between these two simple python codes? (one works and the other doesn't work) 同一个正则表达式在一个脚本中起作用,而在另一个脚本中不起作用 - Same regex works in one script, doesn't work in another Soup 可以在一个 IMBD 页面上工作,但不能在另一个页面上工作。 怎么解决? - Soup works on one IMBD page but not on another. How to solve? 字符串集之间的区别不起作用 - Difference between set of strings doesn't work Python:一个列表中两个位置之间的差异取决于另一个列表的规则集 - Python: Difference between two positions in one list depending on rule set for another list 这两个列表创建代码有什么区别(一个是带有 if 条件的普通 for 循环,另一个是线性代码) - What is the difference between these two list creation codes (one normal for loop with if condition and the other one liner code) IF CONDITION 在 Recaptcha 和另一个 Element 之间不起作用,只有 1 个有效。 Selenium python - IF CONDITION doesn't work between Recaptcha and another Element, just 1 works. Selenium python Django forms 的区别,一个有效,第二个无效 - Django forms difference, one works, the second one doesn't 两个清单之间的差异 - Difference between two list list(a)和[a]有什么区别? - What is the difference between list(a) and [a]?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM