/* $RCSfile$ * $Author$ * $Date$ * $Revision$ * * Copyright (C) 2004-2009 Ulrich Bauer <ulrich.bauer@alumni.tum.de> * * Contact: cdk-devel@lists.sourceforge.net * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * All we ask is that proper credit is given for our work, which includes * - but is not limited to - adding the above copyright notice to the beginning * of your source code files, and to any copyright notice that you may distribute * with programs based on this work. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * */ package org.openscience.cdk.ringsearch.cyclebasis; import org._3pq.jgrapht.DirectedGraph; import org._3pq.jgrapht.Edge; import org._3pq.jgrapht.Graph; import org._3pq.jgrapht.UndirectedGraph; import org._3pq.jgrapht.alg.ConnectivityInspector; import org._3pq.jgrapht.graph.SimpleDirectedGraph; import org._3pq.jgrapht.graph.SimpleGraph; import org._3pq.jgrapht.graph.Subgraph; import org.openscience.cdk.graph.BFSShortestPath; import org.openscience.cdk.graph.MinimalPathIterator; import java.util.*; /** * Auxiliary class for <code>CycleBasis</code>. * * @author Ulrich Bauer <ulrich.bauer@alumni.tum.de> * * * @cdk.module standard * @cdk.githash * * @cdk.builddepends jgrapht-0.5.3.jar * @cdk.depends jgrapht-0.5.3.jar */ public class SimpleCycleBasis { private List edgeList; private List cycles; private UndirectedGraph graph; private boolean isMinimized = false; private HashMap edgeIndexMap; public SimpleCycleBasis (List cycles, List edgeList, UndirectedGraph graph) { this.edgeList = edgeList; this.cycles = cycles; this.graph = graph; edgeIndexMap = createEdgeIndexMap(edgeList); } public SimpleCycleBasis (UndirectedGraph graph) { this.cycles = new ArrayList(); this.edgeList = new ArrayList(); this.graph = graph; createMinimumCycleBasis(); } private void createMinimumCycleBasis() { Graph subgraph = new Subgraph(graph, null, null); Set remainingEdges = new HashSet(graph.edgeSet()); Set selectedEdges = new HashSet(); while (!remainingEdges.isEmpty()) { Edge edge = (Edge)remainingEdges.iterator().next(); subgraph.removeEdge(edge); // Compute a shortest cycle through edge List path = BFSShortestPath.findPathBetween(subgraph, edge.getSource(), edge.getTarget()); path.add(edge); SimpleCycle cycle = new SimpleCycle(graph, path); subgraph.addEdge(edge); selectedEdges.add(edge); cycles.add(0, cycle); edgeList.add(0, edge); remainingEdges.removeAll(path); } subgraph.removeAllEdges(selectedEdges); // The cycles just created are already minimal, so we can start minimizing at startIndex int startIndex = cycles.size(); // Now we perform a breadth first traversal and build a fundamental tree base // ("Kirchhoff base") of the remaining subgraph Object currentVertex = graph.vertexSet().iterator().next(); // We build a spanning tree as a directed graph to easily find the parent of a // vertex in the tree. This means however that we have to create new Edge objects // for the tree and can't just use the Edge objects of the graph, since the // the edge in the graph might have a wrong or no direction. Graph spanningTree = new Subgraph(graph, new HashSet(), new HashSet()); Set visitedEdges = new HashSet(); // FIFO for the BFS LinkedList vertexQueue = new LinkedList(); // currentVertex is the root of the spanning tree spanningTree.addVertex(currentVertex); vertexQueue.addLast(currentVertex); // We need to remember the tree edges so we can add them at once to the // index list for the incidence matrix List treeEdges = new Vector(); while (!vertexQueue.isEmpty()) { currentVertex = vertexQueue.removeFirst(); Iterator edges = subgraph.edgesOf(currentVertex).iterator(); while (edges.hasNext()) { // find a neighbour vertex of the current vertex Edge edge = (Edge)edges.next(); if (!visitedEdges.contains(edge)) { // mark edge as visited visitedEdges.add(edge); Object nextVertex = edge.oppositeVertex(currentVertex); if (!spanningTree.containsVertex(nextVertex)) { // tree edge treeEdges.add(edge); spanningTree.addVertex(nextVertex); // create a new (directed) Edge object (as explained above) spanningTree.addEdge(currentVertex, nextVertex); // add the next vertex to the BFS-FIFO vertexQueue.addLast(nextVertex); } else { // non-tree edge // This edge defines a cycle together with the edges of the spanning tree // along the path to the root of the tree. We create a new cycle containing // these edges (not the tree edges, but the corresponding edges in the graph) List edgesOfCycle = BFSShortestPath.findPathBetween(spanningTree, edge.getSource(), edge.getTarget()); // add the non-tree edge to the path edgesOfCycle.add(edge); // add the edge to the index list for the incidence matrix edgeList.add(edge); SimpleCycle newCycle = new SimpleCycle(graph, edgesOfCycle); cycles.add(newCycle); } } } } // Add all the tree edges to the index list for the incidence matrix edgeList.addAll(treeEdges); edgeIndexMap = createEdgeIndexMap(edgeList); // Now the index list is ordered: first the non-tree edges, then the tree edge. // Moreover, since the cycles and the corresponding non-tree edge have been added // to their lists in the same order, the incidence matrix is in upper triangular form. // Now we can minimize the cycles created from the tree base minimize(startIndex); } boolean[][] getCycleEdgeIncidenceMatrix () { return getCycleEdgeIncidenceMatrix((Object[]) cycles.toArray()); } boolean[][] getCycleEdgeIncidenceMatrix (Object[] cycleArray) { boolean[][] result = new boolean[cycleArray.length][edgeList.size()]; for (int i=0; i<cycleArray.length; i++) { SimpleCycle cycle = (SimpleCycle) cycleArray[i]; for (int j=0; j<edgeList.size(); j++) { Edge edge = (Edge)edgeList.get(j); result[i][j] = cycle.containsEdge(edge); } } return result; } // private void minimize() { // // if (isMinimized) // return; // // if (cycles.size()==0) // return; // else // minimize(0); // // isMinimized = true; // } private void minimize(int startIndex) { if (isMinimized) return; // Implementation of "Algorithm 1" from [BGdV04] boolean[][] a = getCycleEdgeIncidenceMatrix(); for (int i=startIndex; i<cycles.size(); i++) { // "Subroutine 2" // Construct kernel vector u boolean[] u = constructKernelVector(edgeList.size(), a, i); // Construct auxiliary graph gu AuxiliaryGraph gu = new AuxiliaryGraph(graph, u); SimpleCycle shortestCycle = (SimpleCycle) cycles.get(i); Iterator vertexIterator = graph.vertexSet().iterator(); while (vertexIterator.hasNext()) { Object vertex = vertexIterator.next(); // check if the vertex is incident to an edge with u[edge] == 1 boolean shouldSearchCycle = false; Collection incidentEdges = graph.edgesOf(vertex); Iterator edgeIterator = incidentEdges.iterator(); while (edgeIterator.hasNext()) { Edge edge = (Edge) edgeIterator.next(); int index = getEdgeIndex(edge); if (u[index]) { shouldSearchCycle = true; break; } } if (shouldSearchCycle) { Object auxVertex0 = gu.auxVertex0(vertex); Object auxVertex1 = gu.auxVertex1(vertex); // Search for shortest path List auxPath = BFSShortestPath.findPathBetween(gu, auxVertex0, auxVertex1); List edgesOfNewCycle = new Vector(); Object v = vertex; edgeIterator = auxPath.iterator(); while (edgeIterator.hasNext()) { Edge auxEdge = (Edge) edgeIterator.next(); // Get the edge corresponding to the aux. edge Edge e = (Edge) gu.edge(auxEdge); if (edgesOfNewCycle.contains(e)) { edgesOfNewCycle.remove(e); } else { edgesOfNewCycle.add(e); } // Get next vertex on path v = e.oppositeVertex(v); } SimpleCycle newCycle = new SimpleCycle(graph, edgesOfNewCycle); if (newCycle.weight() < shortestCycle.weight()) { shortestCycle = newCycle; } } } cycles.set(i, shortestCycle); // insert the new cycle into the matrix for (int j=0; j<edgeList.size(); j++) { a[i][j] = shortestCycle.containsEdge((Edge) edgeList.get(j)); } // perform gaussian elimination on the inserted row for (int j=0; j<i; j++) { if (a[i][j]) { for (int k=0; k<edgeList.size(); k++) { a[i][k] = (a[i][k]!=a[j][k]); } } } } isMinimized = true; //System.out.println("after minimization:"); //printIncidenceMatrix(); } static boolean[] constructKernelVector(int size, boolean[][] a, int i) { // Construct kernel vector u by setting u[i] = true ... boolean[] u = new boolean[size]; u[i] = true; // ... u[j] = 0 (false) for j > i (by initialization)... // ... and solving A u = 0 for (int j=i-1; j>=0; j--) { u[j] = false; for (int k=i; k>j; k--) { u[j] = (u[j] != (a[j][k] && u[k])); } } return u; } public int[] weightVector() { int[] result = new int[cycles.size()]; for (int i=0; i<cycles.size(); i++) { SimpleCycle cycle = (SimpleCycle) cycles.get(i); result[i] = (int) cycle.weight(); } Arrays.sort(result); return result; } public List edges() { return edgeList; } public List cycles() { return cycles; } static boolean[][] inverseBinaryMatrix(boolean[][] m, int n) { boolean[][] a = new boolean[n][n]; for (int i=0; i<n; i++) { for (int j=0; j<n; j++) { a[i][j] = m[i][j]; } } boolean[][] r = new boolean[n][n]; for (int i=0; i<n; i++) { r[i][i] = true; } for (int i=0; i<n; i++) { for (int j=i; j<n; j++) { if (a[j][i]) { for (int k=0; k<n; k++) { if ((k!=j) && (a[k][i])) { for (int l=0; l<n; l++) { a[k][l] = (a[k][l] != a[j][l]); r[k][l] = (r[k][l] != r[j][l]); } } } if (i!=j) { boolean[] swap = a[i]; a[i] = a[j]; a[j] = swap; swap = r[i]; r[i] = r[j]; r[j] = swap; } break; } } } return r; } public Collection essentialCycles() { Collection result = new HashSet(); boolean[][] a = getCycleEdgeIncidenceMatrix(); boolean[][] ai = inverseBinaryMatrix(a, cycles.size()); for (int i=0; i<cycles.size(); i++) { // Construct kernel vector u boolean[] u = new boolean[edgeList.size()]; for (int j=0; j<cycles.size(); j++) { u[j] = ai[j][i]; } // Construct kernel vector u from a column of the inverse of a AuxiliaryGraph gu = new AuxiliaryGraph(graph, u); boolean isEssential = true; Iterator vertexIterator = graph.vertexSet().iterator(); while (isEssential && vertexIterator.hasNext()) { Object vertex = vertexIterator.next(); Collection incidentEdges = graph.edgesOf(vertex); // check if the vertex is incident to an edge with u[edge] == 1 boolean shouldSearchCycle = false; for (Iterator it = incidentEdges.iterator(); it.hasNext();) { Edge edge = (Edge) it.next(); int index = getEdgeIndex(edge); if (u[index]) { shouldSearchCycle = true; break; } } if (shouldSearchCycle) { Object auxVertex0 = gu.auxVertex0(vertex); Object auxVertex1 = gu.auxVertex1(vertex); // Search for shortest paths for (Iterator minPaths = new MinimalPathIterator(gu, auxVertex0, auxVertex1); minPaths.hasNext();) { List auxPath = (List) minPaths.next(); List edgesOfNewCycle = new ArrayList(auxPath.size()); for (Iterator it = auxPath.iterator(); it.hasNext();) { Edge auxEdge = (Edge) it.next(); // Get the edge corresponding to the aux. edge Edge e = (Edge) gu.edge(auxEdge); if (edgesOfNewCycle.contains(e)) { edgesOfNewCycle.remove(e); } else { edgesOfNewCycle.add(e); } } SimpleCycle cycle = new SimpleCycle(graph, edgesOfNewCycle); if (cycle.weight() > ((SimpleCycle)cycles.get(i)).weight()) { break; } if (!cycle.equals((SimpleCycle)cycles.get(i))) { isEssential = false; break; } } } } if (isEssential) { result.add((SimpleCycle)cycles.get(i)); } } return result; } public Map relevantCycles() { Map result = new HashMap(); boolean[][] a = getCycleEdgeIncidenceMatrix(); boolean[][] ai = inverseBinaryMatrix(a, cycles.size()); for (int i=0; i<cycles.size(); i++) { // Construct kernel vector u from a column of the inverse of a boolean[] u = new boolean[edgeList.size()]; for (int j=0; j<cycles.size(); j++) { u[j] = ai[j][i]; } // Construct auxiliary graph gu AuxiliaryGraph gu = new AuxiliaryGraph(graph, u); Iterator vertexIterator = graph.vertexSet().iterator(); while (vertexIterator.hasNext()) { Object vertex = vertexIterator.next(); Collection incidentEdges = graph.edgesOf(vertex); // check if the vertex is incident to an edge with u[edge] == 1 boolean shouldSearchCycle = false; for (Iterator it = incidentEdges.iterator(); it.hasNext();) { Edge edge = (Edge) it.next(); int index = getEdgeIndex(edge); if (u[index]) { shouldSearchCycle = true; break; } } if (shouldSearchCycle) { Object auxVertex0 = gu.auxVertex0(vertex); Object auxVertex1 = gu.auxVertex1(vertex); // Search for shortest paths for (Iterator minPaths = new MinimalPathIterator(gu, auxVertex0, auxVertex1); minPaths.hasNext();) { List auxPath = (List) minPaths.next(); List edgesOfNewCycle = new ArrayList(auxPath.size()); Iterator edgeIterator = auxPath.iterator(); while (edgeIterator.hasNext()) { Edge auxEdge = (Edge) edgeIterator.next(); // Get the edge corresponding to the aux. edge Edge e = (Edge) gu.edge(auxEdge); if (edgesOfNewCycle.contains(e)) { edgesOfNewCycle.remove(e); } else { edgesOfNewCycle.add(e); } } SimpleCycle cycle = new SimpleCycle(graph, edgesOfNewCycle); if (cycle.weight() > ((SimpleCycle)cycles.get(i)).weight()) { break; } result.put(cycle, (SimpleCycle)cycles.get(i)); } } } } return result; } public List equivalenceClasses() { int[] weight = weightVector(); Object[] cyclesArray = (Object[]) cycles.toArray(); Arrays.sort(cyclesArray, new Comparator() { public int compare(Object o1, Object o2) { return (int) (((SimpleCycle)o1).weight() - ((SimpleCycle)o2).weight()); } }); Collection essentialCycles = essentialCycles(); boolean[][] u = new boolean[cyclesArray.length][edgeList.size()]; boolean[][] a = getCycleEdgeIncidenceMatrix(cyclesArray); boolean[][] ai = inverseBinaryMatrix(a, cyclesArray.length); for (int i=0; i<cyclesArray.length; i++) { for (int j=0; j<cyclesArray.length; j++) { u[i][j] = ai[j][i]; } } UndirectedGraph h = new SimpleGraph(); h.addAllVertices(cycles); ConnectivityInspector connectivityInspector = new ConnectivityInspector(h); int left=0; for (int right=0; right<weight.length; right++) { if ((right<weight.length-1) && (weight[right+1]==weight[right])) continue; // cyclesArray[left] to cyclesArray[right] have same weight // First test (compute pre-classes): // Check if there is a cycle that can replace a[i] as well as a[j] in a basis // This is done by finding a cycle C with <C,u[i]>=1 and <C,u[j]>=1 for (int i=left; i<=right; i++) { if (essentialCycles.contains((SimpleCycle) cyclesArray[i])) continue; for (int j=i+1; j<=right; j++) { if (essentialCycles.contains((SimpleCycle) cyclesArray[j])) continue; // check if cyclesArray[i] and cyclesArray[j] are already in the same class if (connectivityInspector.pathExists(cyclesArray[i], cyclesArray[j])) continue; boolean sameClass = false; AuxiliaryGraph2 auxGraph = new AuxiliaryGraph2(graph, edgeList, u[i], u[j]); for (Iterator it = graph.vertexSet().iterator(); it.hasNext();) { Object vertex = it.next(); // check if the vertex is incident to an edge with u[edge] == 1 boolean shouldSearchCycle = false; Collection incidentEdges = graph.edgesOf(vertex); Iterator edgeIterator = incidentEdges.iterator(); while (edgeIterator.hasNext()) { Edge edge = (Edge) edgeIterator.next(); int index = getEdgeIndex(edge); if (u[i][index] || u[j][index]) { shouldSearchCycle = true; break; } } if (shouldSearchCycle) { Object auxVertex00 = auxGraph.auxVertex00(vertex); Object auxVertex11 = auxGraph.auxVertex11(vertex); List auxPath = BFSShortestPath.findPathBetween(auxGraph, auxVertex00, auxVertex11); double pathWeight = auxPath.size(); if (pathWeight == weight[left]) { sameClass = true; break; } } } if (sameClass) { h.addEdge(cyclesArray[i], cyclesArray[j]); } } } // Second test (compute equivalence classes): // Check if there are two cycle Ci, Cj that can replace a[i], a[j] // and have a common cycle a[k] in their basis representation // This is done by finding a cycle a[k] with <u[k],u[i]>=1 and <u[k],u[j]>=1 for (int i=left; i<=right; i++) { if (essentialCycles.contains((SimpleCycle) cyclesArray[i])) continue; for (int j=i+1; j<=right; j++) { if (essentialCycles.contains((SimpleCycle) cyclesArray[j])) continue; // check if cyclesArray[i] and cyclesArray[j] are already in the same class if (connectivityInspector.pathExists(cyclesArray[i], cyclesArray[j])) continue; boolean sameClass = false; for (int k=0; ((SimpleCycle)cyclesArray[k]).weight() < weight[left]; k++) { AuxiliaryGraph2 auxGraph = new AuxiliaryGraph2(graph, edgeList, u[i], u[k]); boolean shortestPathFound = false; for (Iterator it = graph.vertexSet().iterator(); it.hasNext();) { Object vertex = it.next(); Object auxVertex00 = auxGraph.auxVertex00(vertex); Object auxVertex11 = auxGraph.auxVertex11(vertex); List auxPath = BFSShortestPath.findPathBetween(auxGraph, auxVertex00, auxVertex11); double pathWeight = auxPath.size(); if (pathWeight == weight[left]) { shortestPathFound = true; break; } } if (!shortestPathFound) continue; auxGraph = new AuxiliaryGraph2(graph, edgeList, u[j], u[k]); for (Iterator it = graph.vertexSet().iterator(); it.hasNext();) { Object vertex = it.next(); Object auxVertex00 = auxGraph.auxVertex00(vertex); Object auxVertex11 = auxGraph.auxVertex11(vertex); List auxPath = BFSShortestPath.findPathBetween(auxGraph, auxVertex00, auxVertex11); double pathWeight = auxPath.size(); if (pathWeight == weight[left]) { sameClass = true; break; } } if (sameClass) break; } if (sameClass) { h.addEdge(cyclesArray[i], cyclesArray[j]); } } } left=right+1; } return connectivityInspector.connectedSets(); } private HashMap createEdgeIndexMap(List edgeList) { HashMap map = new HashMap(); for (int i=0; i<edgeList.size(); i++) { map.put(edgeList.get(i), Integer.valueOf(i)); } return map; } private int getEdgeIndex(Edge edge) { return ((Integer) edgeIndexMap.get(edge)).intValue(); } private class AuxiliaryGraph extends SimpleGraph { private static final long serialVersionUID = 857337988734567429L; // graph to aux. graph HashMap vertexMap0 = new HashMap(); HashMap vertexMap1 = new HashMap(); HashMap auxVertexMap = new HashMap(); // aux. edge to edge Map auxEdgeMap = new HashMap(); Graph g; boolean[] u; AuxiliaryGraph(Graph graph, boolean[] u) { g = graph; this.u = u; } public List edgesOf( Object auxVertex ) { Object vertex = auxVertexMap.get(auxVertex); for (Iterator edgeIterator = g.edgesOf(vertex).iterator(); edgeIterator.hasNext();) { Edge edge = (Edge) edgeIterator.next(); int j = getEdgeIndex(edge); Object vertex1 = edge.getSource(); Object vertex2 = edge.getTarget(); if (u[j]) { Object vertex1u = auxVertex0(vertex1); Object vertex2u = auxVertex1(vertex2); Edge auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); vertex1u = auxVertex1(vertex1); vertex2u = auxVertex0(vertex2); auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); } else { Object vertex1u = auxVertex0(vertex1); Object vertex2u = auxVertex0(vertex2); Edge auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); vertex1u = auxVertex1(vertex1); vertex2u = auxVertex1(vertex2); auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); } } return super.edgesOf(auxVertex); } Object auxVertex0(Object vertex) { if (vertexMap0.get(vertex) == null) { Object newVertex0 = vertex + "-0"; vertexMap0.put(vertex, newVertex0); addVertex(newVertex0); auxVertexMap.put(newVertex0, vertex); return newVertex0; } return vertexMap0.get(vertex); } Object auxVertex1(Object vertex) { if (vertexMap1.get(vertex) == null) { Object newVertex1 = vertex + "-1"; vertexMap1.put(vertex, newVertex1); addVertex(newVertex1); auxVertexMap.put(newVertex1, vertex); return newVertex1; } return vertexMap1.get(vertex); } Object edge(Object auxEdge) { return auxEdgeMap.get(auxEdge); } } private class AuxiliaryGraph2 extends SimpleGraph { private static final long serialVersionUID = 5930876716644738726L; // graph to aux. graph private HashMap vertexMap00 = new HashMap(); private HashMap vertexMap01 = new HashMap(); private HashMap vertexMap10 = new HashMap(); private HashMap vertexMap11 = new HashMap(); private HashMap auxVertexMap = new HashMap(); // aux. edge to edge private Map auxEdgeMap = new HashMap(); private Graph g; private boolean[] ui; private boolean[] uj; AuxiliaryGraph2(Graph graph, List edgeList, boolean[] ui, boolean[] uj) { g = graph; this.ui = ui; this.uj = uj; } Object auxVertex00(Object vertex) { if (vertexMap00.get(vertex) == null) { Object newVertex = vertex + "-00"; vertexMap00.put(vertex, newVertex); addVertex(newVertex); auxVertexMap.put(newVertex, vertex); return newVertex; } return vertexMap00.get(vertex); } Object auxVertex01(Object vertex) { if (vertexMap01.get(vertex) == null) { Object newVertex = vertex + "-01"; vertexMap01.put(vertex, newVertex); addVertex(newVertex); auxVertexMap.put(newVertex, vertex); return newVertex; } return vertexMap01.get(vertex); } Object auxVertex10(Object vertex) { if (vertexMap10.get(vertex) == null) { Object newVertex = vertex + "-10"; vertexMap10.put(vertex, newVertex); addVertex(newVertex); auxVertexMap.put(newVertex, vertex); return newVertex; } return vertexMap10.get(vertex); } Object auxVertex11(Object vertex) { if (vertexMap11.get(vertex) == null) { Object newVertex = vertex + "-11"; vertexMap11.put(vertex, newVertex); addVertex(newVertex); auxVertexMap.put(newVertex, vertex); return newVertex; } return vertexMap11.get(vertex); } public List edgesOf( Object auxVertex ) { Object vertex = auxVertexMap.get(auxVertex); for (Iterator edgeIterator = g.edgesOf(vertex).iterator(); edgeIterator.hasNext();) { Edge edge = (Edge) edgeIterator.next(); int k = getEdgeIndex(edge); Object vertex1 = edge.getSource(); Object vertex2 = edge.getTarget(); if (!ui[k] && !uj[k]) { Object vertex1u = auxVertex00(vertex1); Object vertex2u = auxVertex00(vertex2); Edge auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); vertex1u = auxVertex01(vertex1); vertex2u = auxVertex01(vertex2); auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); vertex1u = auxVertex10(vertex1); vertex2u = auxVertex10(vertex2); auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); vertex1u = auxVertex11(vertex1); vertex2u = auxVertex11(vertex2); auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); } else if (ui[k] && !uj[k]) { Object vertex1u = auxVertex00(vertex1); Object vertex2u = auxVertex10(vertex2); Edge auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); vertex1u = auxVertex01(vertex1); vertex2u = auxVertex11(vertex2); auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); vertex1u = auxVertex10(vertex1); vertex2u = auxVertex00(vertex2); auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); vertex1u = auxVertex11(vertex1); vertex2u = auxVertex01(vertex2); auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); } else if (!ui[k] && uj[k]) { Object vertex1u = auxVertex00(vertex1); Object vertex2u = auxVertex01(vertex2); Edge auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); vertex1u = auxVertex01(vertex1); vertex2u = auxVertex00(vertex2); auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); vertex1u = auxVertex10(vertex1); vertex2u = auxVertex11(vertex2); auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); vertex1u = auxVertex11(vertex1); vertex2u = auxVertex10(vertex2); auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); } else if (ui[k] && uj[k]) { Object vertex1u = auxVertex00(vertex1); Object vertex2u = auxVertex11(vertex2); Edge auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); vertex1u = auxVertex01(vertex1); vertex2u = auxVertex10(vertex2); auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); vertex1u = auxVertex10(vertex1); vertex2u = auxVertex01(vertex2); auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); vertex1u = auxVertex11(vertex1); vertex2u = auxVertex00(vertex2); auxEdge = addEdge(vertex1u, vertex2u); auxEdgeMap.put(auxEdge, edge); } } return super.edgesOf(auxVertex); } } public void printIncidenceMatrix() { /* for (int j=0; j<edgeList.size(); j++) { System.out.print(((Edge) edgeList.get(j)).getSource()); } System.out.println(); for (int j=0; j<edgeList.size(); j++) { System.out.print(((Edge) edgeList.get(j)).getTarget()); } System.out.println(); for (int j=0; j<edgeList.size(); j++) { System.out.print('-'); } System.out.println(); */ boolean[][] incidMatr = getCycleEdgeIncidenceMatrix(); for (int i=0; i<incidMatr.length; i++) { for (int j=0; j<incidMatr[i].length; j++) { System.out.print(incidMatr[i][j]?1:0); } System.out.println(); } } }