通过在每个索引处随机选取元素来合并 N 个列表

我有一个 bajillion 配对列表,每对大小相等。我想通过从每个索引中选择一个随机元素来“合并”每个元素,但是我当前的实现非常慢 -即使在多处理时也是如此。(FWIW,我的代码确实需要可线程化)。


def rand_merge(l1, l2):

    newl = []

    for i in range(len(l1)):

        q = random.choice([l1, l2])

        newl.append(q[i])

    return newl

非常基本,但是在 20k 大小约 5-25 的列表上运行它,需要很长时间 - 我认为它是 random.choice 搞砸了工作。但我也尝试过其他版本的 random,比如创建一个由 0 和 1 组成的字符串来引用,不行。


编辑:更清晰:这是一种遗传算法,旨在通过匹配语料库来写句子。有问题的列表是按单词分割的句子。GA 正在将获胜的健身“父母”“合并”到孩子中,每个孩子都是两个父句子的“基因”的合并。这意味着“列表”确实需要匹配,并且不能从更大的列表列表中提取(我不认为)。


这里有一些代码...


from multiprocessing import Pool as ThreadPool

import random


def offspring(parents):

    child = []

    p1 = parents[0].split(' ')

    p2 = parents[1].split(' ')

    for i in range(min(len(p1), len(p2))):

        q = random.choice([p1, p2])

        child.append(q[i])

    child = ' '.join([g for g in child]).strip()

    return child


def nextgen(l): #l is two lists of previous generation and grammar seed

    oldgen = l[0][:pop] # Population's worth of previous generation

    gramsent = l[1] # this is the grammar seed

    newgen = []

    newgen.append(tuple([oldgen[0][0], oldgen[0][0]]))  # Keep the winner!

    for i in range(len(oldgen) - len(oldgen)//4):

        ind1 = oldgen[0][0] # paired off against the winner - for larger pools, this is a random.sample/"tournament"

        ind2 = oldgen[i][0]

        newgen.append(tuple([ind1, ind2]))

    pool = ThreadPool(processes=8)

    newgen = pool.map(offspring, newgen)

    pool.close()

    pool.join()

人口和世代可以一起进入高数,并且每个句子都贯穿始终。自从最初发布问题以来,担心每一代人都需要很长时间才能滚动,我发现(对我来说令人头疼)漫长的处理时间实际上(几乎)与“人口”大小或数量无关的列表。每一代变异大约需要 15 秒。我将人口从 50 增加到 50000,代数从 15 秒增加到 17 秒左右。因此,缓慢显然隐藏在其他地方。


FFIVE
浏览 144回答 1
1回答
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java