【问题标题】:Checking a large list of permutations. Any advice to get it to run faster?检查大量排列。有什么建议可以让它运行得更快吗?
【发布时间】:2022-11-03 18:31:10
【问题描述】:

我有大约 95,000,000 个排列要检查。 我有 8 个不同长度的列表,每个字符串标识在 Excel 表中定义的属性(a-k)。 例如

bcdgj

具有属性 b、c、d、g 和 j

我只需要找到一个包含每个属性至少 3 个的排列,然后将这些属性与电子表格中的数据匹配

我已经制作了这个脚本(我第一次尝试使用 python)

import numpy
import itertools

for x in itertools.product(['abfhj','bcdgj','fghij','abcj','bdgk','abgi','cdei','cdgi','dgik','aghi','abgh','bfhk'],['cdei','bcdgj','abcgi','abcj','abfj','bdfj','cdgi','bhjk','bdgk','dgik'],['afhk','cdgik','cegik','bdgi','cgij','cdei','bcgi','abgh'],['fhjk','bdgij','cgij','abk','ajk','bdk','cik','cdk','cei','fgj'],['abe','abcf','afh','cdi','afj','cdg','abi','cei','cgk','ceg','cgi'],['cdgi','bcgj','bcgi','bcdg','abfh','bdhi','bdgi','bdk','fhk','bei','beg','fgi','abf','abc','egi'],['bcdgik','cegik','chik','afhj','abcj','abfj'],['ceg','bcfg','cgi','bdg','afj','cgj','fhk','cfk','dgk','bcj']):
    gear = ''.join(x)
    count_a = gear.count('a')
    count_b = gear.count('b')
    count_c = gear.count('c')
    count_d = gear.count('d')
    count_e = gear.count('e')
    count_f = gear.count('f')
    count_g = gear.count('g')
    count_h = gear.count('h')
    count_i = gear.count('i')
    count_j = gear.count('j')
    count_k = gear.count('k')
    score_a = numpy.clip(count_a, 0, 3)
    score_b = numpy.clip(count_b, 0, 3)
    score_c = numpy.clip(count_c, 0, 3)
    score_d = numpy.clip(count_d, 0, 3)
    score_e = numpy.clip(count_e, 0, 3)
    score_f = numpy.clip(count_f, 0, 3)
    score_g = numpy.clip(count_g, 0, 3)
    score_h = numpy.clip(count_h, 0, 3)
    score_i = numpy.clip(count_i, 0, 3)
    score_j = numpy.clip(count_j, 0, 3)
    score_k = numpy.clip(count_k, 0, 3)
    rating = score_a + score_b + score_c + score_d + score_e + score_f + score_g + score_h + score_i + score_j + score_k
    if rating == 33:
        print(x)
        print(rating)

我已经调整了评级要求以测试它是否有效,但它需要一段时间来处理 95,000,000 个排列。有人有什么建议让它运行得更快吗? 我想我已经尽可能地减少了每个列表中的值的数量,数据来自的 excel 表每个列表有数百个条目,我已经设法将它减少到每个列表 6-12 个。

【问题讨论】:

  • 我很难理解你的问题。一个字符(字母)是属性还是字符串是属性?您能否举例说明什么是“好”排列和什么是“坏”排列,为什么?

标签: python optimization bigdata permutation


【解决方案1】:
from itertools import groupby, product

data = (
    ['abfhj','bcdgj','fghij','abcj','bdgk','abgi','cdei','cdgi','dgik','aghi','abgh','bfhk'],
    ['cdei','bcdgj','abcgi','abcj','abfj','bdfj','cdgi','bhjk','bdgk','dgik'],
    ['afhk','cdgik','cegik','bdgi','cgij','cdei','bcgi','abgh'],
    ['fhjk','bdgij','cgij','abk','ajk','bdk','cik','cdk','cei','fgj'],
    ['abe','abcf','afh','cdi','afj','cdg','abi','cei','cgk','ceg','cgi'],
    ['cdgi','bcgj','bcgi','bcdg','abfh','bdhi','bdgi','bdk','fhk','bei','beg','fgi','abf','abc ','egi'],
    ['bcdgik','cegik','chik','afhj','abcj','abfj'],
    ['ceg','bcfg','cgi','bdg','afj','cgj','fhk','cfk','dgk','bcj'],
)

for x in product(*data):
    permu = ''.join(x)
    prop_map = dict.fromkeys(permu)
    for prop, group in groupby(sorted(permu)):
        group_rating = len(tuple(group))
        # dont bother searching more props of this permutation if the current
        # property has a rating less than 3
        if group_rating < 3:
            break
        prop_map[prop] = group_rating
    # check if this permutation satisfies the requirement and exit if it does.
    if all(v is not None for v in prop_map.values()):
        print(x)
        print(prop_map)  # total rating of each property
        break

不确定这是否是您正在寻找的,但最明显的优化是通过在排列的属性没有至少 3 个实例时立即停止来“短路”搜索。这是通过首先对排列进行排序然后按属性对其进行分组来实现的。分组后,您检查每个属性的频率是否不小于 3。如果所有属性的检查都没有失败,那么您就有了答案,否则继续下一个排列。

在我的机器上运行上面的代码,我得到:

('abfhj', 'cdei', 'bdgi', 'bdgij', 'cei', 'abfh', 'afhj', 'ceg')
{'a': 3, 'b': 4, 'f': 3, 'h': 3, 'j': 3, 'c': 3, 'd': 3, 'e': 3, 'i': 4, 'g': 3}

ipython 会话的计算时间是 2.94s。我不确定这个速度对于您的用例是否可以接受。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 2020-02-27
    • 1970-01-01
    • 2011-09-25
    • 1970-01-01
    相关资源
    最近更新 更多