我有一个代理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)
的结果,从而呈现了之后的计算结果当我们为代理a2
,a3
和a5
执行这些对时,这些对是多余的,
一种改进的算法是在两个维度(即沿着代理本身及其各自的合作伙伴)按升序对输入结构进行排序,如上例所示,以便每个代理(例如a3
) ,我们只需要计算此代理(a3
)与“高于”a5
)之间的交互,因为我们知道他自己和“低级”伙伴之间的交互(已经计算了(a1, a3)
,(a2, a3)
)。
我想知道这个问题是否有不同的更好的算法?更好的是,我的意思是在时间和空间方面更有效的计算。
答案 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)
>>> 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]}
仍然需要排序,但仅限于一对。