多河流分支结构的排序

2024-06-11 22:29:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个编号的流段列表。每一个都列出了下一个下游段。当然,最后一个流段没有引用下游段。你知道吗

我要订整条河,从最上面的小溪开始,然后顺流而下。在交叉路口,我需要跳到下一个分支的顶部,顺流而下到交叉路口,然后继续到下一个分支。可能有多个分支(任意数量)连接在一个连接处。你知道吗

例如:Sub5流到sub12 子链接是最后一个流段。 未排序:

#####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

我怎样才能有效地做到这一点?? 谢谢

向鲁迪问好

河流拓扑的第二个示例

启动\u拓扑\u块##########|###########|###########|###########|

sub162454692.2942603426.9542456317.2942596676.954,Sub17 子项72453067.2942598176.9542453317.2942596676.954,子项9 Sub82462692.2942607676.9542461067.2942605176.954,Sub9 sub42449817.2942601426.9542450317.2942593176.954,Sub5 sub12464567.2942596801.9542467317.2942585676.954,Sub2 sub142469942.2942601051.9542470817.2942593676.954,Sub15 sub192436567.2942599676.9542433067.2942594676.954,Sub20 Sub132481067.2942601301.9542483067.2942594676.954,Sub20 sub102455817.2942588801.9542458317.2942576426.954,Sub11 sub62445067.2942592926.9542452817.2942585176.954,Sub11 sub172457942.2942593551.9542461067.2942587426.954,Sub18 sub152471442.2942592676.9542467817.2942585676.954,Sub18 sub92435692.2942595176.9542436567.2942591176.954,Sub10 sub22475817.2942597426.9542474067.2942594176.954,Sub3 sub182481442.2942593801.9542482567.2942587926.954,Sub19 sub122484817.2942588051.9542483817.2942584676.954,Sub13 Sub212478067.2942592801.9542481317.2942587676.954,子银行 Sub52437942.2942589801.9542437067.2942587176.954,Sub6 sub32439442.2942589801.9542439317.2942589676.954,Sub5 Sub202435067.2942583801.9542441067.2942574426.954,Sub21 sub112476317.2942590801.9542476067.2942590426.954,Sub12 sub322473067.2942587301.9542468317.2942583426.954,Sub31 sub332469817.2942557926.9542461317.2942549426.954,Sub31 sub332475942.2942590551.9542475817.2942590426.954,Sub31 sub342477692.2942582426.9542474567.2942573926.954,Sub26


Tags: 排序分支sub2sub3sub11sub13sub12sub6
2条回答

下面简单介绍一下如何创建正确的河流图以及遍历河流图所需的所有方法。你知道吗

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)

编辑:使用第二个示例。首先请注意,您有多个水槽。如果这是有意的,那么处理林也应该非常简单(比如让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'

您需要将段表示为图形数据结构。然后,熟悉的图算法,如DFS、BFS和拓扑排序,应该为您完成这项工作,具体取决于您需要什么。你知道吗

如果你能用一个简单的例子或图片来澄清你的问题,以便清楚地了解你需要的排序顺序,我也许能提供一个更具体的方向。你知道吗

相关问题 更多 >