说,我有一组独特的离散参数值,存储在变量'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的方式吗? (通过使用链接列表或任何其他方法的概念?或者列表是多余的?)
答案 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)
邻域可以用图表表示。如果N
是B
的邻居并不一定意味着B
是A
的邻居,则定向。否则它是无向。我猜你想要一个无向图,因为你想要记住节点之间的关系&#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