Ticket #51: 51-4-neg-cycle-75325dfccf38.patch
File 51-4-neg-cycle-75325dfccf38.patch, 4.5 KB (added by , 15 years ago) |
---|
-
lemon/bellman_ford.h
# HG changeset patch # User Peter Kovacs <kpeter@inf.elte.hu> # Date 1249253644 -7200 # Node ID 75325dfccf3898d9df23913cc64979e069a85502 # Parent f9746e45246ee740d32043c486868935988f9b55 Add negativeCycle() function to BellmanFord (#51) diff --git a/lemon/bellman_ford.h b/lemon/bellman_ford.h
a b 770 770 return (*_dist)[v] != OperationTraits::infinity(); 771 771 } 772 772 773 // TODO: implement negative cycle 774 // /// \brief Gives back a negative cycle. 775 // /// 776 // /// This function gives back a negative cycle. 777 // /// If the algorithm have not found yet negative cycle it will give back 778 // /// an empty path. 779 // Path negativeCycle() { 780 // typename Digraph::template NodeMap<int> state(*digraph, 0); 781 // for (ActiveIt it(*this); it != INVALID; ++it) { 782 // if (state[it] == 0) { 783 // for (Node t = it; predArc(t) != INVALID; t = predNode(t)) { 784 // if (state[t] == 0) { 785 // state[t] = 1; 786 // } else if (state[t] == 2) { 787 // break; 788 // } else { 789 // p.clear(); 790 // typename Path::Builder b(p); 791 // b.setStartNode(t); 792 // b.pushFront(predArc(t)); 793 // for(Node s = predNode(t); s != t; s = predNode(s)) { 794 // b.pushFront(predArc(s)); 795 // } 796 // b.commit(); 797 // return true; 798 // } 799 // } 800 // for (Node t = it; predArc(t) != INVALID; t = predNode(t)) { 801 // if (state[t] == 1) { 802 // state[t] = 2; 803 // } else { 804 // break; 805 // } 806 // } 807 // } 808 // } 809 // return false; 810 // } 773 /// \brief Gives back a negative cycle. 774 /// 775 /// This function gives back a directed cycle with negative total 776 /// length if the algorithm has already found one. 777 /// Otherwise it gives back an empty path. 778 lemon::Path<Digraph> negativeCycle() { 779 typename Digraph::template NodeMap<int> state(*_gr, -1); 780 lemon::Path<Digraph> cycle; 781 for (int i = 0; i < int(_process.size()); ++i) { 782 if (state[_process[i]] != -1) continue; 783 for (Node v = _process[i]; (*_pred)[v] != INVALID; 784 v = _gr->source((*_pred)[v])) { 785 if (state[v] == i) { 786 cycle.addFront((*_pred)[v]); 787 for (Node u = _gr->source((*_pred)[v]); u != v; 788 u = _gr->source((*_pred)[u])) { 789 cycle.addFront((*_pred)[u]); 790 } 791 return cycle; 792 } 793 else if (state[v] >= 0) { 794 break; 795 } 796 state[v] = i; 797 } 798 } 799 return cycle; 800 } 811 801 812 802 ///@} 813 803 }; -
test/bellman_ford_test.cc
diff --git a/test/bellman_ford_test.cc b/test/bellman_ford_test.cc
a b 220 220 } 221 221 } 222 222 223 void checkBellmanFordNegativeCycle() { 224 DIGRAPH_TYPEDEFS(SmartDigraph); 225 226 SmartDigraph gr; 227 IntArcMap length(gr); 228 229 Node n1 = gr.addNode(); 230 Node n2 = gr.addNode(); 231 Node n3 = gr.addNode(); 232 Node n4 = gr.addNode(); 233 234 Arc a1 = gr.addArc(n1, n2); 235 Arc a2 = gr.addArc(n2, n2); 236 237 length[a1] = 2; 238 length[a2] = -1; 239 240 { 241 BellmanFord<SmartDigraph, IntArcMap> bf(gr, length); 242 bf.run(n1); 243 StaticPath<SmartDigraph> p = bf.negativeCycle(); 244 check(p.length() == 1 && p.front() == p.back() && p.front() == a2, 245 "Wrong negative cycle."); 246 } 247 248 length[a2] = 0; 249 250 { 251 BellmanFord<SmartDigraph, IntArcMap> bf(gr, length); 252 bf.run(n1); 253 check(bf.negativeCycle().empty(), 254 "Negative cycle should not be found."); 255 } 256 257 length[gr.addArc(n1, n3)] = 5; 258 length[gr.addArc(n4, n3)] = 1; 259 length[gr.addArc(n2, n4)] = 2; 260 length[gr.addArc(n3, n2)] = -4; 261 262 { 263 BellmanFord<SmartDigraph, IntArcMap> bf(gr, length); 264 bf.init(); 265 bf.addSource(n1); 266 for (int i = 0; i < 4; ++i) { 267 check(bf.negativeCycle().empty(), 268 "Negative cycle should not be found."); 269 bf.processNextRound(); 270 } 271 StaticPath<SmartDigraph> p = bf.negativeCycle(); 272 check(p.length() == 3, "Wrong negative cycle."); 273 check(length[p.nth(0)] + length[p.nth(1)] + length[p.nth(2)] == -1, 274 "Wrong negative cycle."); 275 } 276 } 277 223 278 int main() { 224 279 checkBellmanFord<ListDigraph, int>(); 225 280 checkBellmanFord<SmartDigraph, double>(); 281 checkBellmanFordNegativeCycle(); 226 282 return 0; 227 283 }