创建具有验证条件的IPL板球队的所有组合

问题描述

因此,我在Dream11应用程序上下注。在该应用中,您必须从22名球员中选择11名球队。它对一支有效的球队有一些限制。

约束(例如CSK与MI):
检票口数量可以从1到4
击球手的数量可以从3到6
全能选手的数量可以从1到4
保龄球的人数可以从3到6
从CSK选拔的球员人数应小于等于7
从MI中选择的玩家人数应小于等于7
所有选定玩家的总积分应小于等于100

现在的问题是,有时候当创建这些团队时,当他们释放阵容并且您选择的许多球员都没有参加比赛时,或者当一个参加比赛的球队比其他球队更强大时,创建一个真正困难的任务。因此,我想到了一个程序,在该程序中我可以输入22人参加的比赛,并且可以获得我可以组成的11名球员的所有有效球队。

这是输入文件格式:
(第一行仅供参考,它在原始文件中不存在。每列都是制表符分隔的,因为这样很容易从Excel中复制粘贴。)


#Name   #Credit   #Team1   #Team2   #WK   #BAT   #ALL   #BOWL   #Sel
Glenn Maxwell   8.5 1   0   0   0   1   0   0
Chris Woakes    9   0   1   0   0   1   0   0
Mitchell Marsh  8   1   0   0   0   1   0   0
marcus Stoinis  8.5 1   0   0   0   1   0   0
Jonny Bairstow  9.5 0   1   1   0   0   0   0
Jos Buttler 9.5 0   1   1   0   0   0   0
Alex Carey  8.5 1   0   1   0   0   0   0
Eoin Morgan 9   0   1   0   1   0   0   0
Sam Billings    8   0   1   0   1   0   0   0
Joe Root    10  0   1   0   1   0   0   0
David Warner    10  1   0   0   1   0   0   0
Aaron Finch 9.5 1   0   0   1   0   0   0
Marnus Labuschagne  8.5 1   0   0   1   0   0   0
Jason Roy   9   0   1   0   1   0   0   0
Jofra Archer    9   0   1   0   0   0   1   0
Tom Curran  8.5 0   1   0   0   0   1   0
Adil Rashid 9   0   1   0   0   0   1   0
Mark Wood   8.5 0   1   0   0   0   1   0
Josh Hazlewood  8.5 1   0   0   0   0   1   0
Mitchell Starc  9   1   0   0   0   0   1   0
Pat Cummins 9   1   0   0   0   0   1   0
Adam Zampa  8.5 1   0   0   0   0   1   0

“积分”列具有相应玩家的积分。在所有其他列中,0表示相应的玩家不是那个东西,而1表示相应的玩家不是那个东西(例如,Team1列中的1表示该球员属于实际比赛团队1,WK列中的1表示该球员是检票员。)

这是我编写的用于完成此任务的程序。

import itertools
ValidTeam = []
with open("Players.txt","r") as dfile:
    players = [t for t in dfile.read().split("\n")]
combos = list(itertools.combinations(players,11))
for combo in combos:
    crd,t1,t2,wk,bat,alr,bowl = 0,0
    for tplayer in combo:
        player = tplayer.split("\t")
        crd += float(player[1])
        t1 += int(player[2])
        t2 += int(player[3])
        wk += int(player[4])
        bat += int(player[5])
        alr += int(player[6])
        bowl += int(player[7])
    if crd <= 100 and t1 <= 7 and t2 <= 7 and (wk in range(1,5)) and (bat in range(3,7)) and (alr in range(1,5)) and (bowl in range(3,7)):
        ValidTeam.append(combo)
        print(player)
    print("")
print(ValidTeam)

现在问题是由于某种原因,我不明白它正在显示错误消息

Traceback (most recent call last):
  File "C:\Users\RACHIT\Desktop\TM.py",line 12,in <module>
    crd += float(player[1])
IndexError: list index out of range

请帮我解决这个问题。 另外,由于将有22C11可能的队伍,并且在将来,选定的队长和副队长也具有特殊特权,因此它成为2! * 22C11,再加上许多团队的验证部分,再加上我正在考虑将来也要处理那些有效的团队,以从中选择最好的团队,因此可能需要很多时间来处理。因此,将使它变得更快,更高效,更好的想法将受到赞赏和欢迎。

PS:我是第一次使用itertools,所以对此没有太多了解,但它确实非常方便。

解决方法

改进范围:

  1. players = [t.split('\t') for t in dfile.read().split("\n")]

    字符串操作很昂贵。而不是在生成组合后稍后再执行,而是先执行。这样,您将只对所有玩家执行一次。

  2. 您可以并行处理连击。将您的内部循环转换为处理列表的函数。使用pool.map。

实施示例:

import multiprocessing as mp

def fun(combo):
    # Implement your logic here for one team,similar to your logic inside current for loop
    # return True if valid else if invalid return False 

if __name__ == '__main__':
    .
    .  # Implement reading players from file and generating list of combinations
    .

    num_workers = mp.cpu_count()
    with mp.Pool(num_workers) as pool:
        valid_teams = [c for c,keep in zip(combos,pool.map(fun,combos)) if keep]

    # do something with valid_teams

参考: https://docs.python.org/3/library/multiprocessing.html

,

list index out of range表示您正在尝试访问不存在的数组索引,

player [1]假定在tplayer.split("\t")中形成的玩家数组具有至少2个元素。拆分未产生这样的数组,应解决该问题