我有一个编号的Stream细分列表。每个人都列出了下一个下游流段。最后一个流段当然没有引用下游段。
我需要订购整条河流,从最顶端的河流开始,向下流动。在交叉点,我需要跳到下一个分支的顶部,向下工作到交汇点,然后继续到下一个分支。在交叉点可能有多个分支(任意数字)。
例如:Sub5流向Sub 12 SubSINK是LAst流段。 UNSORTED:
#####START_TOPOLOGY_BLOCK##########|###########|###########|###########|
Sub5,2454692.294,2603426.954,2456317.294,2596676.954,Sub12
Sub7,2453067.294,2598176.954,2453317.294,2596676.954,Sub12
Sub11,2462692.294,2607676.954,2461067.294,2605176.954,Sub12
Sub13,2449817.294,2601426.954,2450317.294,2593176.954,SubSINK
Sub2,2464567.294,2596801.954,2467317.294,2585676.954,Sub12
Sub12,2469942.294,2601051.954,2470817.294,2593676.954,Sub13
Sub1,2436567.294,2599676.954,2433067.294,2594676.954,Sub2
Sub3,2481067.294,2601301.954,2483067.294,2594676.954,Sub5
Sub4,2455817.294,2588801.954,2458317.294,2576426.954,Sub5
Sub6,2445067.294,2592926.954,2452817.294,2585176.954,Sub7
Sub8,2457942.294,2593551.954,2461067.294,2587426.954,Sub11
Sub9,2471442.294,2592676.954,2467817.294,2585676.954,Sub11
Sub10,2435692.294,2595176.954,2436567.294,2591176.954,Sub11
排序方法:
#####START_TOPOLOGY_BLOCK##########|###########|###########|###########|
Sub6,2445067.294,2592926.954,2452817.294,2585176.954,Sub7
Sub7,2453067.294,2598176.954,2453317.294,2596676.954,Sub12
Sub9,2471442.294,2592676.954,2467817.294,2585676.954,Sub11
Sub10,2435692.294,2595176.954,2436567.294,2591176.954,Sub11
Sub8,2457942.294,2593551.954,2461067.294,2587426.954,Sub11
Sub11,2462692.294,2607676.954,2461067.294,2605176.954,Sub12
Sub1,2436567.294,2599676.954,2433067.294,2594676.954,Sub2
Sub2,2464567.294,2596801.954,2467317.294,2585676.954,Sub12
Sub4,2455817.294,2588801.954,2458317.294,2576426.954,Sub5
Sub3,2481067.294,2601301.954,2483067.294,2594676.954,Sub5
Sub5,2454692.294,2603426.954,2456317.294,2596676.954,Sub12
Sub12,2469942.294,2601051.954,2470817.294,2593676.954,Sub13
Sub13,2449817.294,2601426.954,2450317.294,2593176.954,SubSINK
我怎样才能有效地做到这一点? 谢谢
关心鲁迪
河流拓扑的第二个例子
START_TOPOLOGY_BLOCK ########## | ########### | ########### | ########### |Sub16,2454692.294,2603426.954,2456317.294,2596676.954,Sub17 Sub7,2453067.294,2598176.954,2453317.294,2596676.954,SUB9 Sub8,2462692.294,2607676.954,2461067.294,2605176.954,SUB9 Sub4,2449817.294,2601426.954,2450317.294,2593176.954,SUB5 Sub1,2464567.294,2596801.954,2467317.294,2585676.954,分公司2 Sub14,2469942.294,2601051.954,2470817.294,2593676.954,SUB15 Sub19,2436567.294,2599676.954,2433067.294,2594676.954,SUB20 Sub13,2481067.294,2601301.954,2483067.294,2594676.954,SUB20 Sub10,2455817.294,2588801.954,2458317.294,2576426.954,SUB11 Sub6,2445067.294,2592926.954,2452817.294,2585176.954,SUB11 Sub17,2457942.294,2593551.954,2461067.294,2587426.954,Sub18 Sub15,2471442.294,2592676.954,2467817.294,2585676.954,Sub18 Sub9,2435692.294,2595176.954,2436567.294,2591176.954,SUB10 Sub2,2475817.294,2597426.954,2474067.294,2594176.954,Sub3中 Sub18,2481442.294,2593801.954,2482567.294,2587926.954,Sub19 Sub12,2484817.294,2588051.954,2483817.294,2584676.954,Sub13 Sub21,2478067.294,2592801.954,2481317.294,2587676.954,SubSINK Sub5,2437942.294,2589801.954,2437067.294,2587176.954,Sub6划 Sub3,2439442.294,2589801.954,2439317.294,2589676.954,SUB5 Sub20,2435067.294,2583801.954,2441067.294,2574426.954,Sub21 Sub11,2476317.294,2590801.954,2476067.294,2590426.954,SUB12 Sub32,2473067.294,2587301.954,2468317.294,2583426.954,SUB31 Sub33,2469817.294,2557926.954,2461317.294,2549426.954,SUB31 Sub33,2475942.294,2590551.954,2475817.294,2590426.954,SUB31 Sub34,2477692.294,2582426.954,2474567.294,2573926.954,Sub26
答案 0 :(得分:1)
您需要将细分代表作为图形数据结构。然后,熟悉的图形算法,如DFS,BFS和拓扑排序,应该为您完成工作,具体取决于您的需求。
如果您可以通过一个简单的示例或图片来澄清您的问题,以便清楚地了解您需要的排序顺序,我可以提供更具体的方向。
答案 1 :(得分:1)
以下几行中的简单内容有望展示如何创建适当的河图以及遍历它的所有方法。
class Point:
def __init__(self, x, y): self.xy= float(x), float(y)
def _insert(G, n, x, y, kind= 0):
if n[kind] not in G: G[n[kind]]= [[], [], Point(x, y)]
G[n[kind]][kind].append(n[not kind])
class River:
def __init__(self, S= None):
self.G= {}
if S is not None:
for s in S: self.insert(s)
def insert(self, s):
n= s[0], s[5]
_insert(self.G, n, s[1], s[2])
_insert(self.G, n, s[3], s[4], 1)
def degree(self, n, kind= 1): return len(self.G[n][kind])
def sink(self):
for n in self.G:
if not self.G[n][0]: return n
def traverse(self, n0, fun, level= 0):
for n1 in self.G[n0][1]:
self.traverse(n1, fun, level+ 1)
fun(n0, n1, level)
并进行测试
if __name__ == '__main__':
import csv
reader= csv.reader(open('river.dat', 'r'))
reader.next()
r= River([s for s in reader])
def fun(n0, n1, level):
"""segment (n1, n0) has:
level, indicating a 'hop' distance from the sink
degree(n1, 1), in degree to segment (0 indicates a source)
n1, id of segments start
n0, id of segments end
degree(n0, 0), out degree from segment (0 indicates a sink)
"""
print '{}:({}:{} -> {}:{})'.format(
level, r.degree(n1), n1, n0, r.degree(n0, 0))
r.traverse(r.sink(), fun)
将打印:
3:(0:Sub3 -> Sub5:1)
3:(0:Sub4 -> Sub5:1)
2:(2:Sub5 -> Sub12:1)
3:(0:Sub6 -> Sub7:1)
2:(1:Sub7 -> Sub12:1)
3:(0:Sub8 -> Sub11:1)
3:(0:Sub9 -> Sub11:1)
3:(0:Sub10 -> Sub11:1)
2:(3:Sub11 -> Sub12:1)
3:(0:Sub1 -> Sub2:1)
2:(1:Sub2 -> Sub12:1)
1:(4:Sub12 -> Sub13:1)
0:(1:Sub13 -> SubSINK:0)
修改:使用您的第二个示例。首先请注意,您有超过1个接收器。如果这是故意的,那么处理森林也应该非常简单(比如让sink返回所有这些,然后在循环中处理遍历)。但无论如何,前22行的输出是:
5:(0:Sub16 -> Sub17:1)
4:(1:Sub17 -> Sub18:1)
5:(0:Sub14 -> Sub15:1)
4:(1:Sub15 -> Sub18:1)
3:(2:Sub18 -> Sub19:1)
2:(1:Sub19 -> Sub20:1)
7:(0:Sub7 -> Sub9:1)
7:(0:Sub8 -> Sub9:1)
6:(2:Sub9 -> Sub10:1)
5:(1:Sub10 -> Sub11:1)
7:(0:Sub4 -> Sub5:1)
9:(0:Sub1 -> Sub2:1)
8:(1:Sub2 -> Sub3:1)
7:(1:Sub3 -> Sub5:1)
6:(2:Sub5 -> Sub6:1)
5:(1:Sub6 -> Sub11:1)
4:(2:Sub11 -> Sub12:1)
3:(1:Sub12 -> Sub13:1)
2:(1:Sub13 -> Sub20:1)
1:(2:Sub20 -> Sub21:1)
0:(1:Sub21 -> SubSINK:0)
编辑2 :我的答案更多的是提供一些如何处理河树本身的想法。对于您的特定应用,您最有可能找到更好的方法来实际处理这些点。但无论如何你现在可以访问它们,如:
In []: r.G['Sub8'][2].xy
Out[]: (2462692.294, 2607676.954)
In []: r.G['Sub8'][2].xy[0]
Out[]: 2462692.294
您也可以完全忽略class Point
并修改_insert
,如:
def _insert(G, n, x, y, kind= 0):
# if n[kind] not in G: G[n[kind]]= [[], [], Point(x, y)]
if n[kind] not in G: G[n[kind]]= [[], [], (x, y)]
G[n[kind]][kind].append(n[not kind])
然后您将访问以下几点:
In []: r.G['Sub8'][2]
Out[]: ('2462692.294', '2607676.954')
In []: r.G['Sub8'][2][0]
Out[]: '2462692.294'