예제 #1
0
 private boolean edgesCompatible(int edge1, int edge2) {
   E e1 = edgeList1.get(edge1);
   E e2 = edgeList2.get(edge2);
   boolean result = false;
   // edge label must be the same
   if (e1.getLabel().equals(e2.getLabel())) {
     // check connecting vertex labels
     L v1SourceLbl = g1.getEdgeSource(e1).getLabel(),
         v1TargetLbl = g1.getEdgeTarget(e1).getLabel(),
         v2SourceLbl = g2.getEdgeSource(e2).getLabel(),
         v2TargetLbl = g2.getEdgeTarget(e2).getLabel();
     // checks if the pair of source vertices have the same label, and checks the same for the
     // target vertices
     boolean sourceTargetMatch =
         v1SourceLbl.equals(v2SourceLbl) && v1TargetLbl.equals(v2TargetLbl);
     if (directed) {
       result = sourceTargetMatch;
     } else {
       // checks if source1,target2 have the same label and if target1,source2 have the same label
       boolean sourceTargetInverseMatch =
           v1SourceLbl.equals(v2TargetLbl) && v1TargetLbl.equals(v2SourceLbl);
       result = (sourceTargetMatch || sourceTargetInverseMatch);
     }
   }
   return result;
 }
  private void init(Graph<V, E> g, Set<V> vertexSet, Set<E> edgeSet) {
    // create a map between vertex value to its order(1st,2nd,etc)
    // "CAT"=1 "DOG"=2 "RHINO"=3

    this.mapVertexToOrder = new HashMap<V, Integer>(vertexSet.size());

    int counter = 0;
    for (V vertex : vertexSet) {
      mapVertexToOrder.put(vertex, new Integer(counter));
      counter++;
    }

    // create a friendlier representation of an edge
    // by order, like 2nd->3rd instead of B->A
    // use the map to convert vertex to order
    // on directed graph, edge A->B must be (A,B)
    // on undirected graph, edge A-B can be (A,B) or (B,A)

    this.labelsEdgesSet = new HashSet<LabelsEdge>(edgeSet.size());
    for (E edge : edgeSet) {
      V sourceVertex = g.getEdgeSource(edge);
      Integer sourceOrder = mapVertexToOrder.get(sourceVertex);
      int sourceLabel = sourceOrder.intValue();
      int targetLabel = (mapVertexToOrder.get(g.getEdgeTarget(edge))).intValue();

      LabelsEdge lablesEdge = new LabelsEdge(sourceLabel, targetLabel);
      this.labelsEdgesSet.add(lablesEdge);

      if (g instanceof UndirectedGraph<?, ?>) {
        LabelsEdge oppositeEdge = new LabelsEdge(targetLabel, sourceLabel);
        this.labelsEdgesSet.add(oppositeEdge);
      }
    }
  }
예제 #3
0
  /**
   * @param vertexNumber the number which identifies the vertex v in this order.
   * @return the identifying numbers of all vertices which are connected to v by an edge incoming to
   *     v.
   */
  public int[] getInEdges(int vertexNumber) {
    if (cacheEdges && (incomingEdges[vertexNumber] != null)) {
      return incomingEdges[vertexNumber];
    }

    V v = getVertex(vertexNumber);
    Set<E> edgeSet;

    if (graph instanceof DirectedGraph<?, ?>) {
      edgeSet = ((DirectedGraph<V, E>) graph).incomingEdgesOf(v);
    } else {
      edgeSet = graph.edgesOf(v);
    }

    int[] vertexArray = new int[edgeSet.size()];
    int i = 0;

    for (E edge : edgeSet) {
      V source = graph.getEdgeSource(edge), target = graph.getEdgeTarget(edge);
      vertexArray[i++] = mapVertexToOrder.get(source.equals(v) ? target : source);
    }

    if (cacheEdges) {
      incomingEdges[vertexNumber] = vertexArray;
    }

    return vertexArray;
  }
  @Override
  public TraversalGraph<V, E> reconstructTraversalGraph() {

    if (currentStartNode == null) {
      throw new IllegalStateException(
          "You must call #calculate before " + "reconstructing the traversal graph.");
    }

    TraversalGraph<V, E> traversalGraph =
        new TraversalGraph<V, E>(graph.getEdgeFactory(), currentStartNode);
    for (V v : graph.vertexSet()) {
      Set<E> predEdges = (Set<E>) v.getPredecessorEdges();
      for (E e : predEdges) {
        V source = graph.getEdgeSource(e);
        V target = graph.getEdgeTarget(e);
        traversalGraph.addVertex(source);
        traversalGraph.addVertex(target);
        if (v.equals(source)) {
          traversalGraph.addEdge(target, source).setBaseGraphEdge(e);
        } else if (v.equals(target)) {
          traversalGraph.addEdge(source, target).setBaseGraphEdge(e);
        } else {
          throw new IllegalStateException(
              "A vertex has a predecessor " + "edge not ending on itself.");
        }
      }
    }

    return traversalGraph;
  }
