/** * Scale weights in the graph * * @param g {@link BipartiteGraph} * @param c2 first {@link EdgeArray} * @param c1 second {@link EdgeArray} * @param f value * @return <code>true</code> is none of the edges properties in the two array are equal */ private boolean scaleWeights(final BipartiteGraph g, final EdgeArray c2, EdgeArray c1, double f) { Edge e; double C = 0; Iterator<Edge> edgesIterator = g.getEdgesIterator(); while (edgesIterator.hasNext()) { e = (Edge) edgesIterator.next(); C = Math.max(C, fabs((((Double) c2.getEdgeProperty(e)).doubleValue()))); } double S = computeS(f, C); boolean noScaling = true; edgesIterator = g.getEdgesIterator(); while (edgesIterator.hasNext()) { e = (Edge) edgesIterator.next(); c1.setEdgeProperty( e, new Double(scaleWeight(((Double) c2.getEdgeProperty(e)).doubleValue(), S))); if (((Double) c2.getEdgeProperty(e)).doubleValue() != ((Double) c1.getEdgeProperty(e)).doubleValue()) noScaling = false; } return noScaling; }
/** * Run the algorithm * * @return an {@link EdgesSet} */ public EdgesSet runAlgorithm() { EdgesSet result = new EdgesSet(g.getEdgesSet().getVc()); // for all nodes(v,G) pot[v] = 0; // this will be done by giving pot:= VertexArray(g,new Double(0)) if (g.getEdgesSet().isEmpty()) return new EdgesSet(g.getEdgesSet().getVc()); // check that all edges are directed from A to B // this should be a precondition also VertexArray free = new VertexArray(g, new Boolean(true)); VertexArray pred = new VertexArray(g, null); VertexArray dist = new VertexArray(g, new Double(0)); VertexPQ PQ = new VertexPQ(g); switch (heuristic) { case NAIVE_HEURISTIC: Double C = new Double(0); Iterator<Edge> edgesIterator = g.getEdgesIterator(); while (edgesIterator.hasNext()) { Edge e = edgesIterator.next(); Double edgeC = (Double) c.getEdgeProperty(e); if (edgeC.compareTo(C) == 1) // bigger than... C = edgeC; } Iterator<Vertex> leftVertexesIterator = g.getLeftVertexSetIterator(); while (leftVertexesIterator.hasNext()) { pot.setVertexProperty(leftVertexesIterator.next(), C); } break; case SIMPLE_HEURISTIC: Iterator<Vertex> leftVertexesIterator1 = g.getLeftVertexSetIterator(); while (leftVertexesIterator1.hasNext()) { Vertex a = leftVertexesIterator1.next(); Edge eMax = null; double C_max = 0; Iterator<Edge> vertexAdjEdgesIterator = GraphUtilities.getVertexAdjEdges(g, a).getMembers().iterator(); while (vertexAdjEdgesIterator.hasNext()) { Edge e = vertexAdjEdgesIterator.next(); if (((Double) c.getEdgeProperty(e)).doubleValue() > C_max) { eMax = e; C_max = ((Double) c.getEdgeProperty(e)).doubleValue(); } } pot.setVertexProperty(a, new Double(C_max)); Vertex b; if (eMax != null && ((Boolean) free.getVertexProperty((b = GraphUtilities.getEdgeTargetVertex(g, eMax)))) .booleanValue()) { eMax.turnOverEdgeDirection(); free.setVertexProperty(a, new Boolean(false)); free.setVertexProperty(b, new Boolean(false)); } } break; default: // REFINED_HEURISTIC mwbmHeuristic(g, c, pot, free); break; } Iterator<Vertex> leftVertexesIterator = g.getLeftVertexSetIterator(); while (leftVertexesIterator.hasNext()) { Vertex a = leftVertexesIterator.next(); if (((Boolean) free.getVertexProperty(a)).booleanValue()) augment(g, a, c, pot, free, pred, dist, PQ); } Iterator<Vertex> rightVertexesIterator = g.getRightVertexSetIterator(); while (rightVertexesIterator.hasNext()) { Vertex b = rightVertexesIterator.next(); Iterator<Edge> outEdgesIterator = GraphUtilities.getVertexOutEdges(g, b).getMembers().iterator(); while (outEdgesIterator.hasNext()) { result.addMember(outEdgesIterator.next()); } } result.turnOverEdges(false); return result; }
/** * The maximum weight bipartite matching heuristis * * @param g {@link BipartiteGraph} * @param c an {@link EdgeArray} * @param pot a {@link VertexArray} * @param free free {@link VertexArray} */ private void mwbmHeuristic(BipartiteGraph g, EdgeArray c, VertexArray pot, VertexArray free) { Vertex a, b; Edge e, e2, eb; VertexArray secEdge = new VertexArray(g, null); Iterator<Vertex> leftVertexSetIterator = g.getLeftVertexSetIterator(); while (leftVertexSetIterator.hasNext()) { a = (Vertex) leftVertexSetIterator.next(); double max2 = 0, max = 0; eb = null; e2 = null; // compute edges with largest and second largest slack Iterator<Edge> aAdjEdgesIterator = GraphUtilities.getVertexAdjEdges(g, a).getMembers().iterator(); while (aAdjEdgesIterator.hasNext()) { e = (Edge) aAdjEdgesIterator.next(); double we = ((Double) c.getEdgeProperty(e)).doubleValue() - ((Double) pot.getVertexProperty(GraphUtilities.getEdgeTargetVertex(g, e))) .doubleValue(); if (we >= max2) { if (we >= max) { max2 = max; e2 = eb; max = we; eb = e; } else { max2 = we; e2 = e; } } } if (eb != null) { b = GraphUtilities.getEdgeTargetVertex(g, eb); if (((Boolean) free.getVertexProperty(b)).booleanValue()) { // match eb and change pot[] to make slack of e2 zero secEdge.setVertexProperty(a, e2); pot.setVertexProperty(a, new Double(max2)); pot.setVertexProperty(b, new Double(max - max2)); eb.turnOverEdgeDirection(); free.setVertexProperty(a, new Boolean(false)); free.setVertexProperty(b, new Boolean(false)); } else { // try to augment matching along // path of length 3 given by sec_edge[] pot.setVertexProperty(a, new Double(max)); e2 = GraphUtilities.getVertexFirstAdjEdge(g, b); e = (Edge) secEdge.getVertexProperty(GraphUtilities.getEdgeTargetVertex(g, e2)); if (e != null && GraphUtilities.getVertexOutDeg(g, GraphUtilities.getEdgeTargetVertex(g, e)) == 0) { free.setVertexProperty(a, new Boolean(false)); free.setVertexProperty(GraphUtilities.getEdgeTargetVertex(g, e), new Boolean(false)); e.turnOverEdgeDirection(); e2.turnOverEdgeDirection(); eb.turnOverEdgeDirection(); } } } else { pot.setVertexProperty(a, new Double(0)); } } }