示例#1
0
  /**
   * @param graph the graph to be ordered
   * @param orderByDegree should the vertices be ordered by their degree. This speeds up the VF2
   *     algorithm.
   * @param cacheEdges if true, the class creates a adjacency matrix and two arrays for incoming and
   *     outgoing edges for fast access.
   */
  public GraphOrdering(Graph<V, E> graph, boolean orderByDegree, boolean cacheEdges) {
    this.graph = graph;
    this.cacheEdges = cacheEdges;

    List<V> vertexSet = new ArrayList<>(graph.vertexSet());
    if (orderByDegree) {
      java.util.Collections.sort(vertexSet, new GeneralVertexDegreeComparator<>(graph));
    }

    vertexCount = vertexSet.size();
    mapVertexToOrder = new HashMap<>();
    mapOrderToVertex = new ArrayList<>(vertexCount);

    if (cacheEdges) {
      outgoingEdges = new int[vertexCount][];
      incomingEdges = new int[vertexCount][];
      adjMatrix = new Boolean[vertexCount][vertexCount];
    }

    Integer i = 0;
    for (V vertex : vertexSet) {
      mapVertexToOrder.put(vertex, i++);
      mapOrderToVertex.add(vertex);
    }
  }
示例#2
0
    /** {@inheritDoc} */
    protected void encounterVertexAgain(V vertex, E edge) {
      super.encounterVertexAgain(vertex, edge);

      int i;

      if (root != null) {
        // For rooted detection, the path must either
        // double back to the root, or to a node of a cycle
        // which has already been detected.
        if (vertex.equals(root)) {
          i = 0;
        } else if ((cycleSet != null) && cycleSet.contains(vertex)) {
          i = 0;
        } else {
          return;
        }
      } else {
        i = path.indexOf(vertex);
      }

      if (i > -1) {
        if (cycleSet == null) {
          // we're doing yes/no cycle detection
          throw new CycleDetectedException();
        } else {
          for (; i < path.size(); ++i) {
            cycleSet.add(path.get(i));
          }
        }
      }
    }
  /** Calculate the shortest paths (not done per default) */
  private void lazyCalculatePaths() {
    // already we have calculated it once.
    if (paths != null) {
      return;
    }

    lazyCalculateMatrix();

    Map<VertexPair<V>, GraphPath<V, E>> sps = new HashMap<VertexPair<V>, GraphPath<V, E>>();
    int n = vertices.size();

    nShortestPaths = 0;
    for (int i = 0; i < n; i++) {
      V v_i = vertices.get(i);
      for (int j = 0; j < n; j++) {
        // don't count this.
        if (i == j) {
          continue;
        }

        V v_j = vertices.get(j);

        GraphPath<V, E> path = getShortestPathImpl(v_i, v_j);

        // we got a path
        if (path != null) {
          sps.put(new VertexPair<V>(v_i, v_j), path);
          nShortestPaths++;
        }
      }
    }

    this.paths = sps;
  }
  /** 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;
          }
        }
      }
    }
  }
 private void shortestPathRecur(List<E> edges, int v_a, int v_b) {
   int k = backtrace[v_a][v_b];
   if (k == -1) {
     E edge = graph.getEdge(vertices.get(v_a), vertices.get(v_b));
     if (edge != null) {
       edges.add(edge);
     }
   } else {
     shortestPathRecur(edges, v_a, k);
     shortestPathRecur(edges, k, v_b);
   }
 }
示例#6
0
    /** {@inheritDoc} */
    protected V provideNextVertex() {
      V v = super.provideNextVertex();

      // backtrack
      for (int i = path.size() - 1; i >= 0; --i) {
        if (graph.containsEdge(path.get(i), v)) {
          break;
        }

        path.remove(i);
      }

      path.add(v);

      return v;
    }