예제 #5
0
  public int[] getEdgeNumbers(E e) {
    V v1 = graph.getEdgeSource(e), v2 = graph.getEdgeTarget(e);

    int[] edge = new int[2];
    edge[0] = mapVertexToOrder.get(v1);
    edge[1] = mapVertexToOrder.get(v2);

    return edge;
  }
 /**
  * Compute all vertices that have positive degree by iterating over the edges on purpose. This
  * keeps the complexity to O(m) where m is the number of edges.
  *
  * @param graph the graph
  * @return set of vertices with positive degree
  */
 private Set<V> initVisibleVertices(Graph<V, E> graph) {
   Set<V> visibleVertex = new HashSet<>();
   for (E e : graph.edgeSet()) {
     V s = graph.getEdgeSource(e);
     V t = graph.getEdgeTarget(e);
     if (!s.equals(t)) {
       visibleVertex.add(s);
       visibleVertex.add(t);
     }
   }
   return visibleVertex;
 }
  /** Calculates the matrix of all shortest paths, but does not populate the paths map. */
  private void lazyCalculateMatrix() {
    if (d != null) {
      // already done
      return;
    }

    int n = vertices.size();

    // init the backtrace matrix
    backtrace = new int[n][n];
    for (int i = 0; i < n; i++) {
      Arrays.fill(backtrace[i], -1);
    }

    // initialize matrix, 0
    d = new double[n][n];
    for (int i = 0; i < n; i++) {
      Arrays.fill(d[i], Double.POSITIVE_INFINITY);
    }

    // initialize matrix, 1
    for (int i = 0; i < n; i++) {
      d[i][i] = 0.0;
    }

    // initialize matrix, 2
    Set<E> edges = graph.edgeSet();
    for (E edge : edges) {
      V v1 = graph.getEdgeSource(edge);
      V v2 = graph.getEdgeTarget(edge);

      int v_1 = vertices.indexOf(v1);
      int v_2 = vertices.indexOf(v2);

      d[v_1][v_2] = graph.getEdgeWeight(edge);
      if (!(graph instanceof DirectedGraph<?, ?>)) {
        d[v_2][v_1] = graph.getEdgeWeight(edge);
      }
    }

    // run fw alg
    for (int k = 0; k < n; k++) {
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
          double ik_kj = d[i][k] + d[k][j];
          if (ik_kj < d[i][j]) {
            d[i][j] = ik_kj;
            backtrace[i][j] = k;
          }
        }
      }
    }
  }
  public long countExternalEdges(Integer i, Set<DefaultWeightedEdge> neighborSet) {

    int numberExternalEdges = 0;

    // count number of external edges
    for (DefaultWeightedEdge edge : neighborSet) {

      // no easy way to get 'other' out of JGraph's undirected graph edge traversal... ugh!
      Integer src = graph.getEdgeSource(edge);
      Integer dst = graph.getEdgeTarget(edge);
      Integer other = src.equals(i) ? dst : src;

      if (contains(other)) {
        numberExternalEdges -= 1;
      } else {
        numberExternalEdges += 1;
      }
    }

    return numberExternalEdges;
  }
