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

org.peekmoon.database.walker.KosarajuAlgo Maven / Gradle / Ivy

package org.peekmoon.database.walker;

import java.util.ArrayList;
import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class KosarajuAlgo {
	
	private final Map> rowsChildGraph;
	private final Map> rowsParentGraph;
	
	private final Deque l = new LinkedList<>();
	private final Set visited = new HashSet<>();
	
	private final List> components = new ArrayList<>();
	
	public KosarajuAlgo(Map> rowsChildGraph, Map> rowsParentGraph) {
		int childSize = rowsChildGraph.size();
		int parentSize = rowsParentGraph.size();
		if (childSize != parentSize) {
			throw new IllegalArgumentException("Graphs have not the same nomber of vertices "
					+ "child=" + childSize	+ " parent=" + parentSize);
		}
		this.rowsChildGraph = rowsChildGraph;
		this.rowsParentGraph = rowsParentGraph;
	}
	
	public List> process() {
	
		// First pass
		for (Row childRow : rowsChildGraph.keySet()) {
			visit(childRow);
		}
		
		// Second pass
		for (Row row : l) {
			assign(row, row);
		}
		
		return components;
	}
			
	
	private void visit(Row row) {
		if (visited.add(row)) {
			for (Row parent : rowsChildGraph.get(row)) {
				visit(parent);
			}
			l.push(row);
		};
	}
	
	private void assign(Row row, Row rootRow) {
		
		if (!isAssign(row)) {
			getComponent(rootRow).add(row);
			for (Row child : rowsParentGraph.get(row)) {
				assign(child, rootRow);
			}
		}
	}

	private boolean isAssign(Row row) {
		return components.stream().anyMatch(rows->rows.contains(row));
	}
	
	private Set getComponent(Row row) {
		return components.stream()
				.filter(rows->rows.contains(row))
				.findFirst()
				.orElseGet(()-> {
					Set newComponent = new HashSet<>();
					components.add(newComponent);
					return newComponent;
				});
	}
	

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy