拓扑总数


11

对于给定的DAG(有向无环图),其每个拓扑排序都是所有顶点的排列,其中,对于DAG 中的每个边(u,v),在排列中,u出现在v之前。

您的任务是计算给定DAG的拓扑种类总数。

规则

  • 您可以使用任何格式来表示图,例如邻接矩阵,邻接列表或边列表,只要您不对编码进行有用的计算。如果有用,您也可以在输入中包含诸如顶点数或顶点列表之类的东西。
  • 您可以假设输入中的图形始终是DAG(没有任何循环)。
  • 理论上,您的程序应该可以进行任何输入。但是,如果它溢出您语言中的基本整数类型,它可能会失败。
  • 顶点名称可以是任何类型的任何连续值。例如:以0或1开头的数字。(当然,仅当您不使用该数字存储代码时)。
  • 这是代码高尔夫球。最短的代码获胜。

这是相同的输入,但格式不同。您的程序不必全部接受。顶点始终是从0开始的整数。

Adjacency list:
[ [1 2 3 5] [2 4] [] [2] [] [3] ]
Adjacency matrix:
[ [0 1 1 1 0 1] [0 0 1 0 1 0] [0 0 0 0 0 0] [0 0 1 0 0 0] [0 0 0 0 0 0] [0 0 0 1 0 0] ]
Edge list:
6 [ [0 1] [0 2] [0 3] [0 5] [1 2] [1 4] [3 2] [5 3] ]

这是此图中显示的图形:

示例图

输出应为:

9

拓扑排序为:

[0 1 4 5 3 2]
[0 1 5 4 3 2]
[0 1 5 3 4 2]
[0 1 5 3 2 4]
[0 5 1 4 3 2]
[0 5 1 3 4 2]
[0 5 1 3 2 4]
[0 5 3 1 4 2]
[0 5 3 1 2 4]

功能?整个程序?可以吗
isaacg 2015年

@isaacg可以。
jimmy23013 2015年

Answers:


4

果酱-25

q~{_f{1$-_j@j@&!*}_!+:+}j

在user23013的大力帮助下:)

在线尝试

说明:

通用算法与xnor的Python解决方案相同
此处的关键是j运算符,该运算符会记录递归。它需要一个参数,一个或多个初始值的数组(如f(0),f(1)等)和一个块来定义递归。j再次在该块内部使用该运算符,以对同一块进行递归(和记忆化)调用。它也可以与多个参数一起使用,但此处并非如此。
user23013的一项伟大创新是将j与不同的数据类型一起使用,并将邻接表用作初始值的数组。

q~             read and evaluate the input (vertex list followed by adjacency list)
{…}j           run the block on the vertex list, doing memoized recursion
                and using the adjacency list for initial values
    _          copy the vertex list
    f{…}       for each vertex and the vertex list
        1$-    copy the vertex and remove it from the list
                Python: "V-{v}"
        _j     copy the reduced list and call the j block recursively
                this solves the problem for the reduced vertex list
                Python: "f(G,V-{v})"
        @j     bring the vertex to the top of the stack and call the j block recursively
                in this case, it's called with a vertex rather than a list
                and the memoized value is instantly found in the list of initial values
                effectively, this gets the list of vertices adjacent to the current vertex
                Python: "G[v]"
        @&     bring the reduced list to the top of the stack and intersect
        !*     multiply the number of topological sorts of the reduced vertex list
                with 1 if the intersection was empty and 0 if not
                Python: equivalent to "*(V-G[v]==V)"
               after this loop we get an array of sub-results for the reduced vertex lists
    _!+        add 1 or 0 to the array if the array was empty or not
                because we want to get 1 for the empty array
                Python: equivalent to "V<{0}or"
    :+         add the numbers in the array
                Python: "sum(…)"

1
编辑为在输入中明确允许顶点列表。现在25个字节
jimmy23013

@ user23013这是什么巫术?:o
aditsu退出,因为SE无效2015年

7

Python,58岁

f=lambda G,V:V<{0}or sum(f(G,V-{v})*(V-G[v]==V)for v in V)

输入由邻接字典G和顶点集组成V

G = {0:{1,2,3,5}, 1:{2,4}, 2:set(), 3:{2}, 4:set(), 5:{3}, 6:set()}
V = {0,1,2,3,4,5}

该代码是递归的。该集合V存储所有仍需要访问的节点。对于每一个潜在的下一个节点,我们通过看,如果没有剩余的顶点指向它,以检查它的适用性V-G[v]==V检查VG[v]不相交。对于所有合适的此类顶点,我们添加已删除拓扑的数量。作为基本情况,空集为1。


+1(表示不使用边列表)。
jimmy23013

5

Mathematica,80 57 51字节

Count[Permutations@#,l_/;l~Subsets~{2}~SubsetQ~#2]&

该定义的实现非常简单。我只是生成所有排列并计算其中有多少有效。为了检查排列是否有效,我获取了排列中的所有顶点对。方便地,Subsets[l,{2}]不仅给了我所有对,而且还维护了它们在其中的顺序l-正是我所需要的。

上面的函数需要顶点列表和边列表,例如

f[{1, 2, 3, 4, 5, 6}, {{1, 2}, {1, 3}, {1, 4}, {1, 6}, {2, 3}, {2, 5}, {4, 3}, {6, 4}}]

如果调用该函数f

我将尝试打高尔夫球,或者稍后再使用其他方法。


2

Pyth,27个字节

Mlf!sm}_dHfq2lYyTfqSZUZ^UGG

定义2输入功能g。第一个输入是顶点数,第二个是有向边列表。

去测试:

Code:
Mlf!sm}_dHfq2lYyTfqSZUZ^UGGghQeQ

Input:
6, [ [0, 1], [0, 2], [0, 3], [0, 5], [1, 2], [1, 4], [3, 2], [5, 3] ]

在这里尝试。


@ user23013在表达式中使用了计数器计数和列表^UGG,它将生成的所有G条目列表range(len(G))
isaacg 2015年

我的意思是,如果[0, 1, ...]直接在输入中使用它会更短吗?
jimmy23013

@ user23013不,它的长度是相同的:^GlGvs ^UGG
isaacg 2015年

2

Haskell,102 107 100 89 85字节

import Data.List
(%)=elemIndex
n#l=sum[1|p<-permutations[0..n],and[u%p<v%p|[u,v]<-l]]

输入是最高顶点编号(从0开始)和边列表,其中边是两个元素的列表。用法示例:5 # [[0,1], [0,2], [0,3], [0,5], [1,2], [1,4], [3,2], [5,3]]

工作原理:计算所有p边均[u,v]满足的顶点的所有排列:uin的p位置小于vin的位置p。那是定义的直接实现。

编辑:我的第一个版本返回的拓扑排序本身而不是多少。固定它。

编辑II:不适用于未连接顶点的图形。固定它。


我正在考虑添加一个仅包含顶点但不包含边缘的
测试用例

@ user23013:现在适用于未连接顶点的图形。它甚至变得更短。
nimi 2015年
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.