All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.reprezen.genflow.common.graph.TopologicalSorter Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright © 2013, 2016 Modelsolv, Inc.
 * All Rights Reserved.
 *
 * NOTICE: All information contained herein is, and remains the property
 * of ModelSolv, Inc. See the file license.html in the root directory of
 * this project for further information.
 *******************************************************************************/
package com.reprezen.genflow.common.graph;

import static com.google.common.collect.Lists.newArrayList;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

/**
 * Topologically sorts elements to achieve the left-to-right link direction.
 * 
 * @author Tatiana Fesenko 
 * @param 
 * 
 */
public class TopologicalSorter {

	/**
	 * Partitions the graph into disconnected subgraphs and topologically sorts the
	 * subgraphs. The left-to-right direction is guaranteed only for acyclic graphs.
	 * 
	 * @param       > the generic type
	 * @param graph the graph
	 * @return a list of topologically sorted vertices
	 */
	public static  List> splitAndSort(DirectedGraph graph) {
		List> subgraphs = new GraphSplitter().splitToDisconnectedSubGraphs(graph);
		// Collections.reverse(subgraphs);
		List> result = new ArrayList<>();
		for (DirectedGraph subgraph : subgraphs) {
			result.addAll(new TopologicalSorter(subgraph).sort());
		}
		return result;
	}

	private final DirectedGraph graph;
	private final List> reversedResult = new ArrayList>();
	private final Set> visited = new HashSet>();

	public TopologicalSorter(DirectedGraph graph) {
		this.graph = graph;
	}

	/**
	 * Topologically sort the graph
	 * 
	 * @return a list of topologically sorted vertices
	 */
	public List> sort() {
		reversedResult.clear();
		visited.clear();
		ArrayList> reversedGraph = newArrayList(graph);
		Collections.reverse(reversedGraph);
		for (DirectedGraphNode n : graph) {
			reversedResult.addAll(visit(n));
		}
		Collections.reverse(reversedResult);
		return reversedResult;
	}

	private LinkedList> visit(DirectedGraphNode current) {
		LinkedList> result = new LinkedList<>();
		if (visited.contains(current)) {
			return result;
		}
		visited.add(current);
		for (DirectedGraphNode next : current.edgesFrom()) {
			result.addAll(visit(next));
		}
		result.add(current);
		return result;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy