如何生成包含几个随机整数的列表?
How to generate a list with couples of random integers?
我对 Python 和 NetworkX 比较陌生。我需要创建一个类似于 Edgelist=[(0,1),(0,3),(1,0),(1,2),(1,4),(2,1),(2,5)]
的列表,其中的元素代表 边的起始节点和结束节点 (link),后者又是网络的一部分.
我希望 Python 通过从分配的值范围内随机选择 (start,end)
的整数值(即 0, 999
),表示节点 ID。然后,我想确保每个节点 ID 至少包含一次在(开始,结束)值系列中(这意味着我的所有节点都将连接到至少一个其他节点).
我知道我可以使用 random.randint(0, 999)
但我不知道如何将它 "nest" 用于创建列表(也许是 for 循环?)。我希望我有一些代码可以向您展示,但这是我第一次尝试使用 NetworkX!
编辑
为了让您直观地理解我的意思,这里有两张图片。第一个是规则网络(又名格子),第二个是随机网络。第一个的边列表是手动创建的,以便复制国际象棋 table,而第二个显示的边列表是第一个的(手动)洗牌对应的边列表。 如您所见,节点保存在完全相同的位置。希望这对您有所帮助。谢谢!
random.seed(datetime.datetime.now())
from random import randint
# ot generate 100 tuples with randints in range 0-99
li = [(randint(0,99),randint(0,99)) for i in range(100)]
print(li)
[(80, 55), (3, 10), (66, 65), (26, 23), (8, 72), (83, 25), (24, 99), (72, 9), (52, 76), (72, 68), (67, 25), (72, 18), (94, 62), (7, 62), (49, 94), (29, 89), (11, 38), (52, 51), (19, 32), (20, 85), (56, 61), (4, 40), (97, 58), (82, 2), (50, 82), (77, 5), (2, 9), (2, 46), (39, 4), (74, 40), (69, 15), (1, 77), (45, 58), (80, 59), (85, 80), (27, 80), (81, 4), (22, 33), (77, 60), (75, 87), (43, 36), (60, 34), (90, 54), (75, 3), (89, 84), (51, 93), (62, 64), (81, 50), (15, 60), (33, 97), (42, 62), (83, 26), (13, 33), (41, 87), (29, 63), (4, 32), (6, 14), (79, 73), (95, 4), (41, 16), (96, 64), (15, 28), (35, 13), (35, 82), (77, 16), (63, 27), (75, 37), (11, 52), (21, 35), (37, 96), (9, 86), (83, 11), (5, 42), (34, 32), (17, 8), (65, 55), (58, 19), (90, 40), (18, 75), (29, 14), (0, 11), (25, 68), (34, 52), (22, 8), (12, 53), (16, 49), (73, 54), (78, 80), (74, 60), (40, 68), (69, 20), (37, 38), (74, 60), (53, 90), (25, 48), (44, 52), (49, 27), (28, 35), (29, 94), (35, 60)]
这是一个解决方案,它首先生成随机的节点群 (pop1
),然后对其进行洗牌 (pop2
) 并将它们组合成一对列表。
注意:此方法仅生成每个节点恰好一次 start
和恰好一次 end
的顶点,所以可能不是您想要的.另一种方法见下文
import random, copy
random.seed() # defaults to time.time() ...
# extract a number of samples - the number of nodes you want
pop1 = random.sample(xrange(1000), 10)
pop2 = copy.deepcopy( pop1 )
random.shuffle( pop2 )
# generate pairs from the same population - this guarantees your constraint
pairs = zip( pop1, pop2 )
print pairs
输出:
[(17, 347), (812, 688), (347, 266), (731, 342), (342, 49), (904, 17), (49, 731), (50, 904), (688, 50), (266, 812)]
还有一个方法
这允许节点重复出现。
这个想法是从同一群体中绘制 start
和 end
节点:
import random
random.seed()
population = range(10) # any population would do
# choose randomly from the population for both ends
# so you can have duplicates
pairs = [(random.choice(population), random.choice(population) for _ in xrange(100)]
print pairs[:10]
输出:
[(1, 9), (7, 1), (8, 6), (4, 7), (6, 2), (7, 3), (0, 2), (1, 0), (8, 3), (8, 3)]
对于列表创建,您可以执行以下操作:
import random
max = 999
min = 0
original_values = range(min, max) # could be arbitrary list
n_edges = # some number..
my_edge_list = [(random.choice(original_values), random.choice(original_values))
for _ in range(n_edges)]
要断言您拥有所有值,您可以执行以下操作
vals = set([v for tup in my_edge_list for v in tup])
assert all([v in vals for v in original_values])
断言将确保您的边缘具有正确的表示。至于尽最大努力确保您没有达到该断言,您可以做几件事。
- 从您的整数列表中无替换地采样,直到它们都消失以创建一个 "base network",然后随机添加更多满足您的心愿
- 使 n_edges 足够高,很可能会满足您的条件。如果不是再试一次...
这真的取决于您要使用网络做什么以及您希望它具有什么样的结构
编辑: 我更新了我的回复,使其对任意值列表更加稳健,而不是需要顺序列表
有一个类似的答案,但对于一个完整的图表 - How to generate a fully connected subgraph from node list using python's networkx module
在你的情况下,使用 zubinmehta's answer:
import networkx
import itertools
def complete_graph_from_list(L, create_using=None):
G = networkx.empty_graph(len(L),create_using)
if len(L)>1:
if G.is_directed():
edges = itertools.permutations(L,2)
else:
edges = itertools.combinations(L,2)
G.add_edges_from(edges)
return G
您可以将图表构建为:
S = complete_graph_from_list(map(lambda x: str(x), range(0,1000)))
print S.edges()
Python 具有名为 itertools 的内置库。
以下示例说明您如何实现您提到的目标:
import itertools
list = [3, 4, 6, 7]
sublist_length = 2
comb = itertools.combinations(list, sublist_length)
这将 return comb 作为迭代器。
您可以 comb.next()
获取迭代器中的下一个元素或迭代 for 循环以获得您想要的所有结果,如下所示。
for item in comb:
print item
应该输出:
(3, 4),
(3, 6),
(3, 7),
(4, 6),
(4, 7),
(6, 7),
希望这能解决您的问题。
这是一个 networkx 命令,它将创建一个图,使每个节点只有一条边:
import networkx as nx
G = nx.configuration_model([1]*1000)
如果您仔细研究它,它会执行以下操作来回答您的问题 - 每个节点将 恰好 出现在一个边上。
import random
mylist = random.suffle(range(start,end))
edgelist = []
while mylist:
edgelist.append((mylist.pop(),mylist.pop()))
你应该保证 mylist
在弹出之前长度是均匀的。
我对 Python 和 NetworkX 比较陌生。我需要创建一个类似于 Edgelist=[(0,1),(0,3),(1,0),(1,2),(1,4),(2,1),(2,5)]
的列表,其中的元素代表 边的起始节点和结束节点 (link),后者又是网络的一部分.
我希望 Python 通过从分配的值范围内随机选择 (start,end)
的整数值(即 0, 999
),表示节点 ID。然后,我想确保每个节点 ID 至少包含一次在(开始,结束)值系列中(这意味着我的所有节点都将连接到至少一个其他节点).
我知道我可以使用 random.randint(0, 999)
但我不知道如何将它 "nest" 用于创建列表(也许是 for 循环?)。我希望我有一些代码可以向您展示,但这是我第一次尝试使用 NetworkX!
编辑
为了让您直观地理解我的意思,这里有两张图片。第一个是规则网络(又名格子),第二个是随机网络。第一个的边列表是手动创建的,以便复制国际象棋 table,而第二个显示的边列表是第一个的(手动)洗牌对应的边列表。 如您所见,节点保存在完全相同的位置。希望这对您有所帮助。谢谢!
random.seed(datetime.datetime.now())
from random import randint
# ot generate 100 tuples with randints in range 0-99
li = [(randint(0,99),randint(0,99)) for i in range(100)]
print(li)
[(80, 55), (3, 10), (66, 65), (26, 23), (8, 72), (83, 25), (24, 99), (72, 9), (52, 76), (72, 68), (67, 25), (72, 18), (94, 62), (7, 62), (49, 94), (29, 89), (11, 38), (52, 51), (19, 32), (20, 85), (56, 61), (4, 40), (97, 58), (82, 2), (50, 82), (77, 5), (2, 9), (2, 46), (39, 4), (74, 40), (69, 15), (1, 77), (45, 58), (80, 59), (85, 80), (27, 80), (81, 4), (22, 33), (77, 60), (75, 87), (43, 36), (60, 34), (90, 54), (75, 3), (89, 84), (51, 93), (62, 64), (81, 50), (15, 60), (33, 97), (42, 62), (83, 26), (13, 33), (41, 87), (29, 63), (4, 32), (6, 14), (79, 73), (95, 4), (41, 16), (96, 64), (15, 28), (35, 13), (35, 82), (77, 16), (63, 27), (75, 37), (11, 52), (21, 35), (37, 96), (9, 86), (83, 11), (5, 42), (34, 32), (17, 8), (65, 55), (58, 19), (90, 40), (18, 75), (29, 14), (0, 11), (25, 68), (34, 52), (22, 8), (12, 53), (16, 49), (73, 54), (78, 80), (74, 60), (40, 68), (69, 20), (37, 38), (74, 60), (53, 90), (25, 48), (44, 52), (49, 27), (28, 35), (29, 94), (35, 60)]
这是一个解决方案,它首先生成随机的节点群 (pop1
),然后对其进行洗牌 (pop2
) 并将它们组合成一对列表。
注意:此方法仅生成每个节点恰好一次 start
和恰好一次 end
的顶点,所以可能不是您想要的.另一种方法见下文
import random, copy
random.seed() # defaults to time.time() ...
# extract a number of samples - the number of nodes you want
pop1 = random.sample(xrange(1000), 10)
pop2 = copy.deepcopy( pop1 )
random.shuffle( pop2 )
# generate pairs from the same population - this guarantees your constraint
pairs = zip( pop1, pop2 )
print pairs
输出:
[(17, 347), (812, 688), (347, 266), (731, 342), (342, 49), (904, 17), (49, 731), (50, 904), (688, 50), (266, 812)]
还有一个方法
这允许节点重复出现。
这个想法是从同一群体中绘制 start
和 end
节点:
import random
random.seed()
population = range(10) # any population would do
# choose randomly from the population for both ends
# so you can have duplicates
pairs = [(random.choice(population), random.choice(population) for _ in xrange(100)]
print pairs[:10]
输出:
[(1, 9), (7, 1), (8, 6), (4, 7), (6, 2), (7, 3), (0, 2), (1, 0), (8, 3), (8, 3)]
对于列表创建,您可以执行以下操作:
import random
max = 999
min = 0
original_values = range(min, max) # could be arbitrary list
n_edges = # some number..
my_edge_list = [(random.choice(original_values), random.choice(original_values))
for _ in range(n_edges)]
要断言您拥有所有值,您可以执行以下操作
vals = set([v for tup in my_edge_list for v in tup])
assert all([v in vals for v in original_values])
断言将确保您的边缘具有正确的表示。至于尽最大努力确保您没有达到该断言,您可以做几件事。
- 从您的整数列表中无替换地采样,直到它们都消失以创建一个 "base network",然后随机添加更多满足您的心愿
- 使 n_edges 足够高,很可能会满足您的条件。如果不是再试一次...
这真的取决于您要使用网络做什么以及您希望它具有什么样的结构
编辑: 我更新了我的回复,使其对任意值列表更加稳健,而不是需要顺序列表
有一个类似的答案,但对于一个完整的图表 - How to generate a fully connected subgraph from node list using python's networkx module
在你的情况下,使用 zubinmehta's answer:
import networkx import itertools def complete_graph_from_list(L, create_using=None): G = networkx.empty_graph(len(L),create_using) if len(L)>1: if G.is_directed(): edges = itertools.permutations(L,2) else: edges = itertools.combinations(L,2) G.add_edges_from(edges) return G
您可以将图表构建为:
S = complete_graph_from_list(map(lambda x: str(x), range(0,1000)))
print S.edges()
Python 具有名为 itertools 的内置库。 以下示例说明您如何实现您提到的目标:
import itertools
list = [3, 4, 6, 7]
sublist_length = 2
comb = itertools.combinations(list, sublist_length)
这将 return comb 作为迭代器。
您可以 comb.next()
获取迭代器中的下一个元素或迭代 for 循环以获得您想要的所有结果,如下所示。
for item in comb:
print item
应该输出:
(3, 4),
(3, 6),
(3, 7),
(4, 6),
(4, 7),
(6, 7),
希望这能解决您的问题。
这是一个 networkx 命令,它将创建一个图,使每个节点只有一条边:
import networkx as nx
G = nx.configuration_model([1]*1000)
如果您仔细研究它,它会执行以下操作来回答您的问题 - 每个节点将 恰好 出现在一个边上。
import random
mylist = random.suffle(range(start,end))
edgelist = []
while mylist:
edgelist.append((mylist.pop(),mylist.pop()))
你应该保证 mylist
在弹出之前长度是均匀的。