示例#7
0
  /**
   * This method will return a list of vertices which represents the Eulerian circuit of the graph.
   *
   * @param g The graph to find an Eulerian circuit
   * @return null if no Eulerian circuit exists, or a list of vertices representing the Eulerian
   *     circuit if one does exist
   */
  public static <V, E> List<V> getEulerianCircuitVertices(UndirectedGraph<V, E> g) {
    // If the graph is not Eulerian then just return a null since no
    // Eulerian circuit exists
    if (!isEulerian(g)) {
      return null;
    }

    // The circuit will be represented by a linked list
    List<V> path = new LinkedList<V>();
    UndirectedGraph<V, E> sg = new UndirectedSubgraph<V, E>(g, null, null);
    path.add(sg.vertexSet().iterator().next());

    // Algorithm for finding an Eulerian circuit Basically this will find an
    // arbitrary circuit, then it will find another arbitrary circuit until
    // every edge has been traversed
    while (sg.edgeSet().size() > 0) {
      V v = null;

      // Find a vertex which has an edge that hasn't been traversed yet,
      // and keep its index position in the circuit list
      int index = 0;
      for (Iterator<V> iter = path.iterator(); iter.hasNext(); index++) {
        v = iter.next();
        if (sg.degreeOf(v) > 0) {
          break;
        }
      }

      // Finds an arbitrary circuit of the current vertex and
      // appends this into the circuit list
      while (sg.degreeOf(v) > 0) {
        for (Iterator<V> iter = sg.vertexSet().iterator(); iter.hasNext(); ) {
          V temp = iter.next();
          if (sg.containsEdge(v, temp)) {
            path.add(index, temp);
            sg.removeEdge(v, temp);
            v = temp;
            break;
          }
        }
      }
    }
    return path;
  }
  /**
   * Compute the unique decomposition of the input graph G (atoms of G). Implementation of algorithm
   * Atoms as described in Berry et al. (2010), DOI:10.3390/a3020197, <a
   * href="http://www.mdpi.com/1999-4893/3/2/197">http://www.mdpi.com/1999-4893/3/2/197</a>
   */
  private void computeAtoms() {
    if (chordalGraph == null) {
      computeMinimalTriangulation();
    }

    separators = new HashSet<>();

    // initialize g' as subgraph of graph (same vertices and edges)
    UndirectedGraph<V, E> gprime = copyAsSimpleGraph(graph);

    // initialize h' as subgraph of chordalGraph (same vertices and edges)
    UndirectedGraph<V, E> hprime = copyAsSimpleGraph(chordalGraph);

    atoms = new HashSet<>();

    Iterator<V> iterator = meo.descendingIterator();
    while (iterator.hasNext()) {
      V v = iterator.next();
      if (generators.contains(v)) {
        Set<V> separator = new HashSet<>(Graphs.neighborListOf(hprime, v));

        if (isClique(graph, separator)) {
          if (separator.size() > 0) {
            if (separators.contains(separator)) {
              fullComponentCount.put(separator, fullComponentCount.get(separator) + 1);
            } else {
              fullComponentCount.put(separator, 2);
              separators.add(separator);
            }
          }
          UndirectedGraph<V, E> tmpGraph = copyAsSimpleGraph(gprime);

          tmpGraph.removeAllVertices(separator);
          ConnectivityInspector<V, E> con = new ConnectivityInspector<>(tmpGraph);
          if (con.isGraphConnected()) {
            throw new RuntimeException("separator did not separate the graph");
          }
          for (Set<V> component : con.connectedSets()) {
            if (component.contains(v)) {
              gprime.removeAllVertices(component);
              component.addAll(separator);
              atoms.add(new HashSet<>(component));
              assert (component.size() > 0);
              break;
            }
          }
        }
      }

      hprime.removeVertex(v);
    }

    if (gprime.vertexSet().size() > 0) {
      atoms.add(new HashSet<>(gprime.vertexSet()));
    }
  }
  private GraphPath<V, E> getShortestPathImpl(V a, V b) {
    int v_a = vertices.indexOf(a);
    int v_b = vertices.indexOf(b);

    List<E> edges = new ArrayList<E>();
    shortestPathRecur(edges, v_a, v_b);

    // no path, return null
    if (edges.size() < 1) {
      return null;
    }

    double weight = 0.;
    for (E e : edges) {
      weight += graph.getEdgeWeight(e);
    }

    GraphPathImpl<V, E> path = new GraphPathImpl<V, E>(graph, a, b, edges, weight);

    return path;
  }
