Hi everyone I was trying to solve this problem http://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=813 and I realized that it wants to get all the solutions of topological sorting problem, I know how to get only one possible solution and this is my code http://ideone.com/IiQxiu
static ArrayList<Integer> [] arr;
static int visited [];
static Stack<Integer> a = new Stack<Integer>();
static boolean flag=false;
public static void graphcheck(int node){ //method to check if there is a cycle in the graph
visited[node] = 2;
for(int i=0;i<arr[node].size();i++){
int u =arr[node].get(i);
if(visited[u]==0){
graphcheck(u);
}else if(visited[u]==2){
flag=true;
return;
}
}
visited[node] = 1;
}
public static void dfs2(int node){ //method to get one possible topological sort which I want to extend to get all posibilites
visited[node] = 1;
for(int i=0;i<arr[node].size();i++){
int u =arr[node].get(i);
if(visited[u]==0){
dfs2(u);
}
}
a.push(node);
}
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int tc = Integer.parseInt(br.readLine());
for(int k=0;k<tc;k++){
br.readLine();
String h[]= br.readLine().split(" ");
int n= h.length;
arr=new ArrayList[n];
visited = new int[n];
for( int i = 0; i < n; i++) {
arr[ i] = new ArrayList<Integer>();
}
String q[]=br.readLine().split(" ");
int y=q.length;
for(int i=0;i<y;i++){
int x=0;
int z=0;
for(int j=0;j<n;j++){
if(q[i].charAt(0)==h[j].charAt(0)){
x=j;
}else if(q[i].charAt(2)==h[j].charAt(0)){
z=j;
}
}
if(q[i].charAt(1)=='<'){
arr[x].add(z);
}
}
for(int i=0;i<n;i++){
if(visited[i]==0)
graphcheck(i);
}
if(flag){
System.out.println("NO");
}else{
a.clear();
Arrays.fill(visited, 0);
for(int i=0;i<n;i++){
if(visited[i]==0){
dfs2(i);
}
}
int z= a.size();
for(int i=0;i<z;i++){
int x =a.pop();
System.out.print(h[x]+" ");
}
System.out.println();
}
}
}
A potential way would be to modify the algorithm specified by Khan, (1962) , in which a topological sort is calculated using the following algorithm:
L ← Empty list that will contain the sorted elements
S ← Set of all nodes with no incoming edges
while S is non-empty do
remove a node n from S
insert n into L
for each node m with an edge e from n to m do
remove edge e from the graph
if m has no other incoming edges then
insert m into S
if graph has edges then
return error (graph has at least one cycle)
else
return L (a topologically sorted order)
This calculates one topological sort, in order to generate all possible sorts. To get all possible sorts, you could think of the result as a tree, where the root is the first node, and each child of a node is one of the next values. Given a graph:
1 -> 3 -> 8
| | |
| v |
| 7 |
| \ |
| \_ v
+--> 5 -> 9
The tree might look like:
1
/ \
3 5
/|\ |
7 8 9 9
| |
9 9
However, after re-reading your problem:
Given a list of variable constraints of the form A < B, you are to write a program that prints all orderings of the variables that are consistent with the constraints. For example, given the contraints A < B and A < C there are two orderings of the variables A, B and C that are consistent with these constraints: ABC and ACB.
I don't believe this solution will provide you with the answers you are looking for, but you are more than welcome to try and implement it.
Also check out this algorithm .
Note:
I was going to refrain from posting this after re-reading your problem, however I decided against it, as this information may be useful to you.
Good luck.
Adding a solution for future viewers:
To print all solutions of topological sort, we follow the following approach:
Initialize all vertices as unmarked.
Now choose vertex which is unmarked and has zero indegree and decrease indegree of all those vertices by 1 (corresponding to removing edges).
Now add this vertex to list and call the recursive function again and backtrack.
After returning from function reset values of marked, list and indegree for enumeration of other possibilities.
Code below --
class GraphAllTopSorts{
int V; // No. of vertices
LinkedList<Integer>[] adj; //Adjacency List
boolean[] marked; //Boolean array to store the visited nodes
List<Integer> list;
int[] indegree; //integer array to store the indegree of nodes
//Constructor
public GraphAllTopSorts(int v) {
this.V=v;
this.adj = new LinkedList[v];
for (int i=0;i<v;i++) {
adj[i] = new LinkedList<Integer>();
}
this.indegree = new int[v];
this.marked = new boolean[v];
list = new ArrayList<Integer>();
}
// function to add an edge to graph
public void addEdge(int v, int w){
adj[v].add(w);
// increasing inner degree of w by 1
indegree[w]++;
}
// Main recursive function to print all possible topological sorts
public void alltopologicalSorts() {
// To indicate whether all topological are found or not
boolean flag = false;
for (int w=0;w<V;w++) {
// If indegree is 0 and not yet visited then
// only choose that vertex
if (!marked[w] && indegree[w]==0) {
marked[w] = true;
Iterator<Integer> iter = adj[w].listIterator();
while(iter.hasNext()) {
int k = iter.next();
indegree[k]--;
}
// including in list
list.add(w);
alltopologicalSorts();
// resetting marked, list and indegree for backtracking
marked[w] = false;
iter = adj[w].listIterator();
while(iter.hasNext()) {
int k = iter.next();
indegree[k]++;
}
list.remove(list.indexOf(w));
flag = true;
}
}
// We reach here if all vertices are visited.
// So we print the solution here
if (!flag) {
for (int w=0;w<V;w++) {
System.out.print(list.get(w) + " ");
}
System.out.print("\n");
}
}
// Driver program to test above functions
public static void main(String[] args) {
// Create a graph given in the above diagram
GraphAllTopSorts g = new GraphAllTopSorts(6);
g.addEdge(5, 2);
g.addEdge(5, 0);
g.addEdge(4, 0);
g.addEdge(4, 1);
g.addEdge(2, 3);
g.addEdge(3, 1);
System.out.println("All Topological sorts");
g.alltopologicalSorts();
}
}
Source: http://www.geeksforgeeks.org/all-topological-sorts-of-a-directed-acyclic-graph/
Here is the only non-recursion working piece of code I had to construct based on the other algorithms as recursion is really a bad solution when dealing with graph algorithms even if its natural. Instead we can just keep an unvisited set at each level of the topological sort and backtrack without even an extra stack and only this data structure. The time complexity is essentially identical to the recursive versions eg worst case O((m+n)*n!). Of course permuting all $n!$ permutations of set {1..n} and calling a simple O(m+n) is_topological_sort
function will be slower on average case and could not be used to solve a sufficiently large challenge problem.
def topo_khan_enum(g): #O((m+n)*n!)
topo, S, k = [], set(), 0
inc = {u: 0 for u in g}
for u in g:
for v in g[u]: inc[v] += 1
for u in g:
if inc[u] == 0: S.add(u)
unprocessed = {0: set(S)}
while len(unprocessed[k]) != 0:
while len(S) != 0:
u = unprocessed[k].pop(); S.remove(u); k += 1
topo.append(u)
for v in g[u]:
inc[v] -= 1
if inc[v] == 0: S.add(v)
unprocessed[k] = set(S)
if k < len(g): raise ValueError
yield list(topo)
while True:
u = topo.pop(); k -= 1
for v in g[u]:
if inc[v] == 0: S.remove(v)
inc[v] += 1
S.add(u)
if k == 0 or len(unprocessed[k]) != 0: break
return ()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.