Doh! Forgot to actually check for negative cycles in relaxEdge.
Showing
3 changed files
with
27 additions
and
3 deletions
... | @@ -151,12 +151,19 @@ public abstract class AbstractGraphPathSearch<V extends Vertex, E extends Edge<V | ... | @@ -151,12 +151,19 @@ public abstract class AbstractGraphPathSearch<V extends Vertex, E extends Edge<V |
151 | * @param e edge to be relaxed | 151 | * @param e edge to be relaxed |
152 | * @param cost base cost to reach the edge destination vertex | 152 | * @param cost base cost to reach the edge destination vertex |
153 | * @param ew optional edge weight function | 153 | * @param ew optional edge weight function |
154 | + * @param forbidNegatives if true negative values will forbid the link | ||
154 | * @return true if the edge was relaxed; false otherwise | 155 | * @return true if the edge was relaxed; false otherwise |
155 | */ | 156 | */ |
156 | - boolean relaxEdge(E e, double cost, EdgeWeight<V, E> ew) { | 157 | + boolean relaxEdge(E e, double cost, EdgeWeight<V, E> ew, |
158 | + boolean... forbidNegatives) { | ||
157 | V v = e.dst(); | 159 | V v = e.dst(); |
158 | double oldCost = cost(v); | 160 | double oldCost = cost(v); |
159 | - double newCost = cost + (ew == null ? 1.0 : ew.weight(e)); | 161 | + double hopCost = ew == null ? 1.0 : ew.weight(e); |
162 | + if (hopCost < 0 && forbidNegatives.length == 1 && forbidNegatives[0]) { | ||
163 | + return false; | ||
164 | + } | ||
165 | + | ||
166 | + double newCost = cost + hopCost; | ||
160 | boolean relaxed = newCost < oldCost; | 167 | boolean relaxed = newCost < oldCost; |
161 | boolean same = Math.abs(newCost - oldCost) < samenessThreshold; | 168 | boolean same = Math.abs(newCost - oldCost) < samenessThreshold; |
162 | if (same || relaxed) { | 169 | if (same || relaxed) { | ... | ... |
... | @@ -40,7 +40,7 @@ public class DijkstraGraphSearch<V extends Vertex, E extends Edge<V>> | ... | @@ -40,7 +40,7 @@ public class DijkstraGraphSearch<V extends Vertex, E extends Edge<V>> |
40 | if (cost < Double.MAX_VALUE) { | 40 | if (cost < Double.MAX_VALUE) { |
41 | // If the vertex is reachable, relax all its egress edges. | 41 | // If the vertex is reachable, relax all its egress edges. |
42 | for (E e : graph.getEdgesFrom(nearest)) { | 42 | for (E e : graph.getEdgesFrom(nearest)) { |
43 | - result.relaxEdge(e, cost, weight); | 43 | + result.relaxEdge(e, cost, weight, true); |
44 | } | 44 | } |
45 | } | 45 | } |
46 | 46 | ... | ... |
... | @@ -91,4 +91,21 @@ public class DijkstraGraphSearchTest extends BreadthFirstSearchTest { | ... | @@ -91,4 +91,21 @@ public class DijkstraGraphSearchTest extends BreadthFirstSearchTest { |
91 | executeSearch(graphSearch(), graph, A, E, weight, 3, 3.0); | 91 | executeSearch(graphSearch(), graph, A, E, weight, 3, 3.0); |
92 | } | 92 | } |
93 | 93 | ||
94 | + @Test | ||
95 | + public void negativeWeights() { | ||
96 | + graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F, G), | ||
97 | + of(new TestEdge(A, B, 1), | ||
98 | + new TestEdge(A, C, -1), | ||
99 | + new TestEdge(B, D, 1), | ||
100 | + new TestEdge(D, A, -2), | ||
101 | + new TestEdge(C, D, 1), | ||
102 | + new TestEdge(D, E, 1), | ||
103 | + new TestEdge(D, F, 1), | ||
104 | + new TestEdge(E, G, 1), | ||
105 | + new TestEdge(F, G, 1), | ||
106 | + new TestEdge(G, A, -5), | ||
107 | + new TestEdge(A, G, 4))); | ||
108 | + executeSearch(graphSearch(), graph, A, G, weight, 3, 4.0); | ||
109 | + } | ||
110 | + | ||
94 | } | 111 | } | ... | ... |
-
Please register or login to post a comment