/**
   * Returns a List with unique elements,
   *
   * @param v1 vertex from g1
   * @return
   */
  public List<V> getPrioritySubset(V v1) {
    // The resulting list
    List<V> result = new ArrayList<V>();

    // list of already mapped vertices that neighbour v1
    List<V> v1Others = new ArrayList<V>();

    V v1other;
    V v2other;
    for (E e1 : g1.edgesOf(v1)) {
      v1other = Graphs.getOppositeVertex(g1, e1, v1);
      if (mappedVerticesFromG1.contains(v1other)) {
        v1Others.add(v1other);
      }
    }
    for (V v2 : g2.vertexSet()) {
      // if v2's label is the same of v1's label and v2 has not been mapped yet
      if (v1.getLabel().equals(v2.getLabel()) && !mappedVerticesFromG2.contains(v2)) {
        // test if there is an edge to a vertex which has already been mapped
        for (E e2 : g2.edgesOf(v2)) {
          v2other = Graphs.getOppositeVertex(g2, e2, v2);
          // if the vertex v2other has already been mapped
          if (mappedVerticesFromG2.contains(v2other)) {
            // labels are not checked, this is done at a later stage anyway and doing it twice is
            // not needed and takes too much time
            result.add(v2);
            break;
          }
        }
      }
    }
    return result;
  }
Esempio n. 2
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;
  }
 public static Set outgoingEdgesOf(Graph g, Object node) {
   if (g instanceof DirectedGraph) {
     return ((DirectedGraph) g).outgoingEdgesOf(node);
   } else {
     return g.edgesOf(node);
   }
 }
  @Override
  public boolean add(Integer i) {
    // maintain unweighted volume
    Set<DefaultWeightedEdge> neighborSet = graph.edgesOf(i);
    volume += neighborSet.size();

    // maintain correct denominator to compute conductance with
    denominator = Math.min(volume, totalVolume - volume);

    // count how many external edges this node has with the community
    external_edges += countExternalEdges(i, neighborSet);

    conductance = external_edges / (double) denominator;

    return super.add(i);
  }
  @Override
  public boolean remove(Object o) {
    Integer i = (Integer) o;
    // maintain unweighted volume
    Set<DefaultWeightedEdge> neighborSet = graph.edgesOf(i);
    volume -= neighborSet.size();

    // maintain correct denominator to compute conductance with
    denominator = Math.min(volume, totalVolume - volume);

    boolean retValue = super.remove(i);

    // count how many external edges this node has with the community, and remove them (opposite of
    // add)
    external_edges -= countExternalEdges(i, neighborSet);

    conductance = external_edges / (double) denominator;

    return retValue;
  }
  /**
   * Return the change in conductance which would occur from adding a particular vertex to the set.
   * This is linear in the degree of the vertex. ie., O(degree(toAdd))
   */
  @Override
  public double getDeltaConductance(Integer vertex, boolean add) {

    Set<DefaultWeightedEdge> neighborSet = graph.edgesOf(vertex);

    int degree_U = neighborSet.size();
    long delta_E = 0;

    delta_E = countExternalEdges(vertex, neighborSet);

    if (!add) {
      delta_E = -1 * delta_E;
      degree_U = -1 * degree_U;
    }

    long new_volume = volume + degree_U;
    long new_denom = Math.min(new_volume, totalVolume - new_volume);
    double rescaled_conductance = ((denominator) / (double) (new_denom)) * conductance;
    double final_conductance = rescaled_conductance + (delta_E) / (double) (new_denom);

    // this is the change in conductance if one were to add node u
    return final_conductance - conductance;
  }
Esempio n. 7
0
 Set<E> edgesOf(V vertex) {
   return graph.edgesOf(vertex);
 }
  // 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);
  }
  // the algorithm (no heuristics)
  private Pair<Double, Set<E>> run(Graph<V, E> graph) {
    // lookup all relevant vertices
    Set<V> visibleVertex = initVisibleVertices(graph);

    // run algorithm
    Set<E> m1 = new HashSet<>();
    Set<E> m2 = new HashSet<>();
    double m1Weight = 0d, m2Weight = 0d;
    int i = 1;
    while (!visibleVertex.isEmpty()) {
      // find vertex arbitrarily
      V x = visibleVertex.stream().findAny().get();

      // grow path from x
      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 it to either m1 or m2, alternating between them
        if (maxWeightedEdge != null) {
          switch (i) {
            case 1:
              m1.add(maxWeightedEdge);
              m1Weight += maxWeight;
              break;
            case 2:
              m2.add(maxWeightedEdge);
              m2Weight += maxWeight;
              break;
            default:
              throw new RuntimeException("Failed to figure out matching, seems to be a bug");
          }
          i = 3 - i;
        }

        // remove x and incident edges
        visibleVertex.remove(x);

        // go to next vertex
        x = maxWeightedNeighbor;
      }
    }

    // return best matching
    if (comparator.compare(m1Weight, m2Weight) > 0) {
      return Pair.of(m1Weight, m1);
    } else {
      return Pair.of(m2Weight, m2);
    }
  }
