Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 在树结构中合并分支的模式或算法?_Algorithm_Design Patterns - Fatal编程技术网

Algorithm 在树结构中合并分支的模式或算法?

Algorithm 在树结构中合并分支的模式或算法?,algorithm,design-patterns,Algorithm,Design Patterns,我正在尝试将一个DAG(有向无环图)映射到下面显示的结构中 这是我从DAG开始的一个例子 其中圆弧总是从左向右 然后,我将该图还原,并将其扩展为一棵树,其中包含重复的节点,如下所示: <root> <seq> <mod1/> <flow> <seq> <mod4/> <mod7/>

我正在尝试将一个DAG(有向无环图)映射到下面显示的结构中

这是我从DAG开始的一个例子

其中圆弧总是从左向右

然后,我将该图还原,并将其扩展为一棵树,其中包含重复的节点,如下所示:

<root>
    <seq>
        <mod1/>
        <flow>
            <seq>
                <mod4/>
                <mod7/>
            </seq>
            <seq>
                <flow>
                    <seq>
                        <flow>
                            <mod4/>
                            <mod3/>
                        </flow>
                        <mod6/>
                    </seq>
                    <seq>
                        <flow>
                            <mod4/>
                            <mod3/>
                            <mod2/>
                        </flow>
                        <mod5/>
                    </seq>
                </flow>
                <mod8/>
            </seq>
        </flow>
    </seq>
</root>

我正在寻找的是一些算法或模式,以实现以下合并结构。(注意,它再次被还原)

目标是生成如下所示的XML:

<root>
    <seq>
        <mod1/>
        <flow>
            <seq>
                <mod4/>
                <mod7/>
            </seq>
            <seq>
                <flow>
                    <seq>
                        <flow>
                            <mod4/>
                            <mod3/>
                        </flow>
                        <mod6/>
                    </seq>
                    <seq>
                        <flow>
                            <mod4/>
                            <mod3/>
                            <mod2/>
                        </flow>
                        <mod5/>
                    </seq>
                </flow>
                <mod8/>
            </seq>
        </flow>
    </seq>
</root>

我不认为这有什么关系,但我正在解析JSON,用Java7编写XML。 框是web服务,箭头表示输入和输出参数,因此,例如,一旦模块1、2、3和4完成,模块5就会被调用,它们的输出就是它的输入

编辑:好的,下面是另一个有十个节点的示例。我希望这能让您更好地理解何时需要合并I节点


为了回答@blubb,在这个例子中,我们可以看到“服务”8和9是如何被合并的。否则,他们需要工作的所有服务(1、2、3、4、5和6)都将被呼叫两次而不需要。最后一个草图中的中间分支将执行两次:一次用于8,一次用于9。

我对树数据结构不太了解,我认为树数据结构可能是结果的良好载体,我对转换为XML的知识也不太了解,但是如果给我数据并绘制了路径,例如

1 4 7
1 2 5 8
1 3 5 8
1 4 5 8
1 3 6 8
1 2 5 9
1 3 5 9
1 4 5 9
1 3 6 9
1 2 10
1 2 5 10
1 3 5 10
1 4 5 10
然后,合并节点的一种方法可以是:

Take increasingly larger chunks from the end of each line and examine the
first cell to the left of them. Nodes are merged if matching right-side 
chunks flow to the same aggregated first cells on the left. Remove duplicate 
paths.

解释/示例:

1 4 7
1 2 5 (8,9) -- merged
1 3 5 (8,9)
1 4 5 (8,9)
1 3 6 (8,9)
1 2 5 (8,9)
1 3 5 (8,9)
1 4 5 (8,9)
1 3 6 (8,9)
1 2 10
1 2 5 10
1 3 5 10
1 4 5 10
1 4 7
1 (2,3,4) 5 (8,9)
1 3 6 (8,9)
1 2 10
1 (2,3,4) 5 10

第一次通过(取结束单元格,与左侧聚集的第一个单元格进行比较):


第二遍(取末端单元格+1个单元格,与左侧聚集的第一个单元格进行比较):


看起来很像我要求的结果。(两端的重复单元可以合并为单个节点,即左侧1个,右侧(8,9)和10个,如eskalera的最终草图所示。)

最后,我找到了一种算法来完成这项工作。这是给所有试图帮助我的人的:

首先,我从草图1中的DAG构建了一个反向生成树。因此,我从模块7和8开始,向后构建树,并在其中复制模块

之后,我创建了名为FLOW和SEQUENCE的虚拟节点,并在树中引入它们,以便每个模块节点都是SEQUENCE节点的子节点。跨越分支是序列节点,是流节点的子节点。我认为这一步足够直观,但重要的是要理解我们需要虚拟节点,以便我们可以关闭流节点,这些节点从一个节点分裂到多个节点

之后,我首先遍历树的深度,对于每个模块(我们称之为驱动程序),我将其子模块与驱动程序的兄弟姐妹的子模块进行比较。如果它们不匹配,我会继续与驱动程序的兄弟姐妹的孙辈一起往下走,因此,来自驱动程序兄弟姐妹的所有分支都必须通过与驱动程序相同的节点。从图形上看,这意味着在某些点上,两个节点需要完全相同的模块

如果它们匹配,我将从重合节点向下清除合并分支,这意味着我将它们从父节点上断开。从那里开始,它与驱动程序序列节点一起进入一个新的序列节点,进入同一个流节点

在浏览完整棵树之后,只要进行了合并,我们就会再次浏览这棵树,这一次我们的关系会更密切。这意味着我们不是比较司机的孩子,而是比较司机的好孩子

最后一步显然是再次还原树


由于这些虚拟节点的编程所隐含的复杂性,我将一些概念放在一边。主要原因是,一旦引入虚拟节点,所有父子兄弟关系都将丢失。但我希望大家已经理解了大意。

你能把最后一段再延长一点吗?我认为这将有助于更清楚地理解这个问题。第二张和第三张图片-它们看起来就像你只是将所有1节点“合并”为一个1节点,对吗?另外:你能解释一下为什么你同时“合并”2,3,4的三个1节点,而不是3和4的两个1节点吗?谢谢大家的回答。我已经编辑了我的问题。在你的最后一个例子中,我不明白为什么你有2,3,4和4,3,2,而不仅仅是其中一个。看起来你可以使用其中一个,然后在5之后进行分支,一个分支合并6(合并8,9),另一个分支合并10。你为什么不合并2,3,4?我的意思是,你的算法是基于这样一个事实:当两个节点有相等的子节点时,两个节点合并,这是不正确的。每当所有子代都有这些子代时,它们就会合并,这意味着没有一个子分支不通过“瓶颈”(最好在第一张草图上看到)@eskalera更仔细地阅读算法--
2,3,4@eskalera与
1相同,因此右侧块必须完全匹配,但最左侧的新单元格除外?
  N/A    <- 1 4 7
  1      <- 2 5 (8,9)
  1      <- 3 5 (8,9)
  1      <- 4 5 (8,9)
  1      <- 3 6 (8,9)
  N/A    <- 1 2 10
  1      <- 2 5 10
  1      <- 3 5 10
  1      <- 4 5 10
1 4 7
1 (2,3,4) 5 (8,9)
1 3 6 (8,9)
1 2 10
1 (2,3,4) 5 10