成对计算的有效算法

时间:2012-06-06 23:23:51

标签: python algorithm data-structures

我有一个代理a = {a1, a2, a3,..., an}列表,其中每个代理可以与零个或多个其他代理配对。例如,对于n = 6,我可以:

a1: a2, a3, a5
a2: a1, a3, a4
a3: a1, a2. a5
a4: a2
a5: a1, a3
a6:
每个对彼此交互,每个代理都获得一个值作为这种交互的结果(例如,他们可以玩游戏,但是交互的细节可以在这里被抽象掉)。 我感兴趣的是根据给定的成对结构计算和存储这些交互的结果,如上所述。

显然,一个天真的算法是通过每个代理,然后逐个计算与他的每个交互伙伴的成对交互。 但是,很明显这种方法会复制一些(或可能很多)计算。使用上面的示例:

当我们完成代理a1时,我们已经获得了(a1, a2)(a1, a3)(a1, a5)的结果,从而呈现了之后的计算结果当我们为代理a2a3a5执行这些对时,这些对是多余的,

一种改进的算法是在两个维度(即沿着代理本身及其各自的合作伙伴)按升序对输入结构进行排序,如上例所示,以便每个代理(例如a3) ,我们只需要计算此代理(a3)与“高于”a5)之间的交互,因为我们知道他自己和“低级”伙伴之间的交互(已经计算了(a1, a3)(a2, a3))。

我想知道这个问题是否有不同的更好的算法?更好的是,我的意思是在时间和空间方面更有效的计算。

5 个答案:

答案 0 :(得分:3)

是的,这会尝试将每个对添加到集合中两次,但我觉得这可能比条件更有效。有没有人想尝试替代选择?

agents = {
    'a1': ['a2', 'a3', 'a5'],
    'a2': ['a1', 'a3', 'a4'],
    'a3': ['a1', 'a2', 'a5'],
    'a4': ['a2'],
    'a5': ['a1', 'a3'],
    'a6': []
}
pairs = {(k,v) for k in agents for v in agents[k]}

这仍然是O(n),因此在效率方面胜过涉及排序的任何事情

使用

可能会获得较小的加速
pairs = {(k,v) for k,vs in agents.iteritems() for v in vs}

答案 1 :(得分:2)

您可以将代理ID与以下内容进行比较:

agents = {
    'a1': ['a2', 'a3', 'a5'],
    'a2': ['a1', 'a3', 'a4'],
    'a3': ['a1', 'a2', 'a5'],
    'a4': ['a2'],
    'a5': ['a1', 'a3'],
    'a6': []
}

interactions = []
for agent, connections in agents.iteritems():
    interactions.extend((agent, connection) for connection in connections if agent < connection)

print interactions
# [('a1', 'a2'), ('a1', 'a3'), ('a1', 'a5'), ('a3', 'a5'), ('a2', 'a3'), ('a2', 'a4')]

答案 2 :(得分:0)

itertools救援

>>> from itertools import combinations
>>> agents=['a1','a2','a3','a4','a5']
>>> list(combinations(agents, 2))
[('a1', 'a2'), ('a1', 'a3'), ('a1', 'a4'), ('a1', 'a5'), 
 ('a2', 'a3'), ('a2', 'a4'), ('a2', 'a5'),
 ('a3', 'a4'), ('a3', 'a5'),
 ('a4', 'a5')]
>>> 

答案 3 :(得分:0)

据我了解你的问题,你为什么不考虑二维矩阵?在第一阶段,如果两个代理可以相互合作,则将交集单元设置为等于1。 在第二阶段,只需在矩阵周围设置一个周期,并仅在那些具有互连的代理(即,单元格等于1)之间计算一些值。而不是1,将有一个真正的价值。因此,在这种情况下,您不需要进行冗余计算。唯一的冗余部分是在矩阵中填充计算值两次。

答案 4 :(得分:0)

根据@ gnibbler的回答,我想出了这个:

agents = {
    'a1': ['a2', 'a3', 'a5'],
    'a2': ['a1', 'a3', 'a4'],
    'a3': ['a1', 'a2', 'a5'],
    'a4': ['a2'],
    'a5': ['a1', 'a3'],
    'a6': []
}

pairs = {tuple(sorted((k,v))) for k in agents for v in agents[k]}

仍然需要排序,但仅限于一对。