实现Every-to-Every交互的有效方法?

时间:2010-02-18 13:22:24

标签: python c algorithm parallel-processing

给定一个元素列表,如果每个元素都需要知道该列表中每个其他元素的状态,如何处理所有元素?

例如,在Python中实现它的直接方法可能是:

S = [1,2,3,4]
for e in S:
  for j in S:
    if e!=j:
      process_it(e,j)

但如果元素数量巨大,则O(n²)非常慢。必须有另一种有效的方法,也包括并发性。你能救我吗?

3 个答案:

答案 0 :(得分:2)

如果你需要处理每对项目,那么就有O(n 2 )对,所以你必须进行多次调用!

如果您只需要组合(ab,ac,bc),而不是所有排列(ab,ba,ac,ca,bc,cb),那么你可以这样做,将调用次数减半(并跳过if):

for idA,val in enumerate(items):
    for idB in range(0, idA):
        process_it(val,items[idB]) 

改善它的唯一方法是找到一种分解你process_it例程的方法,这样它就可以在多对上运行。没有更多的信息,我们可以建议不多。

答案 1 :(得分:1)

以多进程方式处理给定任务的适用性取决于任务的 性质 以及各种子任务的相互依赖性(或缺乏性), 生成子任务列表的方式
换句话说,使用问题的措辞, 涉及并发 的能力 取决于process_it()方法是这样的事实:

  • 每次使用给定的参数集调用时,它会产生完全相同的结果(直接和副作用)。 (这是多可处理任务的典型案例)
  • 一系列调用的总体结果与系列的顺序无关(这是一个多处理任务的奇怪情况)。

并且它不依赖于对process_it()的一系列调用的顺序由列表的笛卡尔积产生的顺序(问题的 Every-to-Every )或者通过一些预先构建的列表或其他方式。

此外,问题的复杂性(问题中的O(n ^ 2))不会减少,因为问题是以多进程方式提交的。事实上,多进程逻辑通常会引入额外的复杂性(为组织和提供多个线程并为其结果提供“支付”);然而,这种增加的难度通常是问题的另一个数量级(例如恒定,或者可能是n线性),因此不会改变整体复杂性。

无关 能够将流程拆分为多个异步子任务,可能会降低问题的复杂性,正如其他一些答案中暗示的那样(例如,如果process_it(a,b)与process_it(b,a)相同,或者如果底层数据首先对其进行排序可以减少process_it需要的次数)被称为等。)

此外,虽然一些编程语言或库/环境使管理多处理更容易,但问题通常与语言无关;也许python标签和说明性片段以某种方式混淆了这个问题。

答案 2 :(得分:0)

一个可靠的选择是在FPGA中实现它并使它们同时工作。除此之外 - 如果没有例外,并且真的 - 所有 - 需要 - 所有 - 而不是“有些人需要一些”,那么你就会被判处标准方法。