예제 #9
0
 V getEdgeTarget(E e) {
   return graph.getEdgeTarget(e);
 }
  // the algorithm (improved with additional heuristics)
  private Pair<Double, Set<E>> runWithHeuristics(Graph<V, E> graph) {
    // lookup all relevant vertices
    Set<V> visibleVertex = initVisibleVertices(graph);

    // create solver for paths
    DynamicProgrammingPathSolver pathSolver = new DynamicProgrammingPathSolver();

    Set<E> matching = new HashSet<>();
    double matchingWeight = 0d;
    Set<V> matchedVertices = new HashSet<>();

    // run algorithm
    while (!visibleVertex.isEmpty()) {
      // find vertex arbitrarily
      V x = visibleVertex.stream().findAny().get();

      // grow path from x
      LinkedList<E> path = new LinkedList<>();
      while (x != null) {
        // first heaviest edge incident to vertex x (among visible neighbors)
        double maxWeight = 0d;
        E maxWeightedEdge = null;
        V maxWeightedNeighbor = null;
        for (E e : graph.edgesOf(x)) {
          V other = Graphs.getOppositeVertex(graph, e, x);
          if (visibleVertex.contains(other) && !other.equals(x)) {
            double curWeight = graph.getEdgeWeight(e);
            if (comparator.compare(curWeight, 0d) > 0
                && (maxWeightedEdge == null || comparator.compare(curWeight, maxWeight) > 0)) {
              maxWeight = curWeight;
              maxWeightedEdge = e;
              maxWeightedNeighbor = other;
            }
          }
        }

        // add edge to path and remove x
        if (maxWeightedEdge != null) {
          path.add(maxWeightedEdge);
        }
        visibleVertex.remove(x);

        // go to next vertex
        x = maxWeightedNeighbor;
      }

      // find maximum weight matching of path using dynamic programming
      Pair<Double, Set<E>> pathMatching = pathSolver.getMaximumWeightMatching(graph, path);

      // add it to result while keeping track of matched vertices
      matchingWeight += pathMatching.getFirst();
      for (E e : pathMatching.getSecond()) {
        V s = graph.getEdgeSource(e);
        V t = graph.getEdgeTarget(e);
        if (!matchedVertices.add(s)) {
          throw new RuntimeException("Set is not a valid matching, please submit a bug report");
        }
        if (!matchedVertices.add(t)) {
          throw new RuntimeException("Set is not a valid matching, please submit a bug report");
        }
        matching.add(e);
      }
    }

    // extend matching to maximal cardinality (out of edges with positive weight)
    for (E e : graph.edgeSet()) {
      double edgeWeight = graph.getEdgeWeight(e);
      if (comparator.compare(edgeWeight, 0d) <= 0) {
        // ignore zero or negative weight
        continue;
      }
      V s = graph.getEdgeSource(e);
      if (matchedVertices.contains(s)) {
        // matched vertex, ignore
        continue;
      }
      V t = graph.getEdgeTarget(e);
      if (matchedVertices.contains(t)) {
        // matched vertex, ignore
        continue;
      }
      // add edge to matching
      matching.add(e);
      matchingWeight += edgeWeight;
    }

    // return extended matching
    return Pair.of(matchingWeight, matching);
  }
예제 #11
0
  /**
   * @param connectedOnly if true, the result will be a connected graph
   * @return
   */
  public Graph<V, E> toGraph() {
    if (subgraph != null) return subgraph;
    if (directed) {
      subgraph = new DirectedMultigraph<V, E>(g2.getEdgeFactory());
    } else {
      subgraph = new Multigraph<V, E>(g2.getEdgeFactory());
    }

    E edge;
    V source;
    V target;
    for (int x = 0; x < dimx; x++) {
      for (int y = 0; y < dimy; y++) {
        if (matrix[x][y]) {
          edge = edgeList2.get(y);
          source = g2.getEdgeSource(edge);
          target = g2.getEdgeTarget(edge);
          if (mappedVerticesFromG2.contains(source) && mappedVerticesFromG2.contains(target)) {
            // make sure the source and target vertices have been added, then add the edge
            subgraph.addVertex(source);
            subgraph.addVertex(target);
            subgraph.addEdge(source, target, edge);
          }
        }
      }
    }

    if (connectedOnly) {
      // make sure this subgraph is connected, if it is not return the largest connected part
      List<Set<V>> connectedVertices = new ArrayList<Set<V>>();
      for (V v : subgraph.vertexSet()) {
        if (!SharedStaticMethods.containsV(connectedVertices, v)) {
          connectedVertices.add(SharedStaticMethods.getConnectedVertices(subgraph, v));
        }
      }
      // ConnectedVertices now contains Sets of connected vertices every vertex of the subgraph is
      // contained exactly once in the list
      // if there is more then 1 set, then this method should return the largest connected part of
      // the graph
      if (connectedVertices.size() > 1) {
        Graph<V, E> largestResult = null;
        Graph<V, E> currentGraph;
        int largestSize = -1;
        Set<V> currentSet;
        for (int i = 0; i < connectedVertices.size(); i++) {
          currentSet = connectedVertices.get(i);
          /*note that 'subgraph' is the result from the Mcgregor algorithm, 'currentGraph' is an
           * induced subgraph of 'subgraph'. 'currentGraph' is connected, because the vertices in
           * 'currentSet' are connected with edges in 'subgraph'
           */
          currentGraph = new Subgraph<V, E, Graph<V, E>>(subgraph, currentSet);
          if (currentGraph.edgeSet().size() > largestSize) {
            largestResult = currentGraph;
          }
        }

        return largestResult;
      }
    }

    return subgraph;
  }