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

com.hubspot.blazar.data.util.GraphUtils Maven / Gradle / Ivy

package com.hubspot.blazar.data.util;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.TreeMultimap;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

public enum GraphUtils {
  INSTANCE;

  public > List topologicalSort(SetMultimap transitiveReduction) {
    SetMultimap graph = TreeMultimap.create(transitiveReduction);

    List sorted = new ArrayList<>();
    Deque roots = new ArrayDeque<>();
    for (V vertex : graph.keySet()) {
      if (incomingVertices(graph, vertex).isEmpty()) {
        roots.add(vertex);
      }
    }

    while (!roots.isEmpty()) {
      V root = roots.removeFirst();
      sorted.add(root);

      Set children = graph.removeAll(root);
      for (V child : children) {
        if (incomingVertices(graph, child).isEmpty()) {
          roots.addLast(child);
        }
      }
    }

    return sorted;
  }

  public  SetMultimap transitiveReduction(SetMultimap edges) {
    SetMultimap paths = findAllPaths(edges);

    SetMultimap reduced = HashMultimap.create(paths);
    Set vertices = vertices(paths);

    for (V vertexJ : vertices) {
      for (V vertexI : vertices) {
        if (reduced.get(vertexI).contains(vertexJ)) {
          for (V vertexK : vertices) {
            if (reduced.get(vertexJ).contains(vertexK)) {
              reduced.get(vertexI).remove(vertexK);
            }
          }
        }
      }
    }

    return reduced;
  }

  private  Set incomingVertices(SetMultimap graph, V target) {
    Set incomingVertices = new HashSet<>();
    for (Entry path : graph.entries()) {
      if (path.getValue().equals(target)) {
        incomingVertices.add(path.getKey());
      }
    }

    return incomingVertices;
  }

  private  SetMultimap findAllPaths(SetMultimap edges) {
    SetMultimap paths = HashMultimap.create(edges);
    Set vertices = vertices(paths);

    for (V vertexI : vertices) {
      for (V vertexJ : vertices) {
        if (paths.get(vertexJ).contains(vertexI)) {
          for (V vertexK : vertices) {
            if (paths.get(vertexI).contains(vertexK)) {
              paths.get(vertexJ).add(vertexK);
            }
          }
        }
      }
    }

    return paths;
  }

  private  Set vertices(SetMultimap graph) {
    return ImmutableSet.builder().addAll(graph.keySet()).addAll(graph.values()).build();
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy