/*
* This file is part of JOP, the Java Optimized Processor
* see <http://www.jopdesign.com/>
*
* Copyright (C) 2011, Stefan Hepp (stefan@stefant.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jopdesign.common.graphutils;
import com.jopdesign.common.graphutils.DFSTraverser.DFSEdgeType;
import com.jopdesign.common.graphutils.DFSTraverser.DFSVisitor;
import com.jopdesign.common.graphutils.DFSTraverser.EmptyDFSVisitor;
import org.jgrapht.DirectedGraph;
import org.jgrapht.EdgeFactory;
import org.jgrapht.graph.DefaultDirectedGraph;
import org.jgrapht.graph.SimpleDirectedGraph;
import java.util.Collection;
import java.util.Set;
/**
* @author Stefan Hepp (stefan@stefant.org)
*/
public class GraphUtils {
public static <V,E> DirectedGraph<V,E> copyGraph(DirectedGraph<V,E> graph,
Collection<V> roots,
final boolean includeBackedges)
{
return copyGraph(new DefaultEdgeProvider<V, E>(graph), graph.getEdgeFactory(), roots, includeBackedges);
}
public static <V,E> DirectedGraph<V,E> copyGraph(EdgeProvider<V,E> provider, EdgeFactory<V,E> factory,
Collection<V> roots,
final boolean includeBackedges)
{
final DirectedGraph<V,E> newGraph = new DefaultDirectedGraph<V, E>(factory);
DFSVisitor<V,E> visitor = new EmptyDFSVisitor<V, E>() {
@Override
public boolean visitNode(V parent, E edge, V node, DFSEdgeType type, Collection<E> outEdges, int depth) {
if (type.isFirstVisit()) {
newGraph.addVertex(node);
}
if (type != DFSEdgeType.ROOT && (includeBackedges || type != DFSEdgeType.BACK_EDGE)) {
newGraph.addEdge(parent, node);
}
return true;
}
};
DFSTraverser<V,E> traverser = new DFSTraverser<V, E>(visitor);
traverser.traverse(provider, roots);
return newGraph;
}
public static <V,E> SimpleDirectedGraph<V,E> createAcyclicGraph(DirectedGraph<V, E> graph) {
BackEdgeFinder<V,E> finder = new BackEdgeFinder<V, E>(graph);
return finder.createDAG();
}
public static <V,E> SimpleDirectedGraph<V,E> createSimpleGraph(DirectedGraph<V,E> graph) {
SimpleDirectedGraph<V,E> simpleGraph = new SimpleDirectedGraph<V, E>(graph.getEdgeFactory());
// add all nodes
for (V node : graph.vertexSet()) {
simpleGraph.addVertex(node);
}
for (E edge : graph.edgeSet()) {
V source = graph.getEdgeSource(edge);
V target = graph.getEdgeTarget(edge);
if (!source.equals(target)) {
simpleGraph.addEdge(source, target, edge);
}
}
return simpleGraph;
}
public static <V,E> SimpleDirectedGraph<V,E> createSimpleGraph(DirectedGraph<V,E> graph,
Set<V> nodes, boolean addChilds)
{
SimpleDirectedGraph<V,E> simpleGraph = new SimpleDirectedGraph<V, E>(graph.getEdgeFactory());
for (V node : nodes) {
simpleGraph.addVertex(node);
}
for (V node : nodes) {
for (E edge : graph.outgoingEdgesOf(node)) {
V target = graph.getEdgeTarget(edge);
boolean inGraph = simpleGraph.containsVertex(target);
if (addChilds && !inGraph) {
simpleGraph.addVertex(target);
inGraph = true;
}
if (inGraph) {
simpleGraph.addEdge(node, target, edge);
}
}
}
return simpleGraph;
}
}