Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 通过适当的约束条件,得出可行的解决方案_Python_Pulp_Integer Programming - Fatal编程技术网

Python 通过适当的约束条件,得出可行的解决方案

Python 通过适当的约束条件,得出可行的解决方案,python,pulp,integer-programming,Python,Pulp,Integer Programming,我正在尝试为特定数量的赛程选择15名球员。我的问题由两个二进制变量组成,分别是player和fixture choices = LpVariable.dicts( "Choices", (fixtures, constraints["player"]), 0, 1, LpBinary) 我想使用此约束限制为一组固定装置挑选的球员数量(这很糟糕-它计算所有挑选的球员,而不是使用的球员数量): 我的目标是从一个夹具到另一个夹具选择15个和少量的更改,但由于某些原因,这些约束

我正在尝试为特定数量的赛程选择15名球员。我的问题由两个二进制变量组成,分别是player和fixture

choices = LpVariable.dicts(
            "Choices", (fixtures, constraints["player"]), 0, 1, LpBinary)
我想使用此约束限制为一组固定装置挑选的球员数量(这很糟糕-它计算所有挑选的球员,而不是使用的球员数量):

我的目标是从一个夹具到另一个夹具选择15个和少量的更改,但由于某些原因,这些约束产生了不可行的问题。例如,如果我搜索
fixtures=[0,1,2]
当我将传输限制设置为45(15*3)时,问题变得可行。我不知道如何制定转移限制来实现我的目标

例如:

players = [1, 2, 3, 4, 5, 6]
fixtures = [1, 2, 3]

prob = LpProblem(
    "Fantasy football selection", LpMaximize)

choices = LpVariable.dicts(
    "Players", (fixtures, players), 0, 1, LpBinary)

# objective function
prob += lpSum([predict_score(f, p) * choices[f][p]
               for p in players for f in fixtures]), "Total predicted score"

# constraints
for f in fixtures:
    # total players for each fixture
    prob += lpSum([choices[f][p] for p in players]) == 2, ""
    if f != fixtures[0]:
        # max of 1 change between fixtures
        prob += lpSum([1 if choices[f-1][p] != choices[f]
                       [p] else 0 for p in players]) <= 2, ""

