创建相互邻居元素的列表

时间:2018-02-12 06:48:32

标签: python list

说,我有一组独特的离散参数值,存储在变量'para'中。

para=[1,2,3,4,5,6,7,8,9,10]

此列表中的每个元素都有'K'个邻居(给定:每个邻居εpara)。

编辑:对于每个元素,这个'K'显然不相同。 并澄清我的问题的实际大小:我需要一个接近 50-100个邻居的邻居,因为我的参数列表大约是 1000个元素大。<​​/ p>

注意:元素的邻居是另一个可以通过单个突变跳转到的“元素值”。

neighbors_of_1 = [2,4,5,9] #contains all possible neighbors of 1 (i.e para[0])
  

问题:如何定义其他元素的 每个   来自'para'的邻居 随机 ,但请记住以前的   分配邻居/关系?

例如:

neighbors_of_5=[1,3,7,10] #contains all possible neighbors of 5 (i.e para[4])

注意:'1'已被指定为'5'的邻居,并记住'neighbors_of_1'的值。他们是“共同的”邻居。

我知道执行此操作的低效方法是,保持循环先前分配的列表并检查当前状态是否是另一个州的邻居,如果True,将该州的价值存储为新邻居之一。

有更清洁/更pythonic的方式吗? (通过使用链接列表或任何其他方法的概念?或者列表是多余的?)

2 个答案:

答案 0 :(得分:0)

我相信,这个解决方案可以满足您的需求。它不是最有效的,因为它会产生相当多的额外元素和数据,但是我的计算机上的运行时间仍然很短,我认为你不会在紧密的内循环中反复运行它?

import itertools as itools
import random

# Generating a random para variable:
#para=[1,2,3,4,5,6,7,8,9,10]
para = list(range(10000))
random.shuffle(para)
para = para[:1000]

# Generate all pais in para (in random order)
pairs = [(a,b) for a, b in itools.product(para, para) if a < b]
random.shuffle(pairs)

K = 50 # average number of neighbors
N = len(para)*K//2 # total connections

# Generating a neighbors dict, holding all the neighbors of an element
neighbors = dict()
for elem in para:
    neighbors[elem] = []

# append the neighbors to eachother
for pair in pairs[:N]:
    neighbors[pair[0]].append(pair[1])
    neighbors[pair[1]].append(pair[0])

# sort each neighbor list
for neighbor in neighbors.values():
    neighbor.sort()

我希望你理解我的解决方案。否则请随时提出几点建议。

答案 1 :(得分:0)

邻域可以用图表表示。如果NB的邻居并不一定意味着BA的邻居,则定向。否则它是无向。我猜你想要一个无向图,因为你想要记住节点之间的关系&#34;。

除了明显选择使用第三方库作为图形之外,您还可以通过在图形顶点之间使用一组边来解决您的问题。边缘可以由它们的两个末端代表。由于它们是无向的,因此要么使用元组(A,B),要么使用A < B,要么使用frozenset((A,B))

请注意,在算法中间需要考虑随机选择哪个邻居,比如不鼓励选择有很多邻居的节点,以避免超出限制。

这是我所做的伪代码。

edges = set()
arities = [ 0 for p in para ]
for i in range(len(para)):
   p = para[i]
   arity = arities[i]
   n = random.randrange(50, 100)
   k = n
   while k > 0:
       w = list(map(lambda x : 1/x, arities))
       #note: test what random scheme suits you best
       j = random.choices(para, weight = w )
       #note: I'm storing the vertices index in the edges rather than the nodes.
       #But if the nodes are unique, you could store the nodes.
       e = frozenset((i,j))
       if e not in edges:
           edges.add(e)
           #instead of arities, you could have a list of list of the neighbours.
           #arity[i] would be len(neighbors[i]), then
           arities[i] += 1
           arities[j] += 1
           k-=1