我已阅读了几篇帖子,没有任何内容可以帮助我解决这个问题。我找到了关于每种可能组合的信息,但是我发现每个列表中的所有值的组合而不是列表本身。 (以下是我之前关于导入访问文件的问题的链接,以获取我正在做的更多示例:How do I import an .accdb file into Python and use the data?)。
假设我有一个来自Access的导入列表。
CreatureID Name Atk Def HP Type BattlePower
---------- -------- ------ ------ ----- --------- -----------
1 Snake 1000 500 200 Reptile 20
2 Mouse 500 200 100 Mammal 20
3 Turtle 200 2000 2000 Amphibian 40
4 Cat 1500 700 400 Mammal 20
5 Dog 1700 800 600 Mammal 40
6 Bird 100 100 200 Bird 20
7 Badger 2000 1500 1000 Mammal 40
8 Squirrel 300 200 200 Mammal 20
我一直试图弄清楚如何使用导入的访问数据将每个生物信息存储为一组列表。
creatureList = [ [1, 'Snake', 1000, 500], [2, 'Mouse', 500, 200],
[3, 'Turtle', 200, 2000], [4, 'Cat', 1500, 700],
[5, 'Dog', 1700, 800], [6, 'Bird', 100, 100],
[7, 'Badger', 2000, 1500] ]
在列出清单之后,我需要创建所有可能的生物组合中的5个组。 (可能不需要上一步来完成此操作但不确定)。
group1List = [ [1, 'Snake', 1000, 500], [2, 'Mouse', 500, 200],
[3, 'Turtle', 200, 2000], [4, 'Cat', 1500, 700],
[5, 'Dog', 1700, 800] ]
group2List = [ [1, 'Snake', 1000, 500], [2, 'Mouse', 500, 200],
[3, 'Turtle', 200, 2000], [4, 'Cat', 1500, 700],
[6, 'Bird', 100, 100] ]
group3List = [ [1, 'Snake', 1000, 500], [2, 'Mouse', 500, 200],
[3, 'Turtle', 200, 2000], [4, 'Cat', 1500, 700],
[7, 'Badger', 2000, 1500]]
group4List = [ [2, 'Mouse', 500, 200], [3, 'Turtle', 200, 2000],
[4, 'Cat', 1500, 700], [5, 'Dog', 1700, 800],
[6, 'Bird', 100, 100] ]
group5List = [ [2, 'Mouse', 500, 200], [3, 'Turtle', 200, 2000],
[4, 'Cat', 1500, 700], [5, 'Dog', 1700, 800],
[7, 'Badger', 2000, 1500] ]
接下来的几个步骤我希望能够将每个组的总功能和def功能相加,并能够将它们相互比较,以找到总统计数据最高的组。
group1total = [4900, 4200]
group2total = [3300, 3500]
group3total = [5200, 4900]
试图让它变得比它需要的更难。这是工作代码。
LIST = []
import pypyodbc
import itertools
import operator
pypyodbc.lowercase = False
conn = pypyodbc.connect(
r"Driver={Microsoft Access Driver (*.mdb, *.accdb)};" +
r"Dbq=C:\Users\Ju\Desktop\Dark Summoner.accdb;")
cur = conn.cursor()
cur.execute("SELECT Number, ID, Name, Atk, Def, HP, BP, Species, Special FROM Impulse_AA");
while True:
row = cur.fetchone()
if row is None:
break
listadd = [row]
LIST = LIST+ listadd
GROUPS = max(((sum(map(lambda x:x[4]+x[5]+x[6],c)),c) for c in
itertools.combinations(LIST,5)),key=operator.itemgetter(0))[1]
我正在尝试存储可能的团队列表,以便稍后进行其他计算。不确定存储信息是否是最佳方式,或者每次重新计算是否更好。
但截至目前,该计划已经开始运行并且永远不会结束(或者至少在5-10分钟之后不会结束)。我目前的数据库中有189种生物,它们是1,905,305,787种组合。
制作所有可能组的原因是还有其他因素需要考虑。我更新了creatureList,以反映一些例子。
BattlePower bonus = 10% atk and 10% def, all creatures have the same battle power
Type bonus = 15% atk and 15% def, all creatures have the same type
创建团队后,有32种不同的组合奖励可供检查。我认为创建列表然后检查组奖金比检查一个组并添加奖金一样并且比较每个组以查看哪个最好是不那么重要。此外,一旦创建了列表并存储了所有max stats,我将尝试将其导出为Microsoft Access文档,这样我只需要在新生物出来时运行计算。
答案 0 :(得分:1)
作为一个单行:
>>> max(((sum(map(lambda x:x[2]+x[3],c)),c) for c in
itertools.combinations(creatureList,5)),key=operator.itemgetter(0))[1]
([1, 'Snake', 1000, 500],
[3, 'Turtle', 200, 2000],
[4, 'Cat', 1500, 700],
[5, 'Dog', 1700, 800],
[7, 'Badger', 2000, 1500])
itertools.combinations(creatureList,5)
返回所有5元素生物组合的迭代器。
(sum(map(lambda x:x[2]+x[3],c)),c)
是给定5元素组合和组合本身的攻击/防御值之和的元组。
max(...,key=...)
返回具有最大攻击/防御总和值的元组。
max(...)[1]
提取相应的组合。
<强>更新强>
根据问题的编辑和生物的数量(189),有一种更好的方式来说明导致更简单解决方案的问题。你有效地为每个生物总结攻击和防御值,然后为5个生物的组合寻找这些值的最大总和。最大的总和将对应于具有最高个人攻击/防御总和的5个生物(因为总和是关联的和可交换的)。
所以,你可以通过创建一个按攻击/防御总和排序的生物列表来获得你正在寻找的结果,然后选择列表末尾的5个生物(这比尝试每个可能的组合要快得多): / p>
>>> [x for x in sorted(creatureList,key=lambda x: x[2]+x[3])][-5:]
[[1, 'Snake', 1000, 500],
[3, 'Turtle', 200, 2000],
[4, 'Cat', 1500, 700],
[5, 'Dog', 1700, 800],
[7, 'Badger', 2000, 1500]]
此解决方案的问题在于它没有考虑攻击/防御总和相等的生物。当可能存在多个解决方案时,它只会提供单一解决方案。以下代码是处理该问题的一种方法:
result = list() # the desired list of 5 creature groups
base = list() # the prefix of all 5 creature groups
length = 5 # the number of creatures remaining to create a 5 creature list
for group in reversed([[x for x in g]
for k,g in itertools.groupby(
sorted(map(lambda x: x + [x[2]+x[3]],creatureList),
key=operator.itemgetter(4)),
key=operator.itemgetter(4))]):
grouplen = len(group)
if grouplen <= length:
base.extend(group)
length -= grouplen
elif length:
for c in itertools.combinations(group,length):
result.append(base + list(c))
break
鉴于这些生物:
[ [1, 'Snake', 1000, 500],
[2, 'Mouse', 500, 200],
[3, 'Turtle', 200, 2000],
[4, 'Cat', 1500, 700],
[5, 'Dog', 1700, 800],
[6, 'Bird', 100, 100],
[7, 'Badger', 2000, 1500],
[8, 'XXX', 500, 1000] ]
结果是:
[ [ [7, 'Badger', 2000, 1500, 3500],
[5, 'Dog', 1700, 800, 2500],
[3, 'Turtle', 200, 2000, 2200],
[4, 'Cat', 1500, 700, 2200],
[1, 'Snake', 1000, 500, 1500] ],
[ [7, 'Badger', 2000, 1500, 3500],
[5, 'Dog', 1700, 800, 2500],
[3, 'Turtle', 200, 2000, 2200],
[4, 'Cat', 1500, 700, 2200],
[8, 'XXX', 500, 1000, 1500] ] ]
附加字段是攻击/防御总和。如果需要,很容易摆脱。但这是我将要为你留下的一项练习。
答案 1 :(得分:0)
这称为Combinations,Python具有标准功能:itertools.combinations。
请记住,组合数量为n!/(k!*(n-k!))
- 因此它会快速增长。对于100个生物,它将是7500万,对于1000个生物,超过8万亿。使用迭代器,不要试图将其放入内存列表中。