遍历多个列表以找到最佳的总体组合

2024-09-27 17:57:18 发布

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

我有一堆文件要迭代,以找到最佳的组合,并希望得到一些建议,如何做到这一点。我必须把 一起组成一个混合年龄的“接力”团队。我们每个年龄需要一个人。但是,我们有一个不能超过的最大重量。我们知道 大概每个人会得到多少分——最高的总分获胜。你知道吗

我有他们的年龄,他们的名字,体重和分数,如5.csv文件中的所有5岁的孩子(姓名,体重,分数)的所有窥视文件

JonnyM,54,20
SallyR,35,18
MeganP,33,25
...

6.csv中的6岁儿童具有相同的格式

DaveL,53,30
NancyP,40,28
...

etc高达20.csv。你知道吗

我想我可以用大量的打字来完成:

import csv
maxweight=5000
bestscore=0
bestcombo=[]
f5 = csv.reader(open("5.csv", "r"), delimiter=',')
f6 = csv.reader(open("6.csv", "r"), delimiter=',')
...
f20 = csv.reader(open("20.csv", "r"), delimiter=',')
for name5,weight5,score5 in 5f:
    for name6,weight6,score6 in 6f:
...
    ...(and a lot more)
        for name20,weight20,score20 in 20f:
            if((weight5+weight6+...weight20)<=maxweight):
                if((score5+score6+...score20)>bestscore):
                    bestcombo=[name5,name6,...name20]

但是,还有更好的办法。我确信这是显而易见的,但我对python也是相当陌生的。你知道吗


Tags: 文件csvinforopen分数readerdelimiter
2条回答

这里有一个解决方案,已经留下足够的意见,以便于理解。您可以用基于文件的读取来替换硬编码的数据列表

import itertools
from functools import reduce

MAX_WEIGHT = 100

#You can read data from files in for loop
csv5 = [('JonnyM',54,20), ('SallyR',35,18), ('MeganP',33,25)]
csv6 = [('HansM',18,20), ('JohnD',35,18)]
csv7 = [('MatG',30,25), ('BossT',36,26)]

args = []
for i in range(5, 8):
    exec('args.append(csv%s)'%i)

result = []
#get cartesian product of these lists
for combinedList in itertools.product(*args):
    #only those that are below the MAX_WEIGHT could be part of solution
    if reduce(lambda a, b: a+b, [e[1] 
        for e in combinedList], 0) <= MAX_WEIGHT:
        result.append(combinedList)

result.sort(key=lambda x: 
        reduce(lambda a, b:a+b, [e[2] for e in x], 0), 
        reverse=True)       

#for r in result:       
#   print(r)

#First element will have max score hence the solution       
print('Desired Solution:' )
print(result[0] )

您可以使用itertools.product。还应使用contextlib.ExitStack关闭文件:

from contextlib import ExitStack
import csv
import itertools

maxweight = 5000
bestscore = 0
bestcombo = []

with ExitStack() as stack:
    files = [csv.reader(stack.enter_context(open("{}.csv".format(i))), delimiter=',') for i in range(5, 21)]
    for combo in itertools.product(*files):
        names, weight_list, score_list = zip(*combo)
        weight = sum(map(int, weight_list))
        score = sum(map(int, score_list))
        if weight <= maxweight and score > bestscore:
            bestcombo = names
            bestscore = score

这是未经测试的(因为我没有访问文件的权限,也懒得合成有效的伪数据),所以如果出现错误,请告诉我。而且,这种方法相当幼稚,因此计算成本很高。你知道吗

相关问题 更多 >

    热门问题