DAG是过渡传递吗?


11

给出此挑战的目标是有限有向无环图(DAG),确定该图是否为传递式约简

关于什么是DAG和传递减少的简要说明:

DAG是具有定向边的图(即,您只能在该边上沿一个方向行进),这样,给定图上的任何起始节点,就不可能返回到起始节点(即,没有循环)。

在给定任何起始节点的情况下,如果可以通过任意正数的边沿移动到图中的另一个终止节点,则将该终止节点定义为可从起始节点到达。在一般的DAG中,可能存在从起始节点到目标结束节点的多条路径。例如,使用以下菱形图:

在此处输入图片说明

要进入节点DA,你可以采取的路径A->B->DA->C->D。因此,D可从到达A。但是,没有路径可以B从node到达节点C。因此,B无法从node到达节点C

将图的可达性定义为图中每个起始节点的可达节点列表。因此,对于同一示例菱形图,可达性为:

A: [B, C, D]
B: [D]
C: [D]
D: []

具有与上图相同的可达性的另一个图如下所示:

在此处输入图片说明

但是,第二个图比原始图具有更多的边。图的可传递约简是具有最少数量的边且原始图具有相同可达性的图。因此,第一个图是第二个图的传递减少。

对于有限的DAG,可传递折减可确保存在并且是唯一的。

输入值

输入是“列表列表”,其中外部列表​​具有顶点数量的长度,而每个内部列表是离开关联节点的边的数量的长度,并包含目标节点的索引。例如,描述上面第一张图的一种方法是(假设基于零的索引):

[[1, 2], [3], [3], []]

您可以在任何任意整数值(例如,基于0或1的索引)处开始第一个节点的索引。

输入可以来自所需的任何输入源(stdio,功能参数等)。只要没有给出其他信息,您就可以自由选择确切的输入格式。例如,如果要从stdio接收输入,则可以使每行都是关联节点的边的列表。例如:

1 2
3
3
'' (blank line)

每个邻接表中的索引不一定要排序,并且可能有多个边连接两个节点(例如:)[[1,1],[]]。您可以假设输入图的连接较弱,并且不包含任何循环(即,它是DAG)。

输出量

如果给定的输入DAG是传递折减,则输出为真,否则为假值。这可以是任何所需的接收器(stdio,返回值,输出参数等)

例子

所有示例均使用基于0的索引。

[[1,2],[3],[3],[]]
true

[[1,2,3],[3],[3],[]]
false

[[1,1],[]]
false

[[1,2,3,4],[5,6,7],[5,8,9],[6,8,10],[7,9,10],[11,12],[11,13],[12,13],[11,14],[12,14],[13,14],[],[],[],[]]
true

[[5,6,7],[2,3,0,4],[5,8,9],[6,8,10],[7,9,10],[11,12],[11,13],[12,13],[11,14],[12,14],[13,14],[],[],[],[]]
true

[[5,6,7],[2,3,0,4,14,5,7],[5,8,9],[6,8,10],[7,9,10],[11,12],[11,13],[12,13],[11,14],[12,14],[13,14],[],[],[],[]]
false

[[5,6,7],[2,3,0,4],[5,8,9],[6,8,10],[7,9,10,14],[11,12],[11,13],[12,13],[11,14],[12,14],[13,14],[],[],[],[]]
false

[[1,3],[2],[3],[]]
false

计分

这是代码高尔夫;以字节为单位的最小代码获胜。您的代码应在合理的时间内完成(无论您使用哪种硬件,最长不超过10分钟)。有标准漏洞。您可以使用所需的任何内置功能。


我们可以对输入的连通性做出任何假设吗?(我尚未检查您所有的测试用例,但它们涵盖了图中的多个断开连接的部分吗?)
Martin Ender's

更新了我认为正确的语言。
helloworld922

我想那很好。您也可以说图是弱连接的
马丁·恩德

Answers:


5

Ruby,101 97字节

一种简单的方法,可计算每个节点的可达范围,并考虑是否可以通过其他任何节点到达子节点。在循环图上看似失败,但是DAG的定义意味着它无论如何都不应该是循环的。

在线尝试!

->g{r=->i{i|i.map{|j|r[g[j]||[]]}.inject([],:|)}
g.all?{|e|e==e&e&&e.none?{|i|r[e-[i]].index i}}}

4

Mathematica,95 82字节

@MartinEnder节省了13个字节。

#~IsomorphicGraphQ~TransitiveReductionGraph@#&@Graph[x=0;##&@@Thread[++x->#]&/@#]&

匿名函数。将嵌套列表作为(基于1的)输入,并返回TrueFalse作为输出。此处的主要解决方案是46字节#~IsomorphicGraphQ~TransitiveReductionGraph@#&,用于测试给定图是否与它的传递减少同构。其余的将输入转换为Graph对象。


3

CJam(41字节)

q~:A_,{{Af=e__&}%_}*]:.|A.&A:$:e`e_2%1-*!

在线演示测试工具

解剖

q~:A      e# Parse input and store in A
_,{       e# Loop V times
  {       e#   Extend adjacency list representation of G^i to G^(i+1)
    Af=   e#   by extending each path by one edge
    e__&  e#   and flattening. NB :| would be shorter but breaks for empty lists
  }%
  _       e#   Duplicate, so that we build up G^2, G^3, ..., G^n
}*]       e# Gather in a single array
:.|       e# Fold pointwise union, giving the reachability from each vertex by
          e# paths of length > 1
A.&       e# Pointwise intersect with the paths of length 1
          e# We hope to get an array of empty arrays

          e# Handle the awkward special case of duplicate edges:
A:$       e# Sort each adjacency list
:e`       e# Run-length encode each adjacency list
e_2%      e# Extract only the run lengths
1-        e# Discard the 1s - so we now have an empty array unless there's a dupe

*         e# Join. We hope to be joining an array of empty arrays by an empty array
          e# giving an empty array
!         e# Check that we get a falsy value (i.e. the empty array)

3

果冻,20个字节

ị³$ÐĿ€ị@Fœ&¥";œ-Q$€E

使用基于1的索引。在线尝试!

松散概述

     €                for each vertex,
ị³$ÐĿ                   compute its reach.
        Fœ&¥"         intersect each vertex's lists of children and
      ị@                children's reaches.
             ;        then concatenate the list of intersections with
              œ-Q$€     all duplicate edges in the original graph.
                   E  are all elements equal? checks that all are empty lists,
                        meaning empty intersections and no duplicates.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.