给定一个DAG,其中每个节点都属于一个类别,如何将该图转换为一个包含每个类别列的表?转换不一定是可逆的,但应保留有关图结构的有用信息;并且应该是一种“自然的”转换,在这种意义上,看图和表的人不应该对任何行感到惊讶。它也应该是紧凑的,即几行。
例如,给出节点a1,b1,b2,c1的曲线图,其中边缘a1-> b1,a1-> b2,b1-> c1,b2-> c1(即菱形图)我希望看到下表:
a b c
--------
a1 b1 c1
a1 b2 c1
我已经对这个问题进行了相当多的考虑,但是我在提出一种能够在某些图表上提供直观结果的算法时遇到了麻烦。考虑具有边缘a1-> c1,b1-> c1的图a1,b1,c1。我想用算法来生成这个表:
a b c
--------
a1 b1 c1
但也许它应该产生这个:
a b c
--------
a1 c1
a1 b1
我正在寻找有关问题的创意和见解。如果您认为问题有所帮助,请随意改变以简化或约束问题。
头脑风暴!
编辑:
转换应始终生成相同的行集,尽管行的顺序无关紧要。
使用例如Excel进行排序和过滤时,表格应该很好。这意味着多个节点不能打包到表的单个单元中 - 每个单元只有一个节点。
答案 0 :(得分:2)
您需要的是topological sorting的变体。这是一种算法,可以对图形顶点进行“排序”,就好像a---->b
边缘意味着a > b
一样。由于图是一个DAG,因此没有周期,这个>
关系是可传递的,因此至少存在一个排序顺序。
对于您的菱形图,存在两个拓扑命令:
a1 b1 b2 c1
a1 b2 b1 c1
b1
和b2
项目没有关联,即使是间接关联,因此,它们可以按任何顺序排列。
对图表进行排序后,您就知道了一个近似的顺序。我的建议是以一种简单的方式填充表格(每行1个顶点),然后“压缩”表格。执行排序并选择您输出的序列。从上到下填充表格,将顶点分配给相关列:
a b c
--------
a1
b2
b1
c1
现在通过从上到下走动来压缩桌子(然后从下到上进行类似的传递)。在每次迭代中,您仔细查看“当前”行(标记为=>
)和“下一行”。
如果当前节点和下一节点中的节点不同,则不对此列执行任何操作:
from ----> to
X b c X b c
-------- --------
=> X1 . . X1 . .
X2 . . => X2 . .
如果在下一行的列X
中没有顶点(表格单元格为空),并且在当前行中有顶点X1
,那么有时您应该填充此空白当前行中具有顶点的单元格。但并非总是如此:你希望你的桌子合乎逻辑,不是吗?因此,当且仅当对于当前行中的所有顶点没有边b--->X1
,c--->X1
等时,才复制顶点。
from ---> to
X b c X b c
-------- --------
=> X1 b c X1 b c
b1 c1 => X1 b1 c1
(编辑:)在第一次(前进)和第二次(后退)过后,你将拥有这样的表格:
first second
a b c a b c
-------- --------
a1 a1 b2 c1
a1 b2 a1 b2 c1
a1 b1 a1 b1 c1
a1 b1 c1 a1 b1 c1
然后,只需删除相等的行即可:
a b c
--------
a1 b2 c1
a1 b1 c1
你应该得到一张漂亮的桌子。为O(n ^ 2)。
答案 1 :(得分:0)
如何在一个单元格中将所有可到达节点从一个节点压缩在一起?例如,您的第一个DAG应如下所示:
a b c
---------------
a1 [b1,b2]
b1 c1
b2 c1
答案 2 :(得分:0)
这听起来像火车系统地图,区域内有站点(a,b,c)。
您可以在一个方向上生成所有可能路线的表格。在这种情况下,“a1,b1,c1”似乎暗示a1-> b1所以如果你只有a1-> c1,b1-> c1
,请不要格式化您可以通过列出从a区开始的最长路线来决定制作表格, 仅使用每个边缘一次,以较短的剩余路径结束。或者只有在连接未使用的边或延伸路径时才允许重复使用边。
换句话说,进行深度优先搜索,尝试不重用边缘(拒绝任何不包含未使用边缘的路径,并可选择修剪端点处使用的边缘)。
答案 3 :(得分:0)
这是我最终做的事情:
压缩行的方法如下:
这提供了非常紧凑的输出,似乎满足我的所有要求。