blob: b1273f04ff6a1e799d4a6459373f0027d690c2b6 [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2017 CEA LIST.
*
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* CEA LIST - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.moka.parametric.utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
public class Graph<T> {
private int v;
private LinkedList<Integer> adj[];
protected Map<Integer, T> index2Object = new HashMap<Integer, T>() ;
protected Map<T, Integer> object2Index = new HashMap<T, Integer>() ;
public Graph(Set<T> vertices, Map<T, Set<T>> edges) {
this.v = vertices.size() ;
adj = new LinkedList[v];
for (int i=0; i<this.v; ++i) {
adj[i] = new LinkedList();
}
int i = 0 ;
for (T obj : vertices) {
index2Object.put(i, obj) ;
object2Index.put(obj, i) ;
i++ ;
}
for (T obj : vertices) {
int objIndex = object2Index.get(obj) ;
if (edges.get(obj) != null) {
for (T connectedTo : edges.get(obj)) {
addEdge(objIndex, object2Index.get(connectedTo));
}
}
}
}
//Constructor
public Graph(int v) {
this.v = v;
adj = new LinkedList[v];
for (int i=0; i<v; ++i) {
adj[i] = new LinkedList();
}
}
// Function to add an edge into the graph
void addEdge(int v,int w) {
adj[v].add(w);
}
// A recursive function used by topologicalSort
void topologicalSortUtil(int v, boolean visited[], Stack<Integer> stack) {
// Mark the current node as visited.
visited[v] = true;
Integer i;
// Recur for all the vertices adjacent to this
// vertex
Iterator<Integer> it = adj[v].iterator();
while (it.hasNext()) {
i = it.next();
if (!visited[i]) {
topologicalSortUtil(i, visited, stack);
}
}
// Push current vertex to stack which stores result
stack.push(new Integer(v));
}
// The function to do Topological Sort. It uses
// recursive topologicalSortUtil()
public List<T> topologicalSort() {
Stack<Integer> stack = new Stack<Integer>();
// Mark all the vertices as not visited
boolean visited[] = new boolean[this.v];
for (int i = 0; i < this.v; i++)
visited[i] = false;
// Call the recursive helper function to store
// Topological Sort starting from all vertices
// one by one
for (int i = 0; i < this.v; i++) {
if (visited[i] == false) {
topologicalSortUtil(i, visited, stack);
}
}
// Print contents of stack
//while (stack.empty()==false) {
// System.out.print(stack.pop() + " ");
//}
List<T> sorted = new ArrayList<T>() ;
while (stack.empty()==false) {
int index = stack.pop() ;
T obj = index2Object.get(index) ;
sorted.add(obj) ;
}
return sorted ;
}
// This function is a variation of DFSUytil() in http://www.geeksforgeeks.org/archives/18212
public boolean isCyclicUtil(int v, boolean visited[], boolean recStack[])
{
Integer i ;
if(visited[v] == false)
{
// Mark the current node as visited and part of recursion stack
visited[v] = true;
recStack[v] = true;
// Recur for all the vertices adjacent to this vertex
Iterator<Integer> it = adj[v].iterator();
while (it.hasNext()) {
i = it.next();
if ( !visited[i] && isCyclicUtil(i, visited, recStack) )
return true;
else if (recStack[i])
return true;
}
}
recStack[v] = false; // remove the vertex from recursion stack
return false;
}
// Returns true if the graph contains a cycle, else false.
// This function is a variation of DFS() in http://www.geeksforgeeks.org/archives/18212
public boolean isCyclic()
{
// Mark all the vertices as not visited and not part of recursion
// stack
boolean[] visited = new boolean[v];
boolean[] recStack = new boolean[v];
for(int i = 0; i < v; i++)
{
visited[i] = false;
recStack[i] = false;
}
// Call the recursive helper function to detect cycle in different
// DFS trees
for(int i = 0; i < v; i++)
if (isCyclicUtil(i, visited, recStack))
return true;
return false;
}
}