获取两个节点之间的节点子图?

时间:2015-09-11 19:48:19

标签: python graph networkx

我有这张图:

%matplotlib inline 
import networkx as nx

G = nx.Graph()

G.add_edge(1, 2)
G.add_edge(2, 3)
G.add_edge(3, 4)
G.add_edge(3, 5)
G.add_edge(4, 6)
G.add_edge(5, 6)
G.add_edge(3, 7)
G.add_edge(7, 6)
G.add_edge(6, 8)
G.add_edge(8, 9)

nx.draw(G, pos=nx.spring_layout(G), with_labels=True)

enter image description here

是否可以在不使用nx.subgraph(G, [3,4,5,6,7])的情况下获取节点3和6之间的子图。我的意思是,如果我知道有这个子图怎么办,但我不知道,例如关于5?

3 个答案:

答案 0 :(得分:1)

我的回答与back2basics非常相似,但更直接地找到了两者之间的节点。如果存在从sourcetarget的路径,nx.all_simple_paths(G, source=source, target=target)将找到该路径,该路径将返回路径的生成器。

import networkx as nx

G = nx.Graph()
G.add_edges_from([(1, 2), (2, 3), (3, 4), (3, 5), (4, 6), (5, 6), (3, 7), (7, 6), (6, 8), (8, 9)])

paths_between_generator = nx.all_simple_paths(G,source=3,target=6)
nodes_between_set = {node for path in paths_between_generator for node in path}
SG = G.subgraph(nodes_between_set)

nodes_between_set = ...使用“set generator”。它相当于

nodes_between_set = set()
for path in paths_beween_generator:
    for node in path:
        nodes_between_set.add(node)

答案 1 :(得分:0)

前三行帮助制作了制作子集所需的列表。

 var serviceBase = 'http://baseDomain/';
var plupload = null;
$scope.uploadedFiles = [];

$scope.fileUpload = {
    url: serviceBase + 'ImageUploadHandler.ashx',
    options: {
        multi_selection: true,
        drop_element: "pluploadDropzone",
        chunk_size: '200kb',
        runtimes: 'html5,flash,silverlight,html4',
        browse_button: "pluploadDropzone",
        container: "pluploadContainer",
        max_file_size: '3mb',
        mime_types: [{ title: 'Allowed', extensions: 'jpeg, jpg, png, gif' }]
    },
    callbacks:
    {
        filesAdded: function (uploader, files) {
            plupload = uploader;

            for (var i = 0 ; i < files.length ; i++) {
                var file = files[i];
                $scope.uploadedFiles.push(file);
                plupload.start();
            }
        }
    }
}

一个警告:子图点被定义为在从第3点到第6点的路径中

答案 2 :(得分:0)

这是基于

的原则
  1. 新子图中的任何节点都可以从源或目的地访问,并且
  2. 根据定义,路径上的任何节点都至少有一个前任和一个后继(对于有向图)或两个邻居(对于无向图)。
  3. 所以,首先我们找到我们可以达到的节点子图,然后递归删除没有至少一个前任和一个后继的节点,直到只有现有的子图。

    import networkx as nx
    def subgraph_from_connections(G, source, target, directed = None):
        included_nodes = [x for x in G.node if nx.has_path(G, source, x) and nx.has_path(G, x, target)]
        G2 = G.subgraph(included_nodes)
        # If this is a undirected graph, we only need to know if it only has 1 neighbor
        # If this is a directed graph, then it needs at least 1 predecessor and at least 1 successor
        if directed == True or (directed is None and type(G) == nx.classes.digraph.DiGraph):
            removals = [x for x in G2.node if len(G2.predecessors(x)) == 0 or len(G2.successors(x)) == 0]
            while len(removals) > 0:
                G2.remove_nodes_from(removals)
                removals = [x for x in G.node if len(G2.predecessors(x)) == 0 or len(G2.successors(x)) == 0]
        else:
            removals = [x for x in G2.node if len(G2.neighbors(x)) < 2]
            while len(removals) > 0:
                G2.remove_nodes_from(removals)
                removals = [x for x in G2.node if len(G2.neighbors(x)) < 2]
        return G2
    

    没有经过广泛测试,但它适用于此处列出的少数案例,并且包含10/11,当时这些案件都包含在Joel的测试中。该算法足够快 - 从之前的1000/10节点随机测试130毫秒(也许我不应该删除它)。