/** {@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; }
/** * @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); } }
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()); }
/** 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; } } } } }
/** {@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; }
/** * @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; }
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; }
/** * 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); }