prob.solve()
print("Status: ", LpStatus[prob.status])
players=[1,2,3,4,5,6]
固定装置=[1,2,3]
问题(
“梦幻足球精选”,LPS)
选项=LpVariable.dicts(
“球员”(固定装置,球员),0,1,LpBinary)
#目标函数
prob+=lpSum([predict_score(f,p)*选项[f][p]
对于球员中的p,对于固定装置中的f),“总预测分数”
#约束条件
对于固定装置中的f:
#每场比赛的球员总数
prob+=lpSum([choices[f][p]代表玩家中的p])==2“
如果f!=固定装置[0]:
#固定装置之间最多可更换1次
prob+=lpSum([1如果选择[f-1][p]!=choices[f]

[p] 其他0表示玩家中的p。)我建议引入额外的二进制变量,用于跟踪ficture
f
和fixture
f-1
之间是否进行了更改。然后可以对允许的更改数量应用约束

在下面的示例代码中,如果您注释掉最后一个约束,您将发现实现了更高的目标,但付出了更多更改的代价。还请注意,我为目标函数中的非零
更改
变量添加了一个很小的惩罚-这是为了在未进行更改时将它们强制为零-此小惩罚对于此方法的工作不是必需的,但可能会使查看发生了什么变得更容易

如果没有最后一个约束,则应获得目标值
118
,但只有
109

from pulp import *
import random

players = [1, 2, 3, 4, 5]
fixtures = [1, 2, 3, 4]
random.seed(42)

score_dict ={(f, p):random.randint(0,20) for f in fixtures for p in players}

def predict_score(f,p):
    return score_dict[(f,p)]

prob = LpProblem(
    "Fantasy football selection", LpMaximize)

# Does fixture f include player p
choices = LpVariable.dicts(
    "choices", (fixtures, players), 0, 1, LpBinary)

changes = LpVariable.dicts(
    "changes", (fixtures[1:], players), 0, 1, LpBinary)

# objective function
prob += lpSum([predict_score(f, p) * choices[f][p]
               for p in players for f in fixtures]
              ) - lpSum([[changes[f][p] for f in fixtures[1:]] for p in players])/1.0e15, "Total predicted score"

# constraints
for f in fixtures:
    # Two players for each fixture
    prob += lpSum([choices[f][p] for p in players]) == 2, ""

    if f != fixtures[0]:
        for p in players:
            # Assign change constraints, force to one if player
            # is subbed in or out
            prob += changes[f][p] >= (choices[f][p] - choices[f-1][p])
            prob += changes[f][p] >= (choices[f-1][p] - choices[f][p])

        # Enforce only one sub-in + one sub-out per fixture (i.e. at most one change)
        # prob += lpSum([changes[f][p] for p in players]) <= 2

prob.solve()
print("Status: ", LpStatus[prob.status])

print("Objective Value: ", prob.objective.value())

choices_soln = [[choices[f][p].value() for p in players] for f in fixtures]
print("choices_soln")
print(choices_soln)

changes_soln = [[changes[f][p].value() for p in players] for f in fixtures[1:]]
print("changes_soln")
print(changes_soln)
来自纸浆进口*
随机输入
玩家=[1,2,3,4,5]
固定装置=[1,2,3,4]
随机种子(42)
score_dict={(f,p):random.randint(0,20)for f in fixture for p in players}
def预测分数(f,p):
返回分数(f,p)]
问题(
“梦幻足球精选”,LPS)
#赛程f包括球员p吗
选项=LpVariable.dicts(
“选择”(赛程、球员)、0、1、LpBinary)
changes=LpVariable.dicts(
“变化”(fixture[1:],players),0,1,LpBinary)
#目标函数
prob+=lpSum([predict_score(f,p)*选项[f][p]
对于球员中的p,对于固定装置中的f]
)-lpSum([[f][p]对于固定装置中的f[1:][p]对于球员中的p])/1.0e15,“总预测分数”
#约束条件
对于固定装置中的f:
#每场比赛两名球员
prob+=lpSum([choices[f][p]代表玩家中的p])==2“
如果f!=固定装置[0]:
对于p-in玩家:
#指定更改约束,强制一个if玩家
#卧铺在里面还是在外面
prob+=更改[f][p]>=(选项[f][p]-选项[f-1][p])
prob+=更改[f][p]>=(选项[f-1][p]-选项[f][p])
#每个夹具仅执行一次分入+一次分出(即最多一次更改)

#prob+=lpSum([changes[f][p]表示玩家中的p])你能提供一个答案吗?另外,你能更清楚地解释一下你正在努力实现的约束吗?我读了文本,但仍然不清楚缺少的约束的目的是什么。嘿,我添加了一个简单的例子,我正在努力实现的约束是“夹具之间最多改变1次”,例如,它产生了不可行的解决方案。我想这是因为变量之间相互依赖,可能是一个非线性方程。一般来说,你不能按照你所指出的方式使用
if
语句,但会有一种方法来表达你想要的约束。。。您只需考虑二进制变量需要哪些操作/约束。还有什么是
predict_score()
函数?它返回一个整数,指示玩家的分数我尝试回答下面的问题。请注意,对于一个完整的应用程序,您应该真正执行任何所需的导入,并提供任何此类函数的最小实现。例如,请参阅我在答案中输入的dummy
predict_score()。
players = [1, 2, 3, 4, 5, 6]
fixtures = [1, 2, 3]

prob = LpProblem(
    "Fantasy football selection", LpMaximize)

choices = LpVariable.dicts(
    "Players", (fixtures, players), 0, 1, LpBinary)

# objective function
prob += lpSum([predict_score(f, p) * choices[f][p]
               for p in players for f in fixtures]), "Total predicted score"

# constraints
for f in fixtures:
    # total players for each fixture
    prob += lpSum([choices[f][p] for p in players]) == 2, ""
    if f != fixtures[0]:
        # max of 1 change between fixtures
        prob += lpSum([1 if choices[f-1][p] != choices[f]
                       [p] else 0 for p in players]) <= 2, ""

prob.solve()
print("Status: ", LpStatus[prob.status])
from pulp import *
import random

players = [1, 2, 3, 4, 5]
fixtures = [1, 2, 3, 4]
random.seed(42)

score_dict ={(f, p):random.randint(0,20) for f in fixtures for p in players}

def predict_score(f,p):
    return score_dict[(f,p)]

prob = LpProblem(
    "Fantasy football selection", LpMaximize)

# Does fixture f include player p
choices = LpVariable.dicts(
    "choices", (fixtures, players), 0, 1, LpBinary)

changes = LpVariable.dicts(
    "changes", (fixtures[1:], players), 0, 1, LpBinary)

# objective function
prob += lpSum([predict_score(f, p) * choices[f][p]
               for p in players for f in fixtures]
              ) - lpSum([[changes[f][p] for f in fixtures[1:]] for p in players])/1.0e15, "Total predicted score"

# constraints
for f in fixtures:
    # Two players for each fixture
    prob += lpSum([choices[f][p] for p in players]) == 2, ""

    if f != fixtures[0]:
        for p in players:
            # Assign change constraints, force to one if player
            # is subbed in or out
            prob += changes[f][p] >= (choices[f][p] - choices[f-1][p])
            prob += changes[f][p] >= (choices[f-1][p] - choices[f][p])

        # Enforce only one sub-in + one sub-out per fixture (i.e. at most one change)
        # prob += lpSum([changes[f][p] for p in players]) <= 2

prob.solve()
print("Status: ", LpStatus[prob.status])

print("Objective Value: ", prob.objective.value())

choices_soln = [[choices[f][p].value() for p in players] for f in fixtures]
print("choices_soln")
print(choices_soln)

changes_soln = [[changes[f][p].value() for p in players] for f in fixtures[1:]]
print("changes_soln")
print(changes_soln)