private void relabel(Vertex u) { // System.out.println("Relabeling " + u); assert (u.getExcess() > 0) : "u not overflowing"; List<Vertex> neighbors = u.getNeighbors(); int minHeight = Integer.MAX_VALUE; for (Vertex v : neighbors) { int residCapacity = getResidualCapacity(u, v); assert (residCapacity == 0 || u.getHeight() <= v.getHeight()); if (residCapacity > 0) { int partnerHeight = v.getHeight(); minHeight = partnerHeight < minHeight ? partnerHeight : minHeight; } } u.setHeight(1 + minHeight); }
private void discharge(Vertex u) { // System.out.println("Discharging " + u); while (u.getExcess() > 0) { if (u.getCurrNeighbor() >= u.getNumNeighbors()) { relabel(u); u.setCurrNeighbor(0); } else { Vertex v = u.getNeighbor(u.getCurrNeighbor()); if (getResidualCapacity(u, v) > 0 && u.getHeight() == v.getHeight() + 1) { push(u, v); } else { u.incNextNeighbor(); } } } }
// Push-relabel methods // Push() pushes flow forwards, or decreases incoming flow private void push(Vertex u, Vertex v) { // System.out.println("Pushing from " + u + " to " + v); int excess = u.getExcess(); int residualCapacity = getResidualCapacity(u, v); assert (excess > 0) : "Excess <= 0"; assert (residualCapacity > 0) : "Resid capacity <= 0"; assert (u.getHeight() == v.getHeight() + 1) : "Height of u != height of v + 1"; int changeInFlow = excess < residualCapacity ? excess : residualCapacity; if (flowsForward(u, v)) { addToFlow(u, v, changeInFlow); } else { addToFlow(v, u, -changeInFlow); } u.addToExcess(-changeInFlow); v.addToExcess(changeInFlow); }
private void setupSourceSide(Set<Employee> emps) { for (Employee e : emps) { Vertex u = Vertex.vertexFromEmployee(e); LV.add(u); source.addToNeighbors(u); u.addToNeighbors(source); setCapacity(source, u, 1); setFlow(source, u, 1); u.setExcess(1); // Prioritize friend for initial flow if (e.getId() == ProjectParams.FRIEND_ID) { V.addFirst(u); } else { V.add(u); } } source.setExcess(source.getExcess() - source.getNumNeighbors()); }