AI4Finance-Foundation / RLSolver

Solvers for NP-hard and NP-complete problems with an emphasis on high-performance GPU computing.

Home Page:https://ai4finance.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

📝 Generate a fixed graph with a constant random seed

Yonv1943 opened this issue · comments

Generate a fixed undirected graph with a constant random seed
固定随机种子,生成固定的无向图

固定完随机种子之后,算法内部会生成固定的伪随机数,
随机生成无向图的函数 generate_graph(),会“消耗”这些伪随机数

下面的代码,可以在指定无向图的节点数量num_nodes,图的生成方式g_type 以及 图的序号valid_i,直接用代码生成固定的图。无论使用什么设备。

我建议使用方案1,避免储存很多表示无向图的txt文件(不用担心文件丢失)。只要指定以下三个信息,就能直接生成无向图,对于这样的 graph_name = 'powerlaw_100_ID042',可以用函数直接生成唯一的无向图 :

  • 无向图的节点数量num_nodes=100
  • 图的生成方式g_type=‘powerlaw’
  • 图的序号valid_i=42

备注:在生成300个节点的图,我们用的是方案3。在2023-08-17日之后才改成方案1


方案1:将图的序号valid_i 作为 random seed 的序号,算力消耗最小,要换随机种子

import random
for valid_i in range(6):
    random.seed(valid_i) 
    graph, num_nodes, num_edges = generate_graph(num_nodes=num_nodes, g_type=g_type)
random.seed()  # 恢复随机种子的默认设置

方案2:固定随机种子后,消耗定量的随机数值,介于方案1与方案2之间。

import random
for valid_i in range(6):
    random.seed(0) 
    [random.random() for _ in range(valid_i * num_nodes)]
    graph, num_nodes, num_edges = graph, num_nodes, num_edges = generate_graph(num_nodes=num_nodes, g_type=g_type)
random.seed()  # 恢复随机种子的默认设置

方案3:固定随机种子后,直接调用生成函数,自动消耗定量的随机数值,在 valid_i 很大的时候消耗较多算力

import random
for valid_i in range(6):
    random.seed(0) 
    graph_tuples = [generate_graph(num_nodes=num_nodes, g_type=g_type) for _ in range(valid_i + 1)]
    graph, num_nodes, num_edges = graph_tuples[-1]
random.seed()  # 恢复随机种子的默认设置

下面是生成无向图的代码:

import networkx as nx


def load_graph(graph_name: str):
    import random

    graph_types = ['erdos_renyi', 'powerlaw', 'barabasi_albert']
    if graph_name.split('_')[0] in graph_types and len(graph_name.split('_')) == 3:
        g_type, num_nodes, valid_i = graph_name.split('_')
        num_nodes = int(num_nodes)
        valid_i = int(valid_i[len('ID'):])
        random.seed(valid_i)
        graph, num_nodes, num_edges = generate_graph(num_nodes=num_nodes, g_type=g_type)
        random.seed()
    elif graph_name.split('_')[0] in graph_types and len(graph_name.split('_')) == 2:
        g_type, num_nodes = graph_name.split('_')
        num_nodes = int(num_nodes)
        graph, num_nodes, num_edges = generate_graph(num_nodes=num_nodes, g_type=g_type)
    else:
        raise ValueError(f"graph_name {graph_name}")
    return graph, num_nodes, num_edges


def generate_graph(num_nodes: int, g_type: str):
    graph_types = ['erdos_renyi', 'powerlaw', 'barabasi_albert']
    assert g_type in graph_types

    if g_type == 'erdos_renyi':
        g = nx.erdos_renyi_graph(n=num_nodes, p=0.15)
    elif g_type == 'powerlaw':
        g = nx.powerlaw_cluster_graph(n=num_nodes, m=4, p=0.05)
    elif g_type == 'barabasi_albert':
        g = nx.barabasi_albert_graph(n=num_nodes, m=4)
    else:
        raise ValueError(f"g_type {g_type} should in {graph_types}")

    graph = []
    for node0, node1 in g.edges:
        distance = 1
        graph.append((node0, node1, distance))
    num_nodes = num_nodes
    num_edges = len(graph)
    return graph, num_nodes, num_edges


def save_graph_info_to_txt(txt_path, graph, num_nodes, num_edges):
    formatted_content = f"{num_nodes} {num_edges}\n"
    for node0, node1, distance in graph:
        row = [node0 + 1, node1 + 1, distance]  # node+1 is not elegant
        formatted_content += " ".join(str(item) for item in row) + "\n"
    with open(txt_path, "w") as file:
        file.write(formatted_content)


def run():
    graph_name = 'powerlaw_0032_ID042'
    txt_path = f"{graph_name}.txt"
    graph, num_nodes, num_edges = load_graph(graph_name=graph_name)
    save_graph_info_to_txt(txt_path=txt_path, graph=graph, num_nodes=num_nodes, num_edges=num_edges)


run()

下面是运行结果:

文件名是 powerlaw_0032_ID042.txt

32 112
1 5 1
1 6 1
1 7 1
1 8 1
1 10 1
1 12 1
1 13 1
1 14 1
1 19 1
1 21 1
1 22 1
1 24 1
1 28 1
2 5 1
2 7 1
2 13 1
2 29 1
3 5 1
3 6 1
3 7 1
3 8 1
3 9 1
3 10 1
3 11 1
3 12 1
3 18 1
3 26 1
4 5 1
4 6 1
4 8 1
4 9 1
4 11 1
4 14 1
4 24 1
4 27 1
4 28 1
5 6 1
5 7 1
5 8 1
5 10 1
5 13 1
5 15 1
5 18 1
5 19 1
5 21 1
5 30 1
6 11 1
6 12 1
6 16 1
6 17 1
6 18 1
6 19 1
6 20 1
6 25 1
6 27 1
6 28 1
6 29 1
6 30 1
6 32 1
7 9 1
7 11 1
7 14 1
7 15 1
7 19 1
7 21 1
7 22 1
7 23 1
7 24 1
7 26 1
7 29 1
7 32 1
8 9 1
8 16 1
8 17 1
8 23 1
8 25 1
8 31 1
9 10 1
9 12 1
9 14 1
9 15 1
9 22 1
9 23 1
9 30 1
10 17 1
10 27 1
11 13 1
11 16 1
11 20 1
11 24 1
11 25 1
11 29 1
12 26 1
13 15 1
13 17 1
13 21 1
14 16 1
15 32 1
16 18 1
16 20 1
18 28 1
19 20 1
19 31 1
20 22 1
20 30 1
21 23 1
21 25 1
22 31 1
23 26 1
25 32 1
26 27 1
27 31 1