示例#10
0
  public Set<JavaClass> findClasses(Collection<File> changedFiles) {
    // First update class index
    List<String> changedClassesNames = new ArrayList<String>();
    for (File changedFile : changedFiles) {
      String changedClassname = builder.classFileChanged(changedFile);
      if (changedClassname != null) {
        changedClassesNames.add(changedClassname);
      }
    }

    // Then find dependencies
    Set<JavaClass> changedClasses = newHashSet();
    for (String changedClassesName : changedClassesNames) {
      JavaClass javaClass = builder.getClass(changedClassesName);
      if (javaClass != null) {
        addToIndex(javaClass);
        changedClasses.add(javaClass);
      }
    }
    builder.clear();
    return changedClasses;
  }
  /**
   * @return the diameter (longest of all the shortest paths) computed for the graph. If the graph
   *     is vertexless, return 0.0.
   */
  public double getDiameter() {
    lazyCalculateMatrix();

    if (Double.isNaN(diameter)) {
      diameter = 0.0;
      int n = vertices.size();
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
          if (!Double.isInfinite(d[i][j]) && d[i][j] > diameter) {
            diameter = d[i][j];
          }
        }
      }
    }
    return diameter;
  }
示例#12
0
  public void testNonSimplePath() {
    List<Integer> vertexList = Arrays.asList(0, 1, 2, 3, 2, 3, 4);
    List<DefaultEdge> edgeList = new ArrayList<>();
    for (int i = 0; i < vertexList.size() - 1; i++)
      edgeList.add(completeGraph.getEdge(vertexList.get(i), vertexList.get(i + 1)));
    GraphPath<Integer, DefaultEdge> p1 = new GraphWalk<>(completeGraph, 0, 4, edgeList, 10);
    assertEquals(0, p1.getStartVertex().intValue());
    assertEquals(4, p1.getEndVertex().intValue());
    assertEquals(vertexList, p1.getVertexList());
    assertEquals(edgeList.size(), p1.getLength());
    assertEquals(10.0, p1.getWeight());

    GraphPath<Integer, DefaultEdge> p2 = new GraphWalk<>(completeGraph, vertexList, 10);
    assertEquals(0, p2.getStartVertex().intValue());
    assertEquals(4, p2.getEndVertex().intValue());
    assertEquals(edgeList, p2.getEdgeList());
    assertEquals(edgeList.size(), p2.getLength());
    assertEquals(10.0, p2.getWeight());
  }
  /**
   * Get the length of a shortest path.
   *
   * @param a first vertex
   * @param b second vertex
   * @return shortest distance between a and b
   */
  public double shortestDistance(V a, V b) {
    lazyCalculateMatrix();

    return d[vertices.indexOf(a)][vertices.indexOf(b)];
  }
  /**
   * Compute the minimal triangulation of the graph. Implementation of Algorithm MCS-M+ as described
   * in Berry et al. (2010), DOI:10.3390/a3020197 <a href="http://www.mdpi.com/1999-4893/3/2/197">
   * http://www.mdpi.com/1999-4893/3/2/197</a>
   */
  private void computeMinimalTriangulation() {
    // initialize chordGraph with same vertices as graph
    chordalGraph = new SimpleGraph<>(graph.getEdgeFactory());
    for (V v : graph.vertexSet()) {
      chordalGraph.addVertex(v);
    }

    // initialize g' as subgraph of graph (same vertices and edges)
    final UndirectedGraph<V, E> gprime = copyAsSimpleGraph(graph);
    int s = -1;
    generators = new ArrayList<>();
    meo = new LinkedList<>();

    final Map<V, Integer> vertexLabels = new HashMap<>();
    for (V v : gprime.vertexSet()) {
      vertexLabels.put(v, 0);
    }
    for (int i = 1, n = graph.vertexSet().size(); i <= n; i++) {
      V v = getMaxLabelVertex(vertexLabels);
      LinkedList<V> Y = new LinkedList<>(Graphs.neighborListOf(gprime, v));

      if (vertexLabels.get(v) <= s) {
        generators.add(v);
      }

      s = vertexLabels.get(v);

      // Mark x reached and all other vertices of gprime unreached
      HashSet<V> reached = new HashSet<>();
      reached.add(v);

      // mark neighborhood of x reached and add to reach(label(y))
      HashMap<Integer, HashSet<V>> reach = new HashMap<>();

      // mark y reached and add y to reach
      for (V y : Y) {
        reached.add(y);
        addToReach(vertexLabels.get(y), y, reach);
      }

      for (int j = 0; j < graph.vertexSet().size(); j++) {
        if (!reach.containsKey(j)) {
          continue;
        }
        while (reach.get(j).size() > 0) {
          // remove a vertex y from reach(j)
          V y = reach.get(j).iterator().next();
          reach.get(j).remove(y);

          for (V z : Graphs.neighborListOf(gprime, y)) {
            if (!reached.contains(z)) {
              reached.add(z);
              if (vertexLabels.get(z) > j) {
                Y.add(z);
                E fillEdge = graph.getEdgeFactory().createEdge(v, z);
                fillEdges.add(fillEdge);
                addToReach(vertexLabels.get(z), z, reach);
              } else {
                addToReach(j, z, reach);
              }
            }
          }
        }
      }

      for (V y : Y) {
        chordalGraph.addEdge(v, y);
        vertexLabels.put(y, vertexLabels.get(y) + 1);
      }

      meo.addLast(v);
      gprime.removeVertex(v);
      vertexLabels.remove(v);
    }
  }
