You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 17:08:29