UNPKG

4.5 kBPlain TextView Raw
1// tslint:disable no-increment-decrement
2/**
3 * TypeScript program to print all topological sorts of a graph
4 * Original C++ source code from http://www.geeksforgeeks.org/all-topological-sorts-of-a-directed-acyclic-graph/
5 */
6export class DirectedAcyclicGraph {
7 private numVertices: number; // No. of vertices
8
9 constructor(numVertices: number) {
10 this.numVertices = numVertices;
11
12 // Initialising all indegree with 0
13 for (let curr: number = 0; curr < numVertices; curr = curr + 1) {
14 this.inDegree.push(0);
15 this.adj.push([]);
16 }
17 }
18
19 // Pointer to an array containing adjacency list
20 private adj: number[][] = [];
21
22 // Vector to store indegree of vertices
23 private inDegree: number[] = [];
24
25 // The function does all Topological Sort.
26 // It uses recursive alltopologicalSortUtil()
27 public alltopologicalSort(): number[][] {
28 const { numVertices } = this;
29 // Mark all the vertices as not visited
30 const visited: boolean[] = [];
31 for (let curr: number = 0; curr < numVertices; curr = curr + 1) {
32 visited.push(false);
33 }
34 const res: number[] = [];
35 return this.alltopologicalSortUtil(res, visited);
36 }
37
38 // A function used by alltopologicalSort
39 // Prints all Topological Sorts
40 // Main recursive function to print all possible
41 // topological sorts
42 private alltopologicalSortUtil(res: number[], visited: boolean[]): number[][] {
43 // console.log('topSort', res, visited); // tslint:disable-line no-console
44 const { numVertices, inDegree, adj } = this;
45 // To indicate whether all topological are found
46 // or not
47 let flag: boolean = false;
48 const allSorts: number[][] = [];
49 const floor: number = inDegree.reduce((result, val, index) => {
50 // console.log('i', index, val, visited[index]); // tslint:disable-line no-console
51 if (visited[index] === false) {
52 return Math.min(result, val);
53 }
54 return result;
55 }, Infinity);
56 // console.log('floor', floor); // tslint:disable-line no-console
57
58 for (let vertex: number = 0; vertex < numVertices; vertex++) {
59 // If indegree is 0 and not yet visited then
60 // only choose that vertex
61 // console.log('i', i, inDegree[i], visited[i]); // tslint:disable-line no-console
62 if (inDegree[vertex] === floor && !visited[vertex]) {
63 // console.log('visit', i, inDegree[i], visited[i]); // tslint:disable-line no-console
64
65 // reducing indegree of adjacent vertices
66 let adjIndex: number;
67 for (adjIndex = 0; adjIndex < adj[vertex].length; adjIndex++) {
68 const jv = adj[vertex][adjIndex];
69 inDegree[jv]--;
70 }
71
72 // including in result
73 visited[vertex] = true;
74 allSorts.push(...this.alltopologicalSortUtil(res.concat(vertex), visited));
75
76 // resetting visited, res and indegree for
77 // backtracking
78 visited[vertex] = false;
79 for (adjIndex = 0; adjIndex < adj[vertex].length; adjIndex++) {
80 const jv = adj[vertex][adjIndex];
81 inDegree[jv]++;
82 }
83
84 flag = true;
85 }
86 }
87
88 // We reach here if all vertices are visited.
89 // So we print the solution here
90 if (!flag) {
91 // console.log('Finished', visited); // tslint:disable-line no-console
92 allSorts.push(res);
93 }
94 return allSorts;
95 }
96
97 // function to add an edge to graph
98 // Utility function to add edge
99 public addEdge(src: number, dest: number): void {
100 this.adj[src].push(dest); // Add w to v's list.
101 // increasing inner degree of w by 1
102 this.inDegree[dest]++;
103 }
104}
105
106/*
107// Driver program to test above functions
108function main(): number {
109 // Create a graph given in the above diagram
110 const g = new DirectedAcyclicGraph(6);
111 g.addEdge(5, 2);
112 g.addEdge(5, 0);
113 g.addEdge(4, 0);
114 g.addEdge(4, 1);
115 g.addEdge(2, 3);
116 g.addEdge(3, 1);
117
118 console.log('All Topological sorts\n'); // tslint:disable-line no-console
119
120 const allSorts = g.alltopologicalSort();
121 console.log(allSorts); // tslint:disable-line no-console
122
123 return 0;
124}
125
126main();
127*/