Esempio n. 10
0
 @Override
 public int compare(V2 v1, V2 v2) {
   return graph.edgesOf(v1).size() - graph.edgesOf(v2).size();
 }
Esempio n. 11
0
 /** @see CrossComponentIterator.Specifics#edgesOf(Object) */
 public Set<EE> edgesOf(VV vertex) {
   return graph.edgesOf(vertex);
 }
Esempio n. 12
0
  /* Each
  time a node in G1 is tentatively paired with a node in G2, MARCS is refined on the
  basis of this node correspondence. Say node i  in G1 is tentatively paired with node j in
  G2. Then any arc r connected to node i in G1 can correspond only to arcs which are
  connected to node j in G2. This is represented in MARCS by setting to zero any bit
  (r, s) such that arc r is connected to node i in G, and arc s is not connected to node j in
  G2. */
  public void refine(V v1, V v2) {
    // marcs is modified, make sure subgraph is set to null (to prevent errors)
    subgraph = null;

    mappedVerticesFromG1.add(v1);
    mappedVerticesFromG2.add(v2);
    List<Integer> edgesV1Ints = null;
    List<Integer> edgesV2Ints = null;
    List<Integer> edgesV1OutInts = null;
    List<Integer> edgesV1InInts = null;
    List<Integer> edgesV2OutInts = null;
    List<Integer> edgesV2InInts = null;
    if (!directed) {
      edgesV1Ints = new ArrayList<Integer>();
      edgesV2Ints = new ArrayList<Integer>();
      for (E e1 : g1.edgesOf(v1)) {
        edgesV1Ints.add(edgeList1.indexOf(e1));
      }
      for (E e2 : g2.edgesOf(v2)) {
        edgesV2Ints.add(edgeList2.indexOf(e2));
      }
    } else { // directed
      edgesV1OutInts = new ArrayList<Integer>();
      edgesV1InInts = new ArrayList<Integer>();
      edgesV2OutInts = new ArrayList<Integer>();
      edgesV2InInts = new ArrayList<Integer>();
      for (E e1 : ((DirectedGraph<V, E>) g1).outgoingEdgesOf(v1)) {
        edgesV1OutInts.add(edgeList1.indexOf(e1));
      }
      for (E e1 : ((DirectedGraph<V, E>) g1).incomingEdgesOf(v1)) {
        edgesV1InInts.add(edgeList1.indexOf(e1));
      }
      for (E e2 : ((DirectedGraph<V, E>) g2).outgoingEdgesOf(v2)) {
        edgesV2OutInts.add(edgeList2.indexOf(e2));
      }
      for (E e2 : ((DirectedGraph<V, E>) g2).incomingEdgesOf(v2)) {
        edgesV2InInts.add(edgeList2.indexOf(e2));
      }
    }
    for (int x = 0; x < dimx; x++) {
      if (!rowOrs[x]) continue;
      for (int y = 0; y < dimy; y++) {
        // if the only one of the two edges x and y are connected to v1 or v2 then x and y are not
        // compatible and the matrix should be set to false
        if (matrix[x][y]) {
          if (directed) {
            if ((edgesV1OutInts.contains(x) && !edgesV2OutInts.contains(y))
                || (!edgesV1OutInts.contains(x) && edgesV2OutInts.contains(y))
                || (edgesV1InInts.contains(x) && !edgesV2InInts.contains(y))
                || (!edgesV1InInts.contains(x) && edgesV2InInts.contains(y))) {
              matrix[x][y] = false;
            }
          } else { // undirected
            if ((edgesV1Ints.contains(x) && !edgesV2Ints.contains(y))
                || (!edgesV1Ints.contains(x) && edgesV2Ints.contains(y))) {
              matrix[x][y] = false;
            }
          }
        }
      }
    }
  }