python networkx使整数节点成为唯一的

时间:2013-12-30 21:32:18

标签: python unique nodes networkx

我正在尝试使用Project Euler Problem 18,它在数字三角形中从上到下找到可能的最大值,并且您只能通过下面一行中的相邻数字。要做到这一点,我在网络中制作一个有向图,然后我将对它进行拓扑排序并做一个最大的路径算法。 我遇到的问题是一些整数在数字三角形中重复,因此计算机认为它们之间存在边缘。 这是我放入.txt文件的数字三角形。

75
95 64
17 47 82
18 35 87 10
20 04 82 47 65
19 01 23 75 03 34
88 02 77 73 07 63 67
99 65 04 28 06 16 70 92
41 41 26 56 83 40 80 70 33
41 48 72 33 47 32 37 16 94 29
53 71 44 65 25 43 91 52 97 51 14
70 11 33 28 77 73 17 78 39 68 17 57
91 71 52 38 17 14 91 43 58 50 27 29 48
63 66 04 68 89 53 67 30 73 16 69 87 40 31
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23

这是我制作的代码。

import networkx as nx

digraph = nx.DiGraph()

def convert_to_list(string):
    """
    Converts a string with newlines to a list of lists,
    where each list is delimited by the newlines
    and the \n is removed.
    """

    split_string = string.split('\n')
    outer_list = [[] for x in xrange(0,len(split_string))]

    for i in range (len(split_string)):
        line = split_string[i].split(' ')
        for number in line:
            outer_list[i].append(int(number))
    return outer_list

def extract_data(file_name="paths1.txt"):
    """
    Takes a file that contains a triangle of numbers
    and constructs a set of nodes and edges that satisfies
    the constraints of the Maximum path sum I and II
    on Project Euler
    """
    text_file = open(file_name, 'r')
    contents = text_file.read()
    #data_list is a list of lists, where each list is a row
    #in the triangle
    data_list = convert_to_list(contents)

    #Add all the nodes to the graph
    for row in data_list:
        for item in row:
            digraph.add_node(item)

    #Add all the edges to the graph
    for row_number in range(0, len(data_list)-1):
        for item_number in range(len(data_list[row_number])):
            digraph.add_edge(data_list[row_number][item_number],data_list[row_number+1][item_number])
            digraph.add_edge(data_list[row_number][item_number],data_list[row_number+1][item_number+1])
digraph_topo = nx.topological_sort(digraph)
extract_data()

我的问题再次提出:如何让这些int节点独一无二,这样计算机可以分辨第0行75和第5行75之间的区别? 谢谢你的回复。

2 个答案:

答案 0 :(得分:1)

与传递每个项目相反,我建议传入某种类型项目的枚举列表。以下是我使用您提供的数据的方法:

In [4]: df = pd.read_csv('triangle.csv', header=None)

In [5]: df
Out[5]: 
    0   1   2   3   4   5   6   7   8   9   10  11  12  13  14
0   75 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1   95  64 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2   17  47  82 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3   18  35  87  10 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4   20   4  82  47  65 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5   19   1  23  75   3  34 NaN NaN NaN NaN NaN NaN NaN NaN NaN
6   88   2  77  73   7  63  67 NaN NaN NaN NaN NaN NaN NaN NaN
7   99  65   4  28   6  16  70  92 NaN NaN NaN NaN NaN NaN NaN
8   41  41  26  56  83  40  80  70  33 NaN NaN NaN NaN NaN NaN
9   41  48  72  33  47  32  37  16  94  29 NaN NaN NaN NaN NaN
10  53  71  44  65  25  43  91  52  97  51  14 NaN NaN NaN NaN
11  70  11  33  28  77  73  17  78  39  68  17  57 NaN NaN NaN
12  91  71  52  38  17  14  91  43  58  50  27  29  48 NaN NaN
13  63  66   4  68  89  53  67  30  73  16  69  87  40  31 NaN
14   4  62  98  27  23   9  70  98  73  93  38  53  60   4  23

In [24]: for row in df.iterrows():
   ....:     for item in row[1]:
   ....:         if np.isnan(item) == False:
   ....:             l.append((n, item))
   ....:             n += 1


In [26]: import networkx as nx

In [27]: G = nx.Graph()

In [28]: G.add_nodes_from(l)

In [29]: G.nodes()
Out[29]: 
[(113, 73.0),
 (74, 39.0),
 (64, 51.0),
 (111, 70.0),
 (72, 17.0),
 (69, 28.0),
 (102, 87.0),
 (46, 48.0),
 (118, 4.0),
 (105, 4.0),
 (92, 66.0),
 (55, 53.0),
 (19, 3.0),
 (17, 23.0),
 (90, 48.0),
 (18, 75.0),
 (27, 67.0),
 (37, 41.0),
 (8, 87.0),
 (59, 25.0),
 (43, 70.0), etc......

我希望这有帮助!

答案 1 :(得分:0)

关于如何使节点唯一的问题:节点的名称不需要作为值。 Networkx允许很多东西作为节点(任何可以清除的东西)。因此,您可以定义一个类,每个节点都是该类的元素,node.value()给出实际的数值。

在这种情况下,一个不错的选择是注意每个都在行i和列j中,值为v。所以你可以添加节点为G.add_node((i,j))然后有一个单独的dict val [(i,j)]为节点的实际值。