2017-11-17 13 views
0

ある程度のチケットを購入することで、抽選で勝つ確率を最大限にしたいと考えています。このために、私は次のコードPythonの線形プログラミング - 変数を整数に制限する方法

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) 

を書いた問題は、目的関数に渡されるチケットの数が整数(そして失敗した階乗関数)ではないことのようです。誰かがチケットが正の整数値に限定されていることをどのように保証するべきか、誰にでも提案できますか?

答えは8でなければなりません。目的関数を手動で呼び出してチェックすることで、これを行うことができます。

+0

を説明しているまあ、明らかな方法はによってそれを整数に変換することです値に 'int()'を呼び出します。あなたがそれをすることができない理由はありますか? –

+0

申し訳ありませんが、私は少しこれに新しいです - しかし、どこを整数にする必要がありますか?目的関数で、またはLpVariableとして "チケット"を宣言したら? – user1936752

+0

説明[ここ](https://pythonhosted.org/PuLP/pulp.html#pulp.LpVariable)のような変数を定義するときに宣言する必要があります。あなたの関数ベースのアプローチがここではうまくいくかどうかは分かりませんが、それは難しいです。 – sascha

答えて

1

あなたの目的は、本当にtは整数変数とN、A、Cである

ExpWin(t) = choose(N,t)*(A-C*t) 

定数です。これは非線形関数なので、リニアMIPソルバはこれを処理できません。

この問題では、それはばかげていますが、一般的にはこれを線形化できます。これは、(あなたのケース10に)

sum(i,x(i)) = 1 
sum(i,i*x(i)) = tickets 

変数チケットの範囲が小さい場合にのみ意味をなすことにより、強制することができる

x(i) = 1 if tickets=i 
     0 otherwise 

:とのバイナリ変数x(i)を紹介します。チケットの数がiの場合に期待される勝利である定数配列w(i)を事前に計算することができます。今度は目的は次のようになります:

max sum(i, w(i)*x(i)) 

これは現在線形です。

とにかく、コードから離れて数学で問題を書き留めることは、常に良いアイデアです。これは、異なる方法で問題を考えるのに役立ちます。あなたがそれを定義するときには、整数に変数を制限することができ

0

:サシャさんのコメントを1として

tickets = LpVariable("tickets", range(0, 10), cat='Integer') # 0<= tickets <= 10

を、これはhere

関連する問題