python - 使用 Python 的纸浆时如何基于决策变量创建约束程序
问题描述
介绍
我想使用 Python 的纸浆创建一个“使用决策变量(如果语法)的开关”。这里,“使用决策变量切换(if语法)”是指,例如,“当x(x是大于或等于0的整数)和y(y是0、1的二进制变量)是决策变量时,如果x为大于等于1的整数,y输出1,如果x为0,y输出0。下面是一个简单的例子,公式见下附问题公式3(图)。
下面是一个简单的例子,展示了我们如何尝试创建“带有决策变量的开关(if 语法)”以及我们取得的结果。
这些示例是通过参考“运筹学导论”(东海大学出版社)中的示例创建的。
一家冰淇淋店计划生产两种冰淇淋:浓缩咖啡冰淇淋和覆盆子冰淇淋。然而,他无法生产尽可能多的产品,因为他只能生产 8000 cc 的牛奶并工作 360 分钟。每个冰淇淋都需要这么多的牛奶和时间,增加产量以实现利润最大化的计划是什么?然而,今天,一份覆盆子冰淇淋的覆盆子数量(配料)将到期。因此,您需要生产至少一种覆盆子冰淇淋,以免浪费。
产品名称 | 需要的牛奶量 | 工作时间 | 利润 |
---|---|---|---|
咖啡冰淇淋 | 100cc | 7 分钟 | 50日元 |
覆盆子冰淇淋 | 150cc | 5分钟 | 10日元 |
上述问题设置可以表述如下
作为一个Python程序,可以表示如下
import pulp
problem = pulp.LpProblem('ice', pulp.LpMaximize)
# Define the decision variables
x_e = pulp.LpVariable('x_e', lowBound=0, cat=pulp.LpInteger)
x_r = pulp.LpVariable('x_r', lowBound=0, cat=pulp.LpInteger)
# Set the objective function
problem += 50*x_e +10*x_r
# Set constraints
problem += 100*x_e + 150* x_r <= 8000
problem += 7*x_e + 5*x_r <= 360
## Newly added constraint
problem += x_r >= 1
# # optimize
problem.solve()
# # print the result
print("Espresso",x_e.value(), "pieces")
print("raspberry",x_r.value(), "pieces")
print("profit",pulp.value(problem.objective), "yen")
运行上述程序的结果如下。我们能够在不丢弃即将过期的覆盆子(一个覆盆子冰淇淋的数量)的情况下最大化我们的利润。
Espresso 50.0 pieces
raspberry 2.0 pieces
profit 2520.0 yen
挑战:在引入一个约束后,该约束充当我自己创建的“带有决策变量(如果语法)的开关”(冰淇淋生产问题)
在上一章中,我们在原来的基本问题上添加了以下约束
#Newly added constraints
problem += x_r >= 1
为了与这个问题的主题保持一致,我们将把这个约束重写为“switch with decision variables (if syntax)”约束,如下所示
import pulp
problem = pulp.LpProblem('ice', pulp.LpMaximize)
# Define a decision variable
x_e = pulp.LpVariable('x_e', lowBound=0, cat=pulp.LpInteger)
x_r = pulp.LpVariable('x_r', lowBound=0, cat=pulp.LpInteger)
### Newly added decision variable
y_r = pulp.LpVariable('y_r', lowBound=0, cat=pulp.LpBinary)
# Set the objective function
problem += 50*x_e +10*x_r
# Set constraints
problem += 100*x_e + 150* x_r <= 8000
problem += 7*x_e + 5*x_r <= 360
### Newly added constraint
if x_r.value() >= 1:
y_r=1
problem += y_r == 1
# # Optimize
problem.solve()
# Print the result
print("Espresso",x_e.value(), "pieces")
print("raspberry",x_r.value(), "pieces")
print("profit",pulp.value(problem.objective), "yen")
结果如下,我报错了。
if x_r.value() >= 1:
TypeError: '>=' not supported between instances of 'NoneType' and 'int'
我尝试在上面进行处理,但我无法使用决策变量创建开关(如果语法)。
是否不可能在纸浆中创建和解决这样的约束(= 使用决策变量切换(如果语法))?(对不起我没有学习,但这是一个非线性问题,不能用纸浆表达吗?)(对不起,我没有学习,但也许这是一个非线性问题,不能用纸浆表达?)或者它只是我写得不好的程序?
如果您能告诉我原因和解决方案,我将不胜感激。(如果可以的话,我想用我熟悉的pull,但是如果可以不用pull写程序,我想挑战一下,所以请告诉我。)
解决方案
您不能添加基于的约束,x_r.value()
因为在问题解决之前它不可用。
更好的方法是连接x_r
并y_r
通过两个额外的约束:
problem += M*y_r >= x_r
problem += y_r <= x_r
这M
是一个足够大的数字,您的数据设置M = min(8000/150, 360/5)
就足够了。
推荐阅读
- android - Firebase 检查电子邮件是否存在(fetchProvidersForEmail 替代方案)
- r - R以交错(交叉)形式组合两个表
- oracle - Windows 上 Oracle XE 11g 的 ORA-12505
- ios - 无法从swift ios中的一段tableview中删除单元格
- python - python在循环期间返回命令提示符,然后恢复循环
- ios - 为什么我的 UITableView 不再工作了?
- qt - qml mousearea overlab 在悬停模式下不起作用
- javascript - 使用 chrome.downloads API 下载文件
- laravel - Ldap/Laravel - 使用 SSL 或 TLS 时连接不成功“使用未定义的常量 LDAP_OPT_X_TLS_CACERTFILE”
- c - 系统编程:Fork()