我正在尝试使用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之间的区别? 谢谢你的回复。
答案 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)]为节点的实际值。