示例#15
0
  /**
   * Reads the geometry and connectivity.
   *
   * @param filename the location of the gjf file
   */
  public GJFfile(String filename) {
    super(filename);

    // read geometry
    String name = "";
    List<Atom> contents = new ArrayList<>();
    SimpleWeightedGraph<Atom, DefaultWeightedEdge> connectivity =
        new SimpleWeightedGraph<>(DefaultWeightedEdge.class);
    int blanks = 0;
    boolean lastBlank = false;
    boolean inGeometryBlock = false;
    for (List<String> line : fileContents) {
      // keep track of how many blanks we have seen
      if (line.size() == 1 && line.get(0).length() == 0) {
        if (lastBlank == false) {
          blanks++;
          lastBlank = true;
        }
        continue;
      } else lastBlank = false;

      // read the metadata
      if (blanks == 1) {
        for (String s : line) {
          String[] fields = s.split("@");
          if (fields.length != 3) continue;
          String identifier = fields[1].toLowerCase();
          String value = fields[2];
          // System.out.println(s);
          // System.out.println(identifier + " : " + value);

          if (identifier.equals("o1")) O1Number = Integer.parseInt(value);
          else if (identifier.equals("o2")) O2Number = Integer.parseInt(value);
          else if (identifier.equals("n3")) N3Number = Integer.parseInt(value);
          else if (identifier.equals("cl1")) Cl1Number = Integer.parseInt(value);
          else if (identifier.equals("su2")) Su2Number = Integer.parseInt(value);
          else if (identifier.equals("ol3")) Ol3Number = Integer.parseInt(value);
          else if (identifier.equals("mem")) mem = Integer.parseInt(value);
          else if (identifier.equals("nprocshared")) nprocshared = Integer.parseInt(value);
          else if (identifier.equals("method")) method = value;
          else if (identifier.equals("basis")) basis = value;
          else System.out.println("unrecognized entry: " + s);
        }

        continue;
      } else if (blanks != 2) continue;

      // deal with the charge and multiplicity card (by ignoring it)
      if (line.size() == 2 && inGeometryBlock == false) {
        inGeometryBlock = true;
        continue;
      }

      if (line.size() != 4 && inGeometryBlock == false)
        throw new IllegalArgumentException(
            "unexpected text in geometry block in " + filename + ":\n" + line.toString());

      // create atom
      // tinker atom types will be nonsense, of course
      Atom newAtom =
          new Atom(
              line.get(0),
              new Vector3D(
                  Double.parseDouble(line.get(1)),
                  Double.parseDouble(line.get(2)),
                  Double.parseDouble(line.get(3))),
              1);
      contents.add(newAtom);
      connectivity.addVertex(newAtom);
    }

    // read connectivity
    blanks = 0;
    lastBlank = false;
    for (List<String> line : fileContents) {
      // read the fourth block of text
      if (line.size() == 1 && line.get(0).length() == 0) {
        if (lastBlank == false) {
          blanks++;
          lastBlank = true;
        }
        continue;
      } else lastBlank = false;

      // only read connectivity lines
      if (blanks != 3) continue;

      Atom fromAtom = contents.get(Integer.parseInt(line.get(0)) - 1);
      for (int i = 1; i < line.size(); i += 2) {
        int toAtomIndex = Integer.parseInt(line.get(i)) - 1;
        Atom toAtom = contents.get(toAtomIndex);
        double bondOrder = Double.parseDouble(line.get(i + 1));
        DefaultWeightedEdge thisEdge = connectivity.addEdge(fromAtom, toAtom);
        connectivity.setEdgeWeight(thisEdge, bondOrder);
      }
    }

    // create the molecule
    molecule = new Molecule(name, contents, connectivity, 0.0);
  }