如何用NetworkX生成指定输入输出节点数的自定义连通有向图?
解决方案:自定义生成符合要求的有向图
你可以通过组合NetworkX现有工具加自定义逻辑来实现需求,以下是具体实现方案:
核心实现思路
先利用random_k_out_graph生成基础有向图,再手动调整节点的入度、出度来匹配指定的输入/输出节点数量,最后按需保证图的连通性。
代码实现
import networkx as nx import random def custom_directed_graph(n, k_input, k_output, k_out=2, connected=True): # 生成基础k-out有向图 G = nx.random_k_out_graph(n, k_out, self_loops=False) # 调整输入节点(入度为0)数量至k_input current_inputs = [node for node in G.nodes if G.in_degree(node) == 0] # 输入节点过多时,给部分节点添加入边 while len(current_inputs) > k_input: target_node = random.choice(current_inputs) source_node = random.choice([n for n in G.nodes if n != target_node]) G.add_edge(source_node, target_node) current_inputs.remove(target_node) # 输入节点不足时,移除部分节点的所有入边 while len(current_inputs) < k_input: target_node = random.choice([node for node in G.nodes if G.in_degree(node) > 0]) for source in list(G.predecessors(target_node)): G.remove_edge(source, target_node) current_inputs.append(target_node) # 调整输出节点(出度为0)数量至k_output current_outputs = [node for node in G.nodes if G.out_degree(node) == 0] # 输出节点过多时,给部分节点添加出边 while len(current_outputs) > k_output: source_node = random.choice(current_outputs) target_node = random.choice([n for n in G.nodes if n != source_node]) G.add_edge(source_node, target_node) current_outputs.remove(source_node) # 输出节点不足时,移除部分节点的所有出边 while len(current_outputs) < k_output: source_node = random.choice([node for node in G.nodes if G.out_degree(node) > 0]) for target in list(G.successors(source_node)): G.remove_edge(source_node, target) current_outputs.append(source_node) # 保证图的弱连通性(按需启用) if connected: components = list(nx.weakly_connected_components(G)) while len(components) > 1: comp1, comp2 = components[0], components[1] node1 = random.choice(list(comp1)) node2 = random.choice(list(comp2)) # 优先保留输入/输出节点的属性 if node1 in current_inputs and node2 not in current_outputs: G.add_edge(node1, node2) elif node2 in current_inputs and node1 not in current_outputs: G.add_edge(node2, node1) else: G.add_edge(node1, node2) components = list(nx.weakly_connected_components(G)) return G
验证与使用示例
# 生成10个节点、2个输入节点、3个输出节点的连通有向图 G = custom_directed_graph(n=10, k_input=2, k_output=3, connected=True) # 检查输入节点数量 input_nodes = [n for n in G.nodes if G.in_degree(n) == 0] print(f"实际输入节点数: {len(input_nodes)} | 预期: 2") # 检查输出节点数量 output_nodes = [n for n in G.nodes if G.out_degree(n) == 0] print(f"实际输出节点数: {len(output_nodes)} | 预期: 3") # 检查连通性 print(f"是否弱连通: {nx.is_weakly_connected(G)} | 预期: True")
关键参数说明
k_out:控制基础图中每个节点的平均出边数,值越大图的密度越高connected:布尔值,控制是否保证图的弱连通性;若需要强连通,可替换为nx.strongly_connected_components并调整边的添加逻辑- 调整输入/输出节点时,优先保留已有的输入/输出节点属性,避免反复修改导致的逻辑混乱
内容的提问来源于stack exchange,提问作者user3389288
相关产品推荐
相关产品推荐

