【发布时间】:2019-04-14 05:18:25
【问题描述】:
我有一个 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 搞砸了工作。但我也尝试过其他版本的随机数,比如创建一个由 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 秒左右。所以缓慢显然隐藏在其他地方。
【问题讨论】:
-
您说“非常慢 - 即使在多处理时”您在多处理/多线程方面到底做了什么?您是否尝试过异步/多线程的组合?您对 multiXYZ 不满意的代码示例将非常有帮助,因此其他人不会提供您已经尝试过的示例。
-
你能举个小例子吗?
-
我发现速度变慢了 - 不是功能;就是每次我调用 pool.join() 时,main 之外的所有东西都会被调用,并且有很多文件加载设置。不幸的是,我无法在 main 内部进行设置,因此我必须删除多处理模块(据我所知)。
标签: python python-2.7 list random