阵列生成器的位置约束

2024-04-29 00:34:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经建立了一个NBA阵容生成器,它使用为每个球员提供的投影优化了9个位置的阵容(2个控卫(PG)、2个得分后卫(SG)、2个小前锋(SF)、2个大前锋(PF)、1个中锋(C))

最初,为了处理可以打两个位置的球员,我设置了一个约束,阻止同一个球员在一个阵容中被选中两次,并且它工作正常。我偶尔遇到的问题是,当我构建多个阵容时,其中两个是重复的,但程序认为它们是不同的

发电机的第1版

例如,在一个阵容中,球员a和球员B都被选中,但他们都是双位置球员,并且他们共享相同的双位置(例如,两者都可以是PG或SG),因为发电机将交换他们,在阵容1中,球员A被选为PG,球员B被选为SG,在阵容2中,球员A被选为SG,球员B被选为PG

我在第一个版本中约束位置的代码如下所示:

    prob += (pulp.lpSum(self.positions['PG'][i] * players_lineup[i] for i in range(self.num_players)) == 2)
    prob += (pulp.lpSum(self.positions['SG'][i] * players_lineup[i] for i in range(self.num_players)) == 2)
    prob += (pulp.lpSum(self.positions['SF'][i] * players_lineup[i] for i in range(self.num_players)) == 2)
    prob += (pulp.lpSum(self.positions['PF'][i] * players_lineup[i] for i in range(self.num_players)) == 2)
    prob += (pulp.lpSum(self.positions['C'][i] * players_lineup[i] for i in range(self.num_players)) == 1)

因为程序将玩家A的PG版本和玩家A的SG版本视为单独的实体,所以它实际上改变了结果(尽管在功能上是相同的)

发电机的第2版

因此,我创建了一个更新版本,其中每个玩家都有一个位置1和位置2(如果玩家没有第二个位置,则可以为无)。我在这里遇到的问题是,我现在可以生成一个满足以下示例中的约束条件的列表,但该列表在技术上是不正确的。首先我将提供我的新约束,然后我将解释我的问题

    #Ensures that the lineup has at least 2 potential suitors for PG
    prob += (pulp.lpSum(self.positions['PG'][i] * players_lineup[i] for i in range(self.num_players)) >= 2)
    # Ensures that the lineup has no more than 2 players who can only play PG
    prob += (pulp.lpSum(
        self.positions['PG'][i] * self.dualPosition[i] * players_lineup[i] for i in range(self.num_players)) <=2)
    #Ensures that the lineup has at least 2 potential suitors for SG
    prob += (pulp.lpSum(self.positions['SG'][i] * players_lineup[i] for i in range(self.num_players)) >= 2)
    # Ensures that the lineup has no more than 2 players who can only play SG
    prob += (pulp.lpSum(
        self.positions['SG'][i] * self.dualPosition[i] * players_lineup[i] for i in range(self.num_players)) <= 2)
    #Ensures that the lineup has at least 2 potential suitors for SF
    prob += (pulp.lpSum(self.positions['SF'][i] * players_lineup[i] for i in range(self.num_players)) >= 2)
    # Ensures that the lineup has no more than 2 players who can only play SF
    prob += (pulp.lpSum(
        self.positions['SF'][i] * self.dualPosition[i] * players_lineup[i] for i in range(self.num_players)) <= 2)
    #Ensures that the lineup has at least 2 potential suitors for PF
    prob += (pulp.lpSum(self.positions['PF'][i] * players_lineup[i] for i in range(self.num_players)) >= 2)
    # Ensures that the lineup has no more than 2 players who can only play PF
    prob += (pulp.lpSum(
        self.positions['PF'][i] * self.dualPosition[i] * players_lineup[i] for i in range(self.num_players)) <= 2)
    #Ensures that the lineup has at least 1 potential suitor for C
    prob += (pulp.lpSum(self.positions['C'][i] * players_lineup[i] for i in range(self.num_players)) >= 1)
    # Ensures that the lineup has no more than 1 player who can only play C
    prob += (pulp.lpSum(
        self.positions['C'][i] * self.dualPosition[i] * players_lineup[i] for i in range(self.num_players)) <= 1)

我在这里面临的问题是,这些限制正在得到满足,但它们显然没有达到我希望它们达到的目标哈哈!我发现正在建立如下阵容:

^{tb1}$

基于上述情况,所有符合我的最低标准的可用PGs-5、SGs-4、SFs-3、PFs-2、C-1的总数。问题是所有SF和PF插槽的可用性都由3名玩家组成,因此,如果我将2个PF选项放入2个PF插槽中,我只剩下1个SF用于2个SF插槽

我不知道如何更新我的限制,以确保所有阵容的地点将有一个保证供应

对冗长的评论表示歉意,如果有什么我可以澄清的,请告诉我


Tags: inselfforrangesgnumpulppg
1条回答
网友
1楼 · 发布于 2024-04-29 00:34:26

我认为,如果你重新规划你的问题,你会更快乐。这里的整数程序自然适合使用一组玩家和一组位置对其进行双重索引。在你的约束条件等方面,事情会变得更加清晰,因为你可以对球员或位置进行求和,从而更清楚地阐述你的问题。实际上不清楚您的许多模型项是什么样子的positions[i]dualPositions[i]。这是一个玩具模型,它可以帮助你思考这个坏男孩的双重索引

请注意,有几种方法可以处理此部分的“法律转让”部分。下面是如何做到这一点的一个概念

# hoops dream team

from pulp import *

salaries = {'bob'   : 100,
            'steve' : 110,
            'bernie': 105,
            'eugene': 120,
            'biff'  : 115, 
            'reggie': 99,
            'mike'  : 102}

positions = {'PG','FWD', 'CTR'}

legal_assignments = {   'bob'   : {'PG'},
                        'steve' : {'PG', 'FWD'},
                        'bernie': {'FWD', 'CTR'},
                        'eugene': {'FWD', 'PG'},
                        'biff'  : {'PG'},
                        'reggie': {'CTR', 'FWD'},
                        'mike'  : {'FWD'}}

legal_assignments_set = { (k,v) for k in legal_assignments.keys() for v in legal_assignments[k]}

prob = LpProblem("Team", LpMinimize)

assign = LpVariable.dicts("assignment", legal_assignments_set, cat="Binary")

#minimize cost of team
prob += sum(assign[player, pos] * salaries[player] for (player, pos) in legal_assignments_set)

# constraints...

# only assign each player once
for player in salaries.keys():
    prob += sum(assign[player, pos] for pos in positions if (player, pos) in legal_assignments_set) <=1

# fill each position to 2 PG, 2 FWD, 1 CTR
prob += sum(assign[player, 'PG'] for player in salaries.keys() if (player, 'PG') in legal_assignments_set) == 2
prob += sum(assign[player, 'FWD'] for player in salaries.keys() if (player, 'FWD') in legal_assignments_set) == 2
prob += sum(assign[player, 'CTR'] for player in salaries.keys() if (player, 'CTR') in legal_assignments_set) == 1

prob.solve()
print('Status:', LpStatus[prob.status])
for v in prob.variables():
    print(v.name, '=', v.varValue)

相关问题 更多 >