[英]Python linear programming - how to constrain a variable to be an integer
I would like to maximize the probability of winning a raffle by buying a certain number of tickets. 我想通过购买一定数量的彩票来最大化赢得抽奖的机率。 For this, I wrote the following code 为此,我编写了以下代码
import numpy as np
import math as mt
from scipy.optimize import minimize
from pulp import *
def objective(tickets, winners = 500, losers = 2500, cost_of_ticket = 40, winning_amt = 1000):
Pwin = 1 - mt.factorial(losers)//mt.factorial(losers - tickets)*mt.factorial(winners+losers-tickets)/mt.factorial(winners+losers)
Ewin = Pwin*(winning_amt - cost_of_ticket*tickets)
return Ewin
# declare your variables
tickets = LpVariable("tickets", range(0, 10)) # 0<= tickets <= 10
prob = LpProblem("problem", LpMaximize)
#define the objective
prob += objective(tickets)
# solve the problem
status = prob.solve(GLPK(msg=0))
LpStatus[status]
# print the results
value(tickets)
The issue seems to be that the number of tickets that get passed into the objective function is not an integer (and the factorial function then fails). 问题似乎是传递到目标函数的票证数量不是整数(然后析因函数失败)。 Can anyone suggest how I should ensure that the ticket is restricted to positive integer values? 谁能建议我如何确保票证限制为正整数值?
The answer, for checking, should be 8. I can do this by manually calling the objective function and checking. 检查的答案应该是8。我可以通过手动调用目标函数并进行检查来做到这一点。
Your objective is really 你的目标是真的
ExpWin(t) = choose(N,t)*(A-C*t)
where t is an integer variable and N,A,C are constants. 其中t是整数变量,而N,A,C是常数。 This is a nonlinear function so a linear MIP solver will not be able to handle this. 这是非线性函数,因此线性MIP求解器将无法处理该函数。
For this problem it is silly, but in general we can linearize this. 对于这个问题,这很愚蠢,但是总的来说,我们可以将其线性化。 Introduce binary variables x(i) with: 引入带有以下内容的二进制变量x(i):
x(i) = 1 if tickets=i
0 otherwise
This can be enforced by 可以通过以下方式强制执行
sum(i,x(i)) = 1
sum(i,i*x(i)) = tickets
This only makes sense if the range of variable tickets is small (in your case 10). 仅当可变凭单的范围较小(在您的情况下为10)时,这才有意义。 Now we can precalculate a constant array w(i) which is the expected win if the number of tickets is i. 现在我们可以预先计算一个常数数组w(i),如果票数为i,这就是预期的获胜率。 Now the objective can look like: 现在目标看起来像:
max sum(i, w(i)*x(i))
which is now linear. 现在是线性的。
Anyway it is always a good idea to step away from code and write down the problem in math. 无论如何,离开代码并写下数学问题总是一个好主意。 This can help you think about the problem in a different way. 这可以帮助您以不同的方式考虑问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.