00001
00002
00003
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef _CHOMP_STRUCT_DIGRAPH_H_
00037 #define _CHOMP_STRUCT_DIGRAPH_H_
00038
00039 #include <iostream>
00040 #include <new>
00041 #include <stack>
00042 #include <queue>
00043 #include <set>
00044 #include <memory>
00045 #include <vector>
00046 #include <algorithm>
00047
00048 #include "chomp/struct/multitab.h"
00049 #include "chomp/struct/hashsets.h"
00050 #include "chomp/struct/flatmatr.h"
00051 #include "chomp/struct/bitfield.h"
00052 #include "chomp/struct/bitsets.h"
00053 #include "chomp/struct/fibheap.h"
00054 #include "chomp/system/textfile.h"
00055 #include "chomp/system/timeused.h"
00056
00057 namespace chomp {
00058 namespace homology {
00059
00060
00061
00062
00063
00064
00067 template <class numType>
00068 class dummyRounding
00069 {
00070 public:
00072 static inline numType add_down (const numType &x, const numType &y)
00073 { return x + y; }
00074
00076 static inline numType add_up (const numType &x, const numType &y)
00077 { return x + y; }
00078
00080 static inline numType sub_down (const numType &x, const numType &y)
00081 { return x - y; }
00082
00084 static inline numType sub_up (const numType &x, const numType &y)
00085 { return x - y; }
00086
00088 static inline numType mul_down (const numType &x, const numType &y)
00089 { return x * y; }
00090
00092 static inline numType mul_up (const numType &x, const numType &y)
00093 { return x * y; }
00094
00096 static inline numType div_down (const numType &x, const numType &y)
00097 { return x / y; }
00098
00100 static inline numType div_down (const numType &x, int_t y)
00101 { return x / y; }
00102
00104 static inline numType div_up (const numType &x, const numType &y)
00105 { return x / y; }
00106
00107 private:
00108 };
00109
00110
00111
00112
00113
00114
00116 class dummyArray
00117 {
00118 public:
00120 dummyArray () {n = 0;}
00121
00123 int_t &operator [] (int_t) {return n;}
00124
00125 private:
00127 int_t n;
00128
00129 };
00130
00131
00132
00133
00134
00135
00136
00137
00141 template <class wType = int>
00142 class diGraph
00143 {
00144 public:
00146 typedef wType weight_type;
00147
00151 diGraph ();
00152
00154 ~diGraph ();
00155
00157 void swap (diGraph<wType> &g);
00158
00160 void addVertex (void);
00161
00164 void addEdge (int_t target);
00165
00168 void addEdge (int_t target, const wType &weight);
00169
00171 void setWeight (int_t vertex, int_t i, const wType &weight);
00172
00174 void setWeight (int_t edge, const wType &weight);
00175
00178 template <class Table>
00179 void setWeights (const Table &tab);
00180
00183 void removeVertex (void);
00184
00189 void removeVertex (int_t vertex, bool updateweights = false);
00190
00192 int_t countVertices (void) const;
00193
00195 int_t countEdges (void) const;
00196
00198 int_t countEdges (int_t vertex) const;
00199
00201 int_t getEdge (int_t vertex, int_t i) const;
00202
00204 const wType &getWeight (int_t vertex, int_t i) const;
00205
00207 const wType &getWeight (int_t edge) const;
00208
00211 template <class Table>
00212 void getWeights (Table &tab) const;
00213
00217 template <class Table>
00218 void writeEdges (Table &tab) const;
00219
00221 template <class wType1>
00222 void transpose (diGraph<wType1> &result,
00223 bool copyweights = false) const;
00224
00228 template <class Table, class wType1>
00229 void subgraph (diGraph<wType1> &result, const Table &tab,
00230 bool copyweights = false) const;
00231
00235 template <class Table, class Color>
00236 void DFScolor (Table &tab, const Color &color,
00237 int_t vertex = 0) const;
00238
00240 template <class Table, class Color>
00241 void DFScolorRecurrent (Table &tab, const Color &color,
00242 int_t vertex = 0) const;
00243
00245 template <class Table, class Color>
00246 void DFScolorStack (Table &tab, const Color &color,
00247 int_t vertex = 0) const;
00248
00251 template <class Table>
00252 void DFSfinishTime (Table &tab) const;
00253
00263 template <class Table1, class Table2, class Table3>
00264 int_t DFSforest (const Table1 &ordered, Table2 &compVertices,
00265 Table3 &compEnds, bool nontrivial = false,
00266 diGraph<wType> *sccGraph = 0) const;
00267
00273 int_t shortestPath (int_t source, int_t destination) const;
00274
00279 int_t shortestLoop (int_t origin) const;
00280
00288 template <class lenTable, class weightsType, class roundType>
00289 void Dijkstra (const roundType &rounding, int_t source,
00290 lenTable &len, weightsType &edgeWeights) const;
00291
00293 template <class lenTable, class roundType>
00294 void Dijkstra (const roundType &rounding, int_t source,
00295 lenTable &len) const;
00296
00298 template <class lenTable>
00299 void Dijkstra (int_t source, lenTable &len) const;
00300
00311 template <class lenTable, class predTable, class roundType>
00312 bool BellmanFord (const roundType &rounding, int_t source,
00313 lenTable &len, wType *infinity, predTable pred) const;
00314
00316 template <class lenTable, class predTable>
00317 bool BellmanFord (int_t source, lenTable &len, wType *infinity,
00318 predTable pred) const;
00319
00323 template <class roundType>
00324 bool BellmanFord (const roundType &rounding, int_t source) const;
00325
00327 bool BellmanFord (int_t source) const;
00328
00335 wType Edmonds () const;
00336
00338 wType EdmondsOld () const;
00339
00354 template <class arrayType, class roundType>
00355 wType FloydWarshall (const roundType &rounding, arrayType &arr,
00356 bool setInfinity = true, bool ignoreNegLoop = false) const;
00357
00359 template <class arrayType>
00360 wType FloydWarshall (arrayType &arr, bool setInfinity = true,
00361 bool ignoreNegLoop = false) const;
00362
00371 template <class arrayType, class roundType>
00372 wType Johnson (const roundType &rounding, arrayType &arr,
00373 bool setInfinity = true, bool ignoreNegLoop = false) const;
00374
00376 template <class arrayType>
00377 wType Johnson (arrayType &arr, bool setInfinity = true,
00378 bool ignoreNegLoop = false) const;
00379
00389 template <class roundType>
00390 wType minPathWeight (const roundType &rounding,
00391 bool ignoreNegLoop = false, int sparseGraph = -1) const;
00392
00394 wType minPathWeight (bool ignoreNegLoop = false,
00395 int sparseGraph = -1) const;
00396
00401 wType minMeanCycleWeight (diGraph<wType> *transposed = 0) const;
00402
00411 template <class roundType>
00412 wType minMeanCycleWeight (const roundType &rounding,
00413 diGraph<wType> *transposed) const;
00414
00420 template <class arrayType, class roundType>
00421 wType minMeanPathWeight (const roundType &rounding,
00422 const arrayType &starting, int_t n) const;
00423
00425 template <class arrayType>
00426 wType minMeanPathWeight (const arrayType &starting, int_t n) const;
00427
00430 template <class wType1, class wType2>
00431 friend bool operator == (const diGraph<wType1> &g1,
00432 const diGraph<wType2> &g2);
00433
00435 template <class outType>
00436 outType &show (outType &out, bool showWeights = false) const;
00437
00438 protected:
00440 int_t nVertices;
00441
00444 multitable<int_t> edgeEnds;
00445
00447 multitable<int_t> edges;
00448
00450 multitable<wType> weights;
00451
00452 private:
00454 template <class Table>
00455 void DFSfinishTimeRecurrent (Table &tab, int_t vertex,
00456 int_t &counter) const;
00457
00459 template <class Table>
00460 void DFSfinishTimeStack (Table &tab, int_t vertex,
00461 int_t &counter) const;
00462
00465 template <class Table1, class Table2>
00466 bool DFSforestRecurrent (Table1 &tab, Table1 &ntab, int_t vertex,
00467 int_t treeNumber, int_t countTrees, Table2 &compVertices,
00468 int_t &curVertex, diGraph *sccGraph, int_t *sccEdgeAdded)
00469 const;
00470
00472 template <class Table1, class Table2>
00473 bool DFSforestStack (Table1 &tab, Table1 &ntab, int_t vertex,
00474 int_t treeNumber, int_t countTrees, Table2 &compVertices,
00475 int_t &curVertex, diGraph *sccGraph, int_t *sccEdgeAdded)
00476 const;
00477
00479 struct edgeTriple
00480 {
00482 int_t vert1;
00483 int_t vert2;
00484
00486 wType weight;
00487
00489 friend bool operator < (const edgeTriple &x,
00490 const edgeTriple &y)
00491 {
00492 return (x. weight < y. weight);
00493 }
00494 };
00495
00498 class posWeight
00499 {
00500 public:
00502 posWeight ()
00503 {
00504 value = 0;
00505 return;
00506 }
00507
00509 explicit posWeight (const wType &_value)
00510 {
00511 if (_value < 0)
00512 value = 0;
00513 else
00514 value = _value;
00515 return;
00516 }
00517
00519 void setInfinity ()
00520 {
00521 value = -1;
00522 return;
00523 }
00524
00526 bool isInfinity () const
00527 {
00528 return (value < 0);
00529 }
00530
00532 const wType &getValue () const
00533 {
00534 return value;
00535 }
00536
00538 friend bool operator < (const posWeight &x,
00539 const posWeight &y)
00540 {
00541 if (y. isInfinity ())
00542 return !(x. isInfinity ());
00543 else if (x. isInfinity ())
00544 return false;
00545 return (x. value < y. value);
00546 }
00547
00549 friend std::ostream &operator << (std::ostream &out,
00550 const posWeight &x)
00551 {
00552 if (x. isInfinity ())
00553 out << "+oo";
00554 else
00555 out << x. getValue ();
00556 return out;
00557 }
00558
00559 private:
00561 wType value;
00562 };
00563
00564 };
00565
00566
00567
00568 template <class wType>
00569 inline diGraph<wType>::diGraph (): nVertices (0),
00570 edgeEnds (1024), edges (4096), weights (4096)
00571 {
00572 return;
00573 }
00574
00575 template <class wType>
00576 inline diGraph<wType>::~diGraph ()
00577 {
00578 return;
00579 }
00580
00581
00582
00583 template <class wType1, class wType2>
00584 inline bool operator == (const diGraph<wType1> &g1,
00585 const diGraph<wType2> &g2)
00586 {
00587 if (g1. nVertices != g2. nVertices)
00588 return false;
00589 if (!g1. nVertices)
00590 return true;
00591 for (int_t i = 0; i < g1. nVertices; ++ i)
00592 {
00593 if (g1. edgeEnds [i] != g2. edgeEnds [i])
00594 return false;
00595 }
00596 int_t nEdges = g1. edgeEnds [g1. nVertices - 1];
00597 for (int_t i = 0; i < nEdges; ++ i)
00598 {
00599 if (g1. edges [i] != g2. edges [i])
00600 return false;
00601 }
00602 return true;
00603 }
00604
00605 template <class wType1, class wType2>
00606 inline bool operator != (const diGraph<wType1> &g1,
00607 const diGraph<wType2> &g2)
00608 {
00609 return !(g1 == g2);
00610 }
00611
00612
00613
00614 template <class wType>
00615 inline void diGraph<wType>::swap (diGraph<wType> &g)
00616 {
00617 my_swap (nVertices, g. nVertices);
00618 edgeEnds. swap (g. edgeEnds);
00619 edges. swap (g. edges);
00620 weights. swap (g. weights);
00621 return;
00622 }
00623
00624 template <class wType>
00625 inline void diGraph<wType>::addVertex (void)
00626 {
00627 edgeEnds [nVertices] = nVertices ? edgeEnds [nVertices - 1] :
00628 static_cast<int_t> (0);
00629 ++ nVertices;
00630 return;
00631 }
00632
00633 template <class wType>
00634 inline void diGraph<wType>::addEdge (int_t target)
00635 {
00636 if (!nVertices)
00637 throw "Trying to add an edge to an empty graph.";
00638
00639
00640 if (target < 0)
00641 throw "Trying to add an edge to a negative vertex.";
00642 int_t &offset = edgeEnds [nVertices - 1];
00643 if (offset + 1 <= 0)
00644 throw "Too many edges in a diGraph (limit = 2,147,483,647).";
00645 edges [offset] = target;
00646 ++ offset;
00647 return;
00648 }
00649
00650 template <class wType>
00651 inline void diGraph<wType>::addEdge (int_t target, const wType &weight)
00652 {
00653 if (!nVertices)
00654 throw "Trying to add an edge to an empty graph.";
00655
00656
00657 if (target < 0)
00658 throw "Trying to add an edge to a negative vertex.";
00659 int_t &offset = edgeEnds [nVertices - 1];
00660 if (offset + 1 <= 0)
00661 throw "Too many edges in a diGraph (limit = 2,147,483,647).";
00662 edges [offset] = target;
00663 weights [offset] = weight;
00664 ++ offset;
00665 return;
00666 }
00667
00668 template <class wType>
00669 inline void diGraph<wType>::setWeight (int_t vertex, int_t i,
00670 const wType &weight)
00671 {
00672 if (!vertex)
00673 weights [i] = weight;
00674 else
00675 weights [edgeEnds [vertex - 1] + i] = weight;
00676 return;
00677 }
00678
00679 template <class wType>
00680 inline void diGraph<wType>::setWeight (int_t edge, const wType &weight)
00681 {
00682 weights [edge] = weight;
00683 return;
00684 }
00685
00686 template <class wType> template <class Table>
00687 inline void diGraph<wType>::setWeights (const Table &tab)
00688 {
00689 if (!nVertices)
00690 return;
00691 int_t nEdges = edgeEnds [nVertices - 1];
00692 for (int_t i = 0; i < nEdges; ++ i)
00693 weights [i] = tab [i];
00694 return;
00695 }
00696
00697 template <class wType>
00698 inline void diGraph<wType>::removeVertex (void)
00699 {
00700 if (!nVertices)
00701 throw "Trying to remove a vertex from the empty graph.";
00702 -- nVertices;
00703 return;
00704 }
00705
00706 template <class wType>
00707 inline void diGraph<wType>::removeVertex (int_t vertex, bool updateweights)
00708 {
00709
00710 if ((vertex < 0) || (vertex >= nVertices))
00711 throw "Trying to remove a vertex that is not in the graph.";
00712
00713
00714 int_t curEdge = 0;
00715 int_t newEdge = 0;
00716 int_t skipped = 0;
00717 for (int_t v = 0; v < nVertices; ++ v)
00718 {
00719
00720 if (!skipped && (v == vertex))
00721 {
00722 curEdge = edgeEnds [v];
00723 ++ skipped;
00724 continue;
00725 }
00726
00727
00728 int_t maxEdge = edgeEnds [v];
00729 for (; curEdge < maxEdge; ++ curEdge)
00730 {
00731 if (edges [curEdge] == vertex)
00732 continue;
00733 int_t target = edges [curEdge];
00734 edges [newEdge] = (target < vertex) ? target :
00735 (target - 1);
00736 if (updateweights)
00737 weights [newEdge] = weights [curEdge];
00738 ++ newEdge;
00739 }
00740 edgeEnds [v - skipped] = newEdge;
00741 }
00742
00743
00744 nVertices -= skipped;
00745
00746 return;
00747 }
00748
00749 template <class wType>
00750 inline int_t diGraph<wType>::countVertices (void) const
00751 {
00752 return nVertices;
00753 }
00754
00755 template <class wType>
00756 inline int_t diGraph<wType>::countEdges (void) const
00757 {
00758 if (!nVertices)
00759 return 0;
00760 else
00761 return edgeEnds [nVertices - 1];
00762 }
00763
00764 template <class wType>
00765 inline int_t diGraph<wType>::countEdges (int_t vertex) const
00766 {
00767 if (!vertex)
00768 return edgeEnds [0];
00769 else
00770 return edgeEnds [vertex] - edgeEnds [vertex - 1];
00771 }
00772
00773 template <class wType>
00774 inline int_t diGraph<wType>::getEdge (int_t vertex, int_t i) const
00775 {
00776 if (!vertex)
00777 return edges [i];
00778 else
00779 return edges [edgeEnds [vertex - 1] + i];
00780 }
00781
00782 template <class wType>
00783 inline const wType &diGraph<wType>::getWeight (int_t vertex, int_t i) const
00784 {
00785 if (!vertex)
00786 return weights [i];
00787 else
00788 return weights [edgeEnds [vertex - 1] + i];
00789 }
00790
00791 template <class wType>
00792 inline const wType &diGraph<wType>::getWeight (int_t edge) const
00793 {
00794 return weights [edge];
00795 }
00796
00797 template <class wType> template <class Table>
00798 inline void diGraph<wType>::getWeights (Table &tab) const
00799 {
00800 if (!nVertices)
00801 return;
00802 int_t nEdges = edgeEnds [nVertices - 1];
00803 for (int_t i = 0; i < nEdges; ++ i)
00804 tab [i] = weights [i];
00805 return;
00806 }
00807
00808 template <class wType> template <class Table>
00809 inline void diGraph<wType>::writeEdges (Table &tab) const
00810 {
00811 int_t curEdge = 0;
00812 for (int_t curVertex = 0; curVertex < nVertices; ++ curVertex)
00813 {
00814 int_t maxEdge = edgeEnds [curVertex];
00815 while (curEdge < maxEdge)
00816 {
00817 tab [curEdge] [0] = curVertex;
00818 tab [curEdge] [1] = edges [curEdge];
00819 ++ curEdge;
00820 }
00821 }
00822 return;
00823 }
00824
00825 template <class wType> template <class wType1>
00826 inline void diGraph<wType>::transpose (diGraph<wType1> &result,
00827 bool copyweights) const
00828 {
00829
00830 result. nVertices = nVertices;
00831 if (!nVertices)
00832 return;
00833
00834
00835 for (int_t i = 0; i < nVertices; ++ i)
00836 result. edgeEnds [i] = 0;
00837 int_t nEdges = edgeEnds [nVertices - 1];
00838 for (int_t i = 0; i < nEdges; ++ i)
00839 {
00840 if (edges [i] < nVertices - 1)
00841 ++ result. edgeEnds [edges [i] + 1];
00842 }
00843 for (int_t i = 2; i < nVertices; ++ i)
00844 result. edgeEnds [i] += result. edgeEnds [i - 1];
00845
00846
00847 int_t curEdge = 0;
00848 for (int_t i = 0; i < nVertices; ++ i)
00849 {
00850 for (; curEdge < edgeEnds [i]; ++ curEdge)
00851 {
00852 int_t j = edges [curEdge];
00853 int_t &offset = result. edgeEnds [j];
00854 result. edges [offset] = i;
00855 if (copyweights)
00856 result. weights [offset] = weights [curEdge];
00857 ++ offset;
00858 }
00859 }
00860 return;
00861 }
00862
00863 template <class wType> template <class Table, class wType1>
00864 inline void diGraph<wType>::subgraph (diGraph<wType1> &g,
00865 const Table &tab, bool copyweights) const
00866 {
00867
00868 int_t *numbers = new int_t [nVertices];
00869 int_t curNumber = 0;
00870 for (int_t i = 0; i < nVertices; ++ i)
00871 {
00872 if (tab [i])
00873 numbers [i] = curNumber ++;
00874 else
00875 numbers [i] = -1;
00876 }
00877
00878
00879 for (int_t i = 0; i < nVertices; ++ i)
00880 {
00881 if (numbers [i] < 0)
00882 continue;
00883 g. addVertex ();
00884 int_t firstEdge = i ? edgeEnds [i - 1] :
00885 static_cast<int_t> (0);
00886 int_t endEdge = edgeEnds [i];
00887 for (int_t j = firstEdge; j < endEdge; ++ j)
00888 {
00889 int_t edgeEnd = edges [j];
00890 if (numbers [edgeEnd] >= 0)
00891 {
00892 if (copyweights)
00893 g. addEdge (numbers [edgeEnd],
00894 weights [j]);
00895 else
00896 g. addEdge (numbers [edgeEnd]);
00897 }
00898 }
00899 }
00900
00901
00902 delete [] numbers;
00903 return;
00904 }
00905
00906
00907
00908 template <class wType> template <class Table, class Color>
00909 inline void diGraph<wType>::DFScolorRecurrent (Table &tab,
00910 const Color &color, int_t vertex) const
00911 {
00912 tab [vertex] = color;
00913 int_t maxEdge = edgeEnds [vertex];
00914 for (int_t i = vertex ? edgeEnds [vertex - 1] :
00915 static_cast<int_t> (0); i < maxEdge; ++ i)
00916 {
00917 int_t next = edges [i];
00918 if (tab [next] != color)
00919 DFScolorRecurrent (tab, color, next);
00920 }
00921 return;
00922 }
00923
00924 template <class wType> template <class Table, class Color>
00925 inline void diGraph<wType>::DFScolorStack (Table &tab, const Color &color,
00926 int_t vertex) const
00927 {
00928
00929 std::stack<int_t> s_vertex;
00930 std::stack<int_t> s_edge;
00931 std::stack<int_t> s_maxedge;
00932
00933
00934 tab [vertex] = color;
00935
00936
00937 int_t edge = vertex ? edgeEnds [vertex - 1] :
00938 static_cast<int_t> (0);
00939 int_t maxedge = edgeEnds [vertex];
00940
00941 while (1)
00942 {
00943
00944
00945 if (edge >= maxedge)
00946 {
00947
00948 if (s_vertex. empty ())
00949 return;
00950
00951
00952 vertex = s_vertex. top ();
00953 s_vertex. pop ();
00954 edge = s_edge. top ();
00955 s_edge. pop ();
00956 maxedge = s_maxedge. top ();
00957 s_maxedge. pop ();
00958 continue;
00959 }
00960
00961
00962 int_t next = edges [edge ++];
00963 if (tab [next] != color)
00964 {
00965
00966 s_vertex. push (vertex);
00967 s_edge. push (edge);
00968 s_maxedge. push (maxedge);
00969
00970
00971 vertex = next;
00972
00973
00974 tab [vertex] = color;
00975
00976
00977 edge = vertex ? edgeEnds [vertex - 1] :
00978 static_cast<int_t> (0);
00979 maxedge = edgeEnds [vertex];
00980 }
00981 }
00982 }
00983
00984 template <class wType> template <class Table, class Color>
00985 inline void diGraph<wType>::DFScolor (Table &tab, const Color &color,
00986 int_t vertex) const
00987 {
00988 DFScolorStack (tab, color, vertex);
00989 return;
00990 }
00991
00992
00993
00994 template <class wType> template <class Table>
00995 inline void diGraph<wType>::DFSfinishTimeRecurrent (Table &tab,
00996 int_t vertex, int_t &counter) const
00997 {
00998
00999 tab [vertex] = -1;
01000
01001
01002 for (int_t edge = vertex ? edgeEnds [vertex - 1] :
01003 static_cast<int_t> (0);
01004 edge < edgeEnds [vertex]; ++ edge)
01005 {
01006 int_t next = edges [edge];
01007 if (!tab [next])
01008 DFSfinishTimeRecurrent (tab, next, counter);
01009 }
01010
01011
01012 tab [vertex] = ++ counter;
01013 return;
01014 }
01015
01016 template <class wType> template <class Table>
01017 inline void diGraph<wType>::DFSfinishTimeStack (Table &tab, int_t vertex,
01018 int_t &counter) const
01019 {
01020
01021 std::stack<int_t> s_vertex;
01022 std::stack<int_t> s_edge;
01023 std::stack<int_t> s_maxedge;
01024
01025
01026 tab [vertex] = -1;
01027
01028
01029 int_t edge = vertex ? edgeEnds [vertex - 1] :
01030 static_cast<int_t> (0);
01031 int_t maxedge = edgeEnds [vertex];
01032
01033 while (1)
01034 {
01035
01036
01037 if (edge >= maxedge)
01038 {
01039
01040
01041 tab [vertex] = ++ counter;
01042
01043
01044 if (s_vertex. empty ())
01045 return;
01046
01047
01048 vertex = s_vertex. top ();
01049 s_vertex. pop ();
01050 edge = s_edge. top ();
01051 s_edge. pop ();
01052 maxedge = s_maxedge. top ();
01053 s_maxedge. pop ();
01054 continue;
01055 }
01056
01057
01058 int_t next = edges [edge ++];
01059 if (!tab [next])
01060 {
01061
01062 s_vertex. push (vertex);
01063 s_edge. push (edge);
01064 s_maxedge. push (maxedge);
01065
01066
01067 vertex = next;
01068
01069
01070 tab [vertex] = -1;
01071
01072
01073 edge = vertex ? edgeEnds [vertex - 1] :
01074 static_cast<int_t> (0);
01075 maxedge = edgeEnds [vertex];
01076 }
01077 }
01078
01079 return;
01080 }
01081
01082 template <class wType> template <class Table>
01083 inline void diGraph<wType>::DFSfinishTime (Table &tab) const
01084 {
01085
01086 for (int_t i = 0; i < nVertices; ++ i)
01087 tab [i] = 0;
01088 int_t counter = 0;
01089
01090
01091 for (int_t i = 0; i < nVertices; ++ i)
01092 {
01093 if (!tab [i])
01094 DFSfinishTimeStack (tab, i, counter);
01095 }
01096
01097 #ifdef DIGRAPH_DEBUG
01098 int_t *tabdebug = new int_t [nVertices];
01099 for (int_t i = 0; i < nVertices; ++ i)
01100 tabdebug [i] = 0;
01101 int_t counterdebug = 0;
01102 for (int_t i = 0; i < nVertices; ++ i)
01103 if (!tabdebug [i])
01104 DFSfinishTimeRecurrent (tabdebug, i, counterdebug);
01105 if (counter != counterdebug)
01106 throw "DFSfinishTime: Wrong counter.";
01107 for (int_t i = 0; i < nVertices; ++ i)
01108 {
01109 if (tab [i] != tabdebug [i])
01110 {
01111 sbug << "\nDFSfinishTime error: tabRec [" << i <<
01112 "] = " << tab [i] << ", tabStack [" << i <<
01113 "] = " << tabdebug [i] << ".\n";
01114 throw "DFSfinishTime: Wrong numbers.";
01115 }
01116 }
01117 sbug << "DEBUG: DFSfinishTime OK. ";
01118 #endif // DIGRAPH_DEBUG
01119 return;
01120 }
01121
01122
01123
01124 template <class wType> template <class Table1, class Table2>
01125 inline bool diGraph<wType>::DFSforestRecurrent (Table1 &tab, Table1 &ntab,
01126 int_t vertex, int_t treeNumber, int_t countTrees,
01127 Table2 &compVertices, int_t &curVertex,
01128 diGraph<wType> *sccGraph, int_t *sccEdgeAdded) const
01129 {
01130
01131 compVertices [curVertex ++] = vertex;
01132
01133
01134 tab [vertex] = treeNumber;
01135
01136
01137
01138
01139 bool loop = false;
01140 for (int_t edge = vertex ? edgeEnds [vertex - 1] :
01141 static_cast<int_t> (0);
01142 edge < edgeEnds [vertex]; ++ edge)
01143 {
01144 int_t next = edges [edge];
01145 if (!tab [next])
01146 loop |= DFSforestRecurrent (tab, ntab, next,
01147 treeNumber, countTrees, compVertices,
01148 curVertex, sccGraph, sccEdgeAdded);
01149 else if (tab [next] == treeNumber)
01150 {
01151 if (sccGraph)
01152 {
01153 int_t target = ntab [treeNumber - 1];
01154 if (sccEdgeAdded [target] != treeNumber)
01155 {
01156 sccGraph -> addEdge (target);
01157 sccEdgeAdded [target] = treeNumber;
01158 }
01159 }
01160 loop = true;
01161 }
01162 else if (sccGraph)
01163 {
01164 int_t target = ntab [tab [next] - 1];
01165 if ((target >= 0) &&
01166 (sccEdgeAdded [target] != treeNumber))
01167 {
01168 sccGraph -> addEdge (target);
01169 sccEdgeAdded [target] = treeNumber;
01170 }
01171 }
01172 }
01173
01174 return loop;
01175 }
01176
01177 template <class wType> template <class Table1, class Table2>
01178 inline bool diGraph<wType>::DFSforestStack (Table1 &tab, Table1 &ntab,
01179 int_t vertex, int_t treeNumber, int_t countTrees,
01180 Table2 &compVertices, int_t &curVertex,
01181 diGraph<wType> *sccGraph, int_t *sccEdgeAdded) const
01182 {
01183
01184 std::stack<int_t> s_vertex;
01185 std::stack<int_t> s_edge;
01186 std::stack<int_t> s_maxedge;
01187 std::stack<bool> s_loop;
01188
01189
01190 compVertices [curVertex ++] = vertex;
01191
01192
01193 tab [vertex] = treeNumber;
01194
01195
01196
01197
01198 bool loop = false;
01199 int_t edge = vertex ? edgeEnds [vertex - 1] :
01200 static_cast<int_t> (0);
01201 int_t maxedge = edgeEnds [vertex];
01202 while (1)
01203 {
01204
01205
01206 if (edge >= maxedge)
01207 {
01208
01209 if (s_vertex. empty ())
01210 return loop;
01211
01212
01213 vertex = s_vertex. top ();
01214 s_vertex. pop ();
01215 edge = s_edge. top ();
01216 s_edge. pop ();
01217 maxedge = s_maxedge. top ();
01218 s_maxedge. pop ();
01219 loop |= s_loop. top ();
01220 s_loop. pop ();
01221 continue;
01222 }
01223
01224
01225 int_t next = edges [edge ++];
01226 if (!tab [next])
01227 {
01228
01229 s_vertex. push (vertex);
01230 s_edge. push (edge);
01231 s_maxedge. push (maxedge);
01232 s_loop. push (loop);
01233
01234
01235 vertex = next;
01236
01237
01238 compVertices [curVertex ++] = vertex;
01239
01240
01241 tab [vertex] = treeNumber;
01242
01243
01244 loop = false;
01245 edge = vertex ? edgeEnds [vertex - 1] :
01246 static_cast<int_t> (0);
01247 maxedge = edgeEnds [vertex];
01248 }
01249 else if (tab [next] == treeNumber)
01250 {
01251 if (sccGraph)
01252 {
01253 int_t target = ntab [treeNumber - 1];
01254 if (sccEdgeAdded [target] != treeNumber)
01255 {
01256 sccGraph -> addEdge (target);
01257 sccEdgeAdded [target] = treeNumber;
01258 }
01259 }
01260 loop = true;
01261 }
01262 else if (sccGraph)
01263 {
01264 int_t target = ntab [tab [next] - 1];
01265 if ((target >= 0) &&
01266 (sccEdgeAdded [target] != treeNumber))
01267 {
01268 sccGraph -> addEdge (target);
01269 sccEdgeAdded [target] = treeNumber;
01270 }
01271 }
01272 }
01273
01274 return loop;
01275 }
01276
01277 template <class wType> template <class Table1, class Table2, class Table3>
01278 inline int_t diGraph<wType>::DFSforest (const Table1 &ordered,
01279 Table2 &compVertices, Table3 &compEnds, bool nontrivial,
01280 diGraph<wType> *sccGraph) const
01281 {
01282
01283
01284 int_t *tab = new int_t [nVertices];
01285 for (int_t i = 0; i < nVertices; ++ i)
01286 tab [i] = 0;
01287
01288
01289
01290 int_t *ntab = new int_t [nVertices];
01291
01292
01293
01294
01295 int_t *sccEdgeAdded = sccGraph ? new int_t [nVertices] :
01296 static_cast<int_t *> (0);
01297 if (sccGraph)
01298 {
01299 for (int_t n = 0; n < nVertices; ++ n)
01300 sccEdgeAdded [n] = -1;
01301 }
01302
01303
01304 int_t treeNumber = 0;
01305
01306
01307 int_t countTrees = 0;
01308 int_t curVertex = 0;
01309
01310
01311 for (int_t i = 0; i < nVertices; ++ i)
01312 {
01313
01314 int_t vertex = ordered [i];
01315
01316
01317 if (tab [vertex])
01318 continue;
01319
01320
01321 if (sccGraph)
01322 sccGraph -> addVertex ();
01323
01324
01325 int_t prevVertex = curVertex;
01326
01327
01328 if (sccGraph)
01329 ntab [treeNumber] = countTrees;
01330 ++ treeNumber;
01331 bool loop = DFSforestStack (tab, ntab, vertex,
01332 treeNumber, countTrees, compVertices,
01333 curVertex, sccGraph, sccEdgeAdded);
01334
01335
01336 compEnds [countTrees ++] = curVertex;
01337
01338
01339 if (nontrivial && !loop)
01340 {
01341 -- countTrees;
01342 curVertex = prevVertex;
01343 if (sccGraph)
01344 {
01345 ntab [treeNumber - 1] = -1;
01346 sccGraph -> removeVertex ();
01347 }
01348 }
01349 }
01350
01351 #ifdef DIGRAPH_DEBUG
01352 diGraph<wType> *sccGraphdebug = 0;
01353 if (sccGraph)
01354 sccGraphdebug = new diGraph<wType>;
01355
01356
01357 int_t *tabdebug = new int_t [nVertices];
01358 for (int_t i = 0; i < nVertices; ++ i)
01359 tabdebug [i] = 0;
01360
01361
01362
01363 int_t *ntabdebug = new int_t [nVertices];
01364
01365
01366
01367 int_t *sccEdgeAddeddebug = sccGraph ? new int_t [nVertices] :
01368 static_cast<int_t> (0);
01369 if (sccGraph)
01370 {
01371 for (int_t n = 0; n < nVertices; ++ n)
01372 sccEdgeAddeddebug [n] = -1;
01373 }
01374
01375 int_t treeNumberdebug = 0;
01376
01377
01378 int_t countTreesdebug = 0;
01379 int_t curVertexdebug = 0;
01380
01381 int_t *compVerticesdebug = new int_t [nVertices];
01382 int_t *compEndsdebug = new int_t [nVertices];
01383
01384
01385 for (int_t i = 0; i < nVertices; ++ i)
01386 {
01387
01388 int_t vertex = ordered [i];
01389
01390
01391 if (tabdebug [vertex])
01392 continue;
01393
01394
01395 if (sccGraphdebug)
01396 sccGraphdebug -> addVertex ();
01397
01398
01399 int_t prevVertex = curVertexdebug;
01400
01401
01402 if (sccGraphdebug)
01403 ntabdebug [treeNumberdebug] = countTreesdebug;
01404 ++ treeNumberdebug;
01405 bool loop = DFSforestRecurrent (tabdebug, ntabdebug, vertex,
01406 treeNumberdebug, countTreesdebug, compVerticesdebug,
01407 curVertexdebug, sccGraphdebug, sccEdgeAddeddebug);
01408
01409
01410 compEndsdebug [countTreesdebug ++] = curVertexdebug;
01411
01412
01413 if (nontrivial && !loop)
01414 {
01415 -- countTreesdebug;
01416 curVertexdebug = prevVertex;
01417 if (sccGraphdebug)
01418 {
01419 ntabdebug [treeNumberdebug - 1] = -1;
01420 sccGraphdebug -> removeVertex ();
01421 }
01422 }
01423 }
01424 if (countTrees != countTreesdebug)
01425 throw "DFSforest: Wrong countTrees.";
01426 for (int_t i = 0; i < countTrees; ++ i)
01427 if (compEnds [i] != compEndsdebug [i])
01428 throw "DFSforest: Wrong compEnds.";
01429 for (int_t i = 0; i < compEndsdebug [countTrees - 1]; ++ i)
01430 if (compVertices [i] != compVerticesdebug [i])
01431 throw "DFSforest: Wrong vertices.";
01432 if (curVertex != curVertexdebug)
01433 throw "DFSforest: Wrong curVertex.";
01434 for (int_t i = 0; i < nVertices; ++ i)
01435 if (tab [i] != tabdebug [i])
01436 throw "DFSforest: Wrong tab.";
01437 if (sccGraph)
01438 {
01439 for (int_t i = 0; i < nVertices; ++ i)
01440 if (ntab [i] != ntabdebug [i])
01441 throw "DFSforest: Wrong ntab.";
01442 if (*sccGraph != *sccGraphdebug)
01443 throw "DFSforest: Wrong graph.";
01444 }
01445 if (sccEdgeAdded)
01446 {
01447 for (int_t i = 0; i < nVertices; ++ i)
01448 if (sccEdgeAdded [i] != sccEdgeAddeddebug [i])
01449 throw "DFSforest: Wrong sccEdgeAdded.";
01450 }
01451 if (treeNumber != treeNumberdebug)
01452 throw "DFSforest: Wrong treeNumber.";
01453 sbug << "DEBUG: DFSforest OK. ";
01454 if (!sccGraph)
01455 sbug << "(Graphs not compared.) ";
01456 delete [] compVerticesdebug;
01457 delete [] compEndsdebug;
01458 if (sccGraphdebug)
01459 delete sccGraphdebug;
01460 delete [] ntabdebug;
01461 delete [] tabdebug;
01462 if (sccEdgeAddeddebug)
01463 delete [] sccEdgeAddeddebug;
01464 #endif // DIGRAPH_DEBUG
01465
01466 if (sccEdgeAdded)
01467 delete [] sccEdgeAdded;
01468 delete [] ntab;
01469 delete [] tab;
01470 return countTrees;
01471 }
01472
01473 template <class wType>
01474 inline int_t diGraph<wType>::shortestPath (int_t source, int_t destination)
01475 const
01476 {
01477
01478 if ((source < 0) || (source >= nVertices) ||
01479 (destination < 0) || (destination >= nVertices))
01480 {
01481 throw "diGraph - shortest path: Wrong vertex number.";
01482 }
01483
01484
01485
01486 BitField visited;
01487 visited. allocate (nVertices);
01488 visited. clearall (nVertices);
01489
01490
01491 std::queue<int_t> q_vertex;
01492 std::queue<int_t> q_depth;
01493
01494
01495 int_t vertex = source;
01496 int_t depth = 0;
01497
01498 while (1)
01499 {
01500
01501 visited. set (vertex);
01502
01503
01504 ++ depth;
01505
01506
01507 int_t firstedge = vertex ? edgeEnds [vertex - 1] :
01508 static_cast<int_t> (0);
01509 int_t maxedge = edgeEnds [vertex];
01510
01511
01512 for (int_t edge = firstedge; edge < maxedge; ++ edge)
01513 {
01514
01515 int_t next = edges [edge];
01516
01517
01518
01519
01520
01521 if (next == destination)
01522 {
01523 visited. free ();
01524 return depth;
01525 }
01526
01527
01528 if (visited. test (next))
01529 continue;
01530
01531
01532 q_vertex. push (next);
01533 q_depth. push (depth);
01534 }
01535
01536
01537
01538
01539 if (q_vertex. empty ())
01540 {
01541 visited. free ();
01542 return 0;
01543 }
01544
01545
01546 vertex = q_vertex. front ();
01547 q_vertex. pop ();
01548 depth = q_depth. front ();
01549 q_depth. pop ();
01550 }
01551 }
01552
01553 template <class wType>
01554 inline int_t diGraph<wType>::shortestLoop (int_t origin) const
01555 {
01556 return shortestPath (origin, origin);
01557 }
01558
01559 template <class wType>
01560 template <class lenTable, class weightsType, class roundType>
01561 inline void diGraph<wType>::Dijkstra (const roundType &rounding,
01562 int_t source, lenTable &len, weightsType &edgeWeights) const
01563 {
01564
01565 FibonacciHeap<posWeight> Q (nVertices);
01566
01567
01568
01569 for (int_t v = 0; v < nVertices; ++ v)
01570 {
01571 posWeight w (0);
01572 if (v != source)
01573 w. setInfinity ();
01574 int_t number = Q. Insert (w);
01575 if (number != v)
01576 {
01577 throw "Wrong implementation of Fibonacci heap "
01578 "for this version of Dijkstra.";
01579 }
01580 }
01581
01582
01583
01584 for (int_t i = 0; i < nVertices; ++ i)
01585 {
01586
01587 int_t minVertex = Q. Minimum ();
01588 posWeight minWeight = Q. ExtractMinimum ();
01589
01590 if (minWeight. isInfinity ())
01591 {
01592 len [minVertex] = -1;
01593 continue;
01594 }
01595 wType minValue = minWeight. getValue ();
01596 len [minVertex] = minValue;
01597
01598
01599
01600 int_t edge = minVertex ? edgeEnds [minVertex - 1] :
01601 static_cast<int_t> (0);
01602 int_t maxEdge = edgeEnds [minVertex];
01603 for (; edge < maxEdge; ++ edge)
01604 {
01605
01606 int_t nextVertex = edges [edge];
01607
01608
01609
01610 const posWeight &nextWeight = Q. Value (nextVertex);
01611 wType newWeight = rounding. add_down (minValue,
01612 edgeWeights [edge]);
01613 if (newWeight < 0)
01614 newWeight = 0;
01615 if (nextWeight. isInfinity () ||
01616 (newWeight < nextWeight. getValue ()))
01617 {
01618 Q. DecreaseKey (nextVertex,
01619 posWeight (newWeight));
01620 }
01621 }
01622 }
01623 return;
01624 }
01625
01626 template <class wType>
01627 template <class lenTable, class roundType>
01628 inline void diGraph<wType>::Dijkstra (const roundType &rounding,
01629 int_t source, lenTable &len) const
01630 {
01631 this -> Dijkstra (rounding, source, len, this -> weights);
01632 return;
01633 }
01634
01635 template <class wType>
01636 template <class lenTable>
01637 inline void diGraph<wType>::Dijkstra (int_t source, lenTable &len) const
01638 {
01639 const dummyRounding<wType> rounding = dummyRounding<wType> ();
01640 this -> Dijkstra (rounding, source, len);
01641 return;
01642 }
01643
01644 template <class wType> template <class lenTable, class predTable,
01645 class roundType>
01646 inline bool diGraph<wType>::BellmanFord (const roundType &rounding,
01647 int_t source, lenTable &len, wType *infinity, predTable pred) const
01648 {
01649
01650 if ((source < 0) || (source >= nVertices))
01651 throw "Bellman-Ford: Wrong source vertex number.";
01652
01653
01654 BitField finite;
01655 finite. allocate (nVertices);
01656 finite. clearall (nVertices);
01657 finite. set (source);
01658 len [source] = 0;
01659
01660
01661 int_t countNegative = 0;
01662
01663
01664 for (int_t i = 0; i < nVertices; ++ i)
01665 pred [i] = -1;
01666
01667
01668 bool noNegativeLoop = false;
01669 int_t counter = 0;
01670 for (; counter <= nVertices; ++ counter)
01671 {
01672 bool modified = false;
01673 int_t curEdge = 0;
01674 for (int_t vertex = 0; vertex < nVertices; ++ vertex)
01675 {
01676 int_t maxEdge = edgeEnds [vertex];
01677 if (!finite. test (vertex))
01678 {
01679 curEdge = maxEdge;
01680 continue;
01681 }
01682 for (; curEdge < maxEdge; ++ curEdge)
01683 {
01684 int_t next = edges [curEdge];
01685 wType newlen = rounding. add_down
01686 (len [vertex], weights [curEdge]);
01687 if (!finite. test (next))
01688 {
01689 finite. set (next);
01690 modified = true;
01691 len [next] = newlen;
01692 pred [next] = vertex;
01693 if (newlen < 0)
01694 ++ countNegative;
01695 }
01696 else if (newlen < len [next])
01697 {
01698 modified = true;
01699 if (!(len [next] < 0) &&
01700 (newlen < 0))
01701 {
01702 ++ countNegative;
01703 }
01704 len [next] = newlen;
01705 pred [next] = vertex;
01706 }
01707 }
01708 }
01709 if (countNegative == nVertices)
01710 {
01711 noNegativeLoop = false;
01712 ++ counter;
01713 break;
01714 }
01715 if (!modified)
01716 {
01717 noNegativeLoop = true;
01718 ++ counter;
01719 break;
01720 }
01721 }
01722
01723
01724 if (false && chomp::homology::sbug. show)
01725 {
01726 chomp::homology::sbug << "Bellman-Ford: " <<
01727 counter << ((counter > 1) ? " loops (" : " loop (") <<
01728 nVertices << " vertices, " << countNegative <<
01729 " negative). " <<
01730 (noNegativeLoop ? "No negative loops.\n" :
01731 "A negative loop found.\n");
01732 }
01733
01734
01735 if (infinity && noNegativeLoop)
01736 {
01737 wType infty (0);
01738 bool first = true;
01739 for (int_t i = 0; i < nVertices; ++ i)
01740 {
01741 if (!finite. test (i))
01742 continue;
01743 if (first)
01744 {
01745 infty = len [i];
01746 first = false;
01747 }
01748 else if (infty < len [i])
01749 {
01750 infty = len [i];
01751 }
01752 }
01753 infty = infty + 1;
01754 for (int_t i = 0; i < nVertices; ++ i)
01755 {
01756 if (!finite. test (i))
01757 len [i] = infty;
01758 }
01759 *infinity = infty;
01760 }
01761
01762 finite. free ();
01763 return noNegativeLoop;
01764 }
01765
01766 template <class wType> template <class lenTable, class predTable>
01767 inline bool diGraph<wType>::BellmanFord (int_t source, lenTable &len,
01768 wType *infinity, predTable pred) const
01769 {
01770 const dummyRounding<wType> rounding = dummyRounding<wType> ();
01771 return this -> BellmanFord (rounding, source, len, infinity, pred);
01772 }
01773
01774 template <class wType> template <class roundType>
01775 inline bool diGraph<wType>::BellmanFord (const roundType &rounding,
01776 int_t source) const
01777 {
01778 std::auto_ptr<wType> len_ptr (new wType [nVertices]);
01779 wType *len = len_ptr. get ();
01780 wType *infinity = 0;
01781 dummyArray tab;
01782 return BellmanFord (rounding, source, len, infinity, tab);
01783 }
01784
01785 template <class wType>
01786 inline bool diGraph<wType>::BellmanFord (int_t source) const
01787 {
01788 const dummyRounding<wType> rounding = dummyRounding<wType> ();
01789 return BellmanFord (rounding, source);
01790 }
01791
01792 template <class wType>
01793 inline wType diGraph<wType>::Edmonds () const
01794 {
01795
01796 std::vector<edgeTriple> edgeTriples (countEdges ());
01797 int_t prevEdge = 0;
01798 int_t curEdge = 0;
01799 for (int_t vert = 0; vert < nVertices; ++ vert)
01800 {
01801 while (curEdge < edgeEnds [vert])
01802 {
01803 edgeTriple &e = edgeTriples [curEdge];
01804 e. vert1 = vert;
01805 e. vert2 = edges [curEdge];
01806 e. weight = weights [curEdge];
01807 ++ curEdge;
01808 }
01809 prevEdge = curEdge;
01810 }
01811 std::sort (edgeTriples. begin (), edgeTriples. end ());
01812
01813
01814 std::auto_ptr<int_t> root_ptr (new int_t [nVertices]);
01815 int_t *root = root_ptr. get ();
01816 for (int_t vert = 0; vert < nVertices; ++ vert)
01817 {
01818 root [vert] = -1;
01819 }
01820
01821
01822 wType totalWeight = 0;
01823 int_t nEdges = countEdges ();
01824 for (int_t curEdge = 0; curEdge < nEdges; ++ curEdge)
01825 {
01826
01827
01828 edgeTriple &e = edgeTriples [curEdge];
01829 int_t root1 = e. vert1;
01830 while (root [root1] >= 0)
01831 {
01832 root1 = root [root1];
01833 }
01834 int_t vert1 = e. vert1;
01835 while (root [vert1] >= 0)
01836 {
01837 int_t next = root [vert1];
01838 root [vert1] = root1;
01839 vert1 = next;
01840 }
01841 int_t root2 = e. vert2;
01842 while (root [root2] >= 0)
01843 {
01844 root2 = root [root2];
01845 }
01846 int_t vert2 = e. vert2;
01847 while (root [vert2] >= 0)
01848 {
01849 int_t next = root [vert2];
01850 root [vert2] = root2;
01851 vert2 = next;
01852 }
01853
01854
01855 if (root1 == root2)
01856 continue;
01857
01858
01859 totalWeight += e. weight;
01860
01861
01862 root [root1] = root2;
01863 }
01864 return totalWeight;
01865 }
01866
01867 template <class wType>
01868 inline wType diGraph<wType>::EdmondsOld () const
01869 {
01870
01871 std::vector<edgeTriple> edgeTriples (countEdges ());
01872 int_t prevEdge = 0;
01873 int_t curEdge = 0;
01874 for (int_t vert = 0; vert < nVertices; ++ vert)
01875 {
01876 while (curEdge < edgeEnds [vert])
01877 {
01878 edgeTriple &e = edgeTriples [curEdge];
01879 e. vert1 = vert;
01880 e. vert2 = edges [curEdge];
01881 e. weight = weights [curEdge];
01882 ++ curEdge;
01883 }
01884 prevEdge = curEdge;
01885 }
01886 std::sort (edgeTriples. begin (), edgeTriples. end ());
01887
01888
01889 std::auto_ptr<int_t> forest_ptr (new int_t [nVertices]);
01890 int_t *forest = forest_ptr. get ();
01891 std::auto_ptr<int_t> next_ptr (new int_t [nVertices]);
01892 int_t *next = next_ptr. get ();
01893 std::auto_ptr<int_t> prev_ptr (new int_t [nVertices]);
01894 int_t *prev = prev_ptr. get ();
01895 for (int_t vert = 0; vert < nVertices; ++ vert)
01896 {
01897 forest [vert] = vert;
01898 next [vert] = -1;
01899 prev [vert] = -1;
01900 }
01901
01902
01903 wType totalWeight = 0;
01904 int_t nEdges = countEdges ();
01905 for (int_t curEdge = 0; curEdge < nEdges; ++ curEdge)
01906 {
01907
01908 edgeTriple &e = edgeTriples [curEdge];
01909 if (forest [e. vert1] == forest [e. vert2])
01910 continue;
01911
01912
01913 totalWeight += e. weight;
01914
01915
01916 int_t vert1 = e. vert1;
01917 while (next [vert1] >= 0)
01918 {
01919 vert1 = next [vert1];
01920 }
01921
01922
01923 int_t vert2 = e. vert2;
01924 while (prev [vert2] >= 0)
01925 {
01926 vert2 = prev [vert2];
01927 }
01928
01929
01930 next [vert1] = vert2;
01931 prev [vert2] = vert1;
01932 int_t treeNumber = forest [vert1];
01933 while (vert2 >= 0)
01934 {
01935 forest [vert2] = treeNumber;
01936 vert2 = next [vert2];
01937 }
01938 }
01939 return totalWeight;
01940 }
01941
01942 template <class wType>
01943 template <class arrayType, class roundType>
01944 inline wType diGraph<wType>::FloydWarshall (const roundType &rounding,
01945 arrayType &arr, bool setInfinity, bool ignoreNegLoop) const
01946 {
01947
01948 if (!nVertices)
01949 return 0;
01950
01951
01952 BitField *finite = new BitField [nVertices];
01953 for (int_t i = 0; i < nVertices; ++ i)
01954 {
01955 finite [i]. allocate (nVertices);
01956 finite [i]. clearall (nVertices);
01957 }
01958
01959
01960 int_t curEdge = 0;
01961 for (int_t source = 0; source < nVertices; ++ source)
01962 {
01963 bool diagset = false;
01964 while (curEdge < edgeEnds [source])
01965 {
01966 int_t target = edges [curEdge];
01967 const wType &weight = weights [curEdge];
01968 if (source == target)
01969 {
01970 if (weight < 0)
01971 {
01972 arr [source] [target] = weight;
01973 diagset = true;
01974 }
01975 }
01976 else
01977 {
01978 arr [source] [target] = weight;
01979 finite [source]. set (target);
01980 }
01981 ++ curEdge;
01982 }
01983 if (!diagset)
01984 arr [source] [source] = 0;
01985 finite [source]. set (source);
01986 }
01987
01988
01989 for (int_t k = 0; k < nVertices; ++ k)
01990 {
01991 for (int_t i = 0; i < nVertices; ++ i)
01992 {
01993 if (!finite [i]. test (k))
01994 continue;
01995 for (int_t j = 0; j < nVertices; ++ j)
01996 {
01997 if (!finite [k]. test (j))
01998 continue;
01999 const wType sum = rounding. add_down
02000 (arr [i] [k], arr [k] [j]);
02001 if (finite [i]. test (j))
02002 {
02003 if (sum < arr [i] [j])
02004 arr [i] [j] = sum;
02005 }
02006 else
02007 {
02008 arr [i] [j] = sum;
02009 finite [i]. set (j);
02010 }
02011 }
02012 }
02013 }
02014
02015
02016
02017 if (!ignoreNegLoop)
02018 {
02019 for (int_t i = 0; i < nVertices; ++ i)
02020 {
02021 if (arr [i] [i] < 0)
02022 throw "Negative loop in Floyd-Warshall.";
02023 }
02024 }
02025
02026
02027 wType result = 0;
02028
02029
02030
02031 if (setInfinity)
02032 {
02033 wType &infinity = result;
02034 for (int_t i = 0; i < nVertices; ++ i)
02035 {
02036 for (int_t j = 0; j < nVertices; ++ j)
02037 {
02038 if (finite [i]. test (j) &&
02039 (infinity <= arr [i] [j]))
02040 {
02041 infinity = rounding. add_up
02042 (arr [i] [j], 1);
02043 }
02044 }
02045 }
02046 for (int_t i = 0; i < nVertices; ++ i)
02047 {
02048 for (int_t j = 0; j < nVertices; ++ j)
02049 {
02050 if (!finite [i]. test (j))
02051 arr [i] [j] = infinity;
02052 }
02053 }
02054 }
02055
02056
02057 else
02058 {
02059 wType &minWeight = result;
02060 bool firstTime = true;
02061 for (int_t i = 0; i < nVertices; ++ i)
02062 {
02063 for (int_t j = 0; j < nVertices; ++ j)
02064 {
02065 if (finite [i]. test (j))
02066 {
02067 if (firstTime)
02068 {
02069 minWeight = arr [i] [j];
02070 firstTime = false;
02071 }
02072 else if (arr [i] [j] < minWeight)
02073 {
02074 minWeight = arr [i] [j];
02075 }
02076 }
02077 }
02078 }
02079 }
02080
02081
02082 for (int_t i = 0; i < nVertices; ++ i)
02083 finite [i]. free ();
02084 delete [] finite;
02085
02086 return result;
02087 }
02088
02089 template <class wType>
02090 template <class arrayType>
02091 inline wType diGraph<wType>::FloydWarshall (arrayType &arr,
02092 bool setInfinity, bool ignoreNegLoop) const
02093 {
02094 const dummyRounding<wType> rounding = dummyRounding<wType> ();
02095 return FloydWarshall (rounding, arr, setInfinity, ignoreNegLoop);
02096 }
02097
02098 template <class wType>
02099 template <class arrayType, class roundType>
02100 inline wType diGraph<wType>::Johnson (const roundType &rounding,
02101 arrayType &arr, bool setInfinity, bool ignoreNegLoop) const
02102 {
02103
02104 if (false && sbug. show)
02105 {
02106 timeused stopWatch;
02107 wType res = FloydWarshall (rounding,
02108 arr, setInfinity, ignoreNegLoop);
02109 chomp::homology::sbug << "\n[Floyd-Warshall: " << res <<
02110 ", " << (double) stopWatch << " sec]\n";
02111 }
02112
02113
02114
02115
02116 if (!nVertices)
02117 return 0;
02118
02119
02120
02121
02122 wType *len = new wType [nVertices];
02123 for (int_t i = 0; i < nVertices; ++ i)
02124 len [i] = 0;
02125
02126
02127 bool noNegativeLoop = false;
02128 int_t counter = 0;
02129 for (; counter <= nVertices; ++ counter)
02130 {
02131 bool modified = false;
02132 int_t curEdge = 0;
02133 for (int_t vertex = 0; vertex < nVertices; ++ vertex)
02134 {
02135 int_t maxEdge = edgeEnds [vertex];
02136 for (; curEdge < maxEdge; ++ curEdge)
02137 {
02138 int_t next = edges [curEdge];
02139 wType newlen = rounding. add_down
02140 (len [vertex], weights [curEdge]);
02141 if (newlen < len [next])
02142 {
02143
02144
02145 if (counter > nVertices)
02146 {
02147 std::cout << vertex;
02148 }
02149 modified = true;
02150 len [next] = newlen;
02151 }
02152 }
02153 }
02154 if (!modified)
02155 {
02156 noNegativeLoop = true;
02157 ++ counter;
02158 break;
02159 }
02160 }
02161 if (!ignoreNegLoop && !noNegativeLoop)
02162 throw "Negative loop found in Johnson's algorithm.";
02163
02164
02165 wType *newWeights = new wType [edgeEnds [nVertices - 1]];
02166 int_t edge = 0;
02167 for (int_t vertex = 0; vertex < nVertices; ++ vertex)
02168 {
02169 int_t maxEdge = edgeEnds [vertex];
02170 for (; edge < maxEdge; ++ edge)
02171 {
02172 wType w = weights [edge];
02173 w = rounding. add_down (w, len [vertex]);
02174 w = rounding. sub_down (w, len [edges [edge]]);
02175 newWeights [edge] = (w < 0) ?
02176 static_cast<wType> (0) : w;
02177 }
02178 }
02179
02180
02181
02182
02183 for (int_t u = 0; u < nVertices; ++ u)
02184 {
02185 this -> Dijkstra (rounding, u, arr [u], newWeights);
02186 }
02187 delete [] newWeights;
02188
02189
02190
02191
02192 wType result = 0;
02193 if (setInfinity)
02194 {
02195 wType &infinity = result;
02196 for (int_t u = 0; u < nVertices; ++ u)
02197 {
02198 for (int_t v = 0; v < nVertices; ++ v)
02199 {
02200 wType w = arr [u] [v];
02201 if (w < 0)
02202 continue;
02203 w = rounding. add_down (w, len [v]);
02204 w = rounding. sub_down (w, len [u]);
02205 if (w < infinity)
02206 continue;
02207 infinity = rounding. add_up (w, 1);
02208 }
02209 }
02210 for (int_t u = 0; u < nVertices; ++ u)
02211 {
02212 for (int_t v = 0; v < nVertices; ++ v)
02213 {
02214 wType w = arr [u] [v];
02215 if (w < 0)
02216 {
02217 arr [u] [v] = infinity;
02218 continue;
02219 }
02220 w = rounding. add_down (w, len [v]);
02221 arr [u] [v] =
02222 rounding. sub_down (w, len [u]);
02223 }
02224 }
02225 }
02226 else
02227 {
02228 wType &minWeight = result;
02229 bool firstTime = true;
02230 for (int_t u = 0; u < nVertices; ++ u)
02231 {
02232 for (int_t v = 0; v < nVertices; ++ v)
02233 {
02234 wType w = arr [u] [v];
02235 if (w < 0)
02236 continue;
02237 w = rounding. add_down (w, len [v]);
02238 w = rounding. sub_down (w, len [u]);
02239 if (firstTime)
02240 {
02241 minWeight = w;
02242 firstTime = false;
02243 }
02244 else if (w < minWeight)
02245 minWeight = w;
02246 }
02247 }
02248 }
02249 delete [] len;
02250
02251
02252 if (false && sbug. show)
02253 {
02254
02255
02256 }
02257
02258 return result;
02259 }
02260
02261 template <class wType>
02262 template <class arrayType>
02263 inline wType diGraph<wType>::Johnson (arrayType &arr,
02264 bool setInfinity, bool ignoreNegLoop) const
02265 {
02266 const dummyRounding<wType> rounding = dummyRounding<wType> ();
02267 return Johnson (rounding, arr, setInfinity, ignoreNegLoop);
02268 }
02269
02270 template <class wType>
02271 template <class roundType>
02272 wType diGraph<wType>::minPathWeight (const roundType &rounding,
02273 bool ignoreNegLoop, int sparseGraph) const
02274 {
02275
02276 if (nVertices <= 0)
02277 return 0;
02278
02279
02280 wType **arr = new wType * [nVertices];
02281 for (int_t i = 0; i < nVertices; ++ i)
02282 arr [i] = new wType [nVertices];
02283
02284
02285
02286 bool sparse = false;
02287 if (sparseGraph == 1)
02288 sparse = true;
02289 else if (sparseGraph != 0)
02290 {
02291 double nEdgesD = this -> countEdges ();
02292 double nVerticesD = this -> countVertices ();
02293 if ((nVerticesD > 3000) && (nEdgesD < nVerticesD * 1000) &&
02294 (nEdgesD < nVerticesD * nVerticesD / 50))
02295 {
02296 sparse = true;
02297 }
02298 }
02299
02300
02301 wType minWeight = sparse ?
02302 this -> Johnson (rounding, arr, false, ignoreNegLoop) :
02303 this -> FloydWarshall (rounding, arr, false, ignoreNegLoop);
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318 for (int_t i = 0; i < nVertices; ++ i)
02319 delete [] (arr [i]);
02320 delete [] arr;
02321
02322 return minWeight;
02323 }
02324
02325 template <class wType>
02326 wType diGraph<wType>::minPathWeight (bool ignoreNegLoop, int sparseGraph)
02327 const
02328 {
02329 const dummyRounding<wType> rounding = dummyRounding<wType> ();
02330 return this -> minPathWeight (rounding, ignoreNegLoop, sparseGraph);
02331 }
02332
02333 template <class wType> template <class outType>
02334 inline outType &diGraph<wType>::show (outType &out, bool showWeights) const
02335 {
02336 out << "; Directed graph: " << nVertices << " vertices.\n";
02337 int_t curEdge = 0;
02338 for (int_t i = 0; i < nVertices; ++ i)
02339 {
02340 for (; curEdge < edgeEnds [i]; ++ curEdge)
02341 {
02342 out << i << " -> " << edges [curEdge];
02343 if (showWeights)
02344 out << " [" << weights [curEdge] << "]\n";
02345 else
02346 out << "\n";
02347 }
02348 }
02349 out << "; This is the end of the graph.\n";
02350 return out;
02351 }
02352
02353
02354
02355
02357 template <class wType>
02358 inline std::ostream &operator << (std::ostream &out, const diGraph<wType> &g)
02359 {
02360 return g. show (out, false);
02361 }
02362
02363
02364
02372 template <class wType, class Table1, class Table2>
02373 inline int_t SCC (const diGraph<wType> &g, Table1 &compVertices,
02374 Table2 &compEnds, diGraph<wType> *scc = 0,
02375 diGraph<wType> *transposed = 0, bool copyweights = false)
02376 {
02377
02378 int_t nVert = g. countVertices ();
02379 int_t *ordered = new int_t [nVert];
02380 int_t *tab = new int_t [nVert];
02381
02382
02383 g. DFSfinishTime (tab);
02384 for (int_t i = 0; i < nVert; ++ i)
02385 ordered [nVert - tab [i]] = i;
02386 delete [] tab;
02387
02388
02389 diGraph<wType> gT;
02390 if (!transposed)
02391 transposed = &gT;
02392 g. transpose (*transposed, copyweights);
02393
02394
02395 int_t n = transposed -> DFSforest (ordered, compVertices, compEnds,
02396 true, scc);
02397
02398
02399 delete [] ordered;
02400 return n;
02401 }
02402
02403
02404
02414 template <class wType, class Table1, class Table2>
02415 inline int_t SCC_Tarjan (const diGraph<wType> &g, Table1 &compVertices,
02416 Table2 &compEnds)
02417 {
02418
02419 int_t nVertices = g. countVertices ();
02420 if (!nVertices)
02421 return 0;
02422
02423
02424
02425 std::vector<int_t> dfsIndex (nVertices, 0);
02426
02427
02428
02429 std::vector<int_t> lowLink (nVertices, 0);
02430
02431
02432 std::stack<int_t> s_nodes;
02433
02434
02435
02436 BitField inTheStack;
02437 inTheStack. allocate (nVertices);
02438 inTheStack. clearall (nVertices);
02439
02440
02441 int_t nComponents = 0;
02442
02443
02444 int_t posVertices = 0;
02445
02446
02447
02448 int_t vertexToScan = 0;
02449
02450
02451 int_t discoveryTime = 0;
02452
02453
02454 std::stack<int_t> s_vertex;
02455 std::stack<int_t> s_edge;
02456 std::stack<int_t> s_maxedge;
02457
02458
02459 int_t vertex = -1;
02460
02461
02462 int_t edge = 0;
02463 int_t maxedge = 0;
02464
02465 while (1)
02466 {
02467
02468
02469 if (edge >= maxedge)
02470 {
02471
02472 if ((vertex >= 0) && (lowLink [vertex] ==
02473 dfsIndex [vertex]))
02474 {
02475 int_t v = 0;
02476 do
02477 {
02478 v = s_nodes. top ();
02479 s_nodes. pop ();
02480 inTheStack. clear (v);
02481 compVertices [posVertices ++] = v;
02482 } while (v != vertex);
02483 compEnds [nComponents ++] = posVertices;
02484 }
02485
02486
02487
02488 if (s_vertex. empty ())
02489 {
02490
02491 while ((vertexToScan < nVertices) &&
02492 (dfsIndex [vertexToScan] != 0))
02493 {
02494 ++ vertexToScan;
02495 }
02496
02497
02498 if (vertexToScan == nVertices)
02499 {
02500 inTheStack. free ();
02501 return nComponents;
02502 }
02503
02504
02505 vertex = vertexToScan ++;
02506
02507
02508
02509 dfsIndex [vertex] = ++ discoveryTime;
02510 lowLink [vertex] = discoveryTime;
02511
02512
02513 s_nodes. push (vertex);
02514 inTheStack. set (vertex);
02515
02516
02517 edge = 0;
02518 maxedge = g. countEdges (vertex);
02519 }
02520
02521
02522 else
02523 {
02524
02525 int_t lowLink2 = lowLink [vertex];
02526
02527
02528 vertex = s_vertex. top ();
02529 s_vertex. pop ();
02530 edge = s_edge. top ();
02531 s_edge. pop ();
02532 maxedge = s_maxedge. top ();
02533 s_maxedge. pop ();
02534
02535
02536 if (lowLink [vertex] > lowLink2)
02537 lowLink [vertex] = lowLink2;
02538 }
02539 }
02540
02541
02542 else
02543 {
02544
02545 int_t next = g. getEdge (vertex, edge ++);
02546
02547
02548 if (dfsIndex [next] == 0)
02549 {
02550
02551 s_vertex. push (vertex);
02552 s_edge. push (edge);
02553 s_maxedge. push (maxedge);
02554
02555
02556 vertex = next;
02557
02558
02559 dfsIndex [vertex] = ++ discoveryTime;
02560 lowLink [vertex] = discoveryTime;
02561
02562
02563 s_nodes. push (vertex);
02564 inTheStack. set (vertex);
02565
02566
02567 edge = 0;
02568 maxedge = g. countEdges (vertex);
02569 }
02570
02571
02572
02573 else if (inTheStack. test (next))
02574 {
02575 if (lowLink [vertex] > dfsIndex [next])
02576 lowLink [vertex] = dfsIndex [next];
02577 }
02578 }
02579 }
02580
02581
02582 inTheStack. free ();
02583 return nComponents;
02584 }
02585
02586
02587
02588 template <class wType>
02589 wType diGraph<wType>::minMeanCycleWeight (diGraph<wType> *transposed) const
02590 {
02591
02592 multitable<int_t> compVertices, compEnds;
02593 bool copyweights = !!transposed;
02594 int_t countSCC = SCC (*this, compVertices, compEnds,
02595 static_cast<diGraph<wType> *> (0), transposed, copyweights);
02596 if (countSCC <= 0)
02597 return 0;
02598
02599
02600 int_t maxCompSize = compEnds [0];
02601 for (int_t comp = 1; comp < countSCC; ++ comp)
02602 {
02603 int_t compSize = compEnds [comp] - compEnds [comp - 1];
02604 if (maxCompSize < compSize)
02605 maxCompSize = compSize;
02606 }
02607
02608
02609 wType **F = new wType * [maxCompSize + 1];
02610 BitField *finite = new BitField [maxCompSize + 1];
02611 for (int_t i = 0; i <= maxCompSize; ++ i)
02612 {
02613 F [i] = new wType [maxCompSize];
02614 finite [i]. allocate (maxCompSize);
02615 }
02616
02617
02618 int_t *numbers = new int_t [nVertices];
02619 int_t *components = new int_t [nVertices];
02620 for (int_t i = 0; i < nVertices; ++ i)
02621 components [i] = -1;
02622 int_t offset = 0;
02623 for (int_t comp = 0; comp < countSCC; ++ comp)
02624 {
02625 int_t maxOffset = compEnds [comp];
02626 int_t pos = offset;
02627 for (; pos < maxOffset; ++ pos)
02628 {
02629 numbers [compVertices [pos]] = pos - offset;
02630 components [compVertices [pos]] = comp;
02631 }
02632 offset = pos;
02633 }
02634
02635
02636 wType minWeight (0);
02637 for (int_t comp = 0; comp < countSCC; ++ comp)
02638 {
02639 int_t offset = comp ? compEnds [comp - 1] :
02640 static_cast<int_t> (0);
02641 int_t compSize = compEnds [comp] - offset;
02642 for (int_t i = 0; i <= compSize; ++ i)
02643 finite [i]. clearall (compSize);
02644 F [0] [0] = 0;
02645 finite [0]. set (0);
02646
02647 for (int_t len = 1; len <= compSize; ++ len)
02648 {
02649
02650 for (int_t i = 0; i < compSize; ++ i)
02651 {
02652 if (!finite [len - 1]. test (i))
02653 continue;
02654 wType prevWeight = F [len - 1] [i];
02655 int_t source = compVertices [offset + i];
02656
02657
02658 int_t edgeOffset = source ?
02659 edgeEnds [source - 1] :
02660 static_cast<int_t> (0);
02661 int_t edgeEnd = edgeEnds [source];
02662 for (; edgeOffset < edgeEnd; ++ edgeOffset)
02663 {
02664 int_t target = edges [edgeOffset];
02665 if (components [target] != comp)
02666 continue;
02667 int_t j = numbers [target];
02668 wType newWeight = prevWeight +
02669 weights [edgeOffset];
02670 if (!finite [len]. test (j))
02671 {
02672 finite [len]. set (j);
02673 F [len] [j] = newWeight;
02674 }
02675 else if (newWeight < F [len] [j])
02676 F [len] [j] = newWeight;
02677 }
02678 }
02679 }
02680
02681
02682 wType minCompWeight (0);
02683 bool firstMin = true;
02684 for (int_t vert = 0; vert < compSize; ++ vert)
02685 {
02686 if (!finite [compSize]. test (vert))
02687 continue;
02688 bool firstAverage = true;
02689 wType maxAverage = 0;
02690 for (int_t first = 0; first < compSize; ++ first)
02691 {
02692 if (!finite [first]. test (vert))
02693 continue;
02694 wType average = (F [compSize] [vert] -
02695 F [first] [vert]) /
02696 (compSize - first);
02697 if (firstAverage)
02698 {
02699 maxAverage = average;
02700 firstAverage = false;
02701 }
02702 else if (maxAverage < average)
02703 maxAverage = average;
02704 }
02705 if (firstMin || (maxAverage < minCompWeight))
02706 {
02707 if (firstAverage)
02708 throw "Bug in Karp's algorithm";
02709 minCompWeight = maxAverage;
02710 firstMin = false;
02711 }
02712 }
02713
02714
02715 if (!comp || (minCompWeight < minWeight))
02716 minWeight = minCompWeight;
02717 }
02718
02719
02720 delete [] components;
02721 delete [] numbers;
02722 for (int_t i = 0; i < maxCompSize; ++ i)
02723 {
02724 finite [i]. free ();
02725 delete [] (F [i]);
02726 }
02727 delete [] finite;
02728 delete [] F;
02729
02730
02731 return minWeight;
02732 }
02733
02734 template <class wType>
02735 template <class roundType>
02736 wType diGraph<wType>::minMeanCycleWeight (const roundType &rounding,
02737 diGraph<wType> *transposed) const
02738 {
02739
02740 multitable<int_t> compVertices, compEnds;
02741 bool copyweights = !!transposed;
02742 int_t countSCC = SCC (*this, compVertices, compEnds,
02743 static_cast<diGraph<wType> *> (0), transposed, copyweights);
02744 if (countSCC <= 0)
02745 return 0;
02746
02747
02748 int_t maxCompSize = compEnds [0];
02749 for (int_t comp = 1; comp < countSCC; ++ comp)
02750 {
02751 int_t compSize = compEnds [comp] - compEnds [comp - 1];
02752 if (maxCompSize < compSize)
02753 maxCompSize = compSize;
02754 }
02755
02756
02757 wType **FUpper = new wType * [maxCompSize + 1];
02758 wType **FLower = new wType * [maxCompSize + 1];
02759 BitField *finite = new BitField [maxCompSize + 1];
02760 for (int_t i = 0; i <= maxCompSize; ++ i)
02761 {
02762 FUpper [i] = new wType [maxCompSize];
02763 FLower [i] = new wType [maxCompSize];
02764 finite [i]. allocate (maxCompSize);
02765 }
02766
02767
02768 int_t *numbers = new int_t [nVertices];
02769 int_t *components = new int_t [nVertices];
02770 for (int_t i = 0; i < nVertices; ++ i)
02771 components [i] = -1;
02772 int_t offset = 0;
02773 for (int_t comp = 0; comp < countSCC; ++ comp)
02774 {
02775 int_t maxOffset = compEnds [comp];
02776 int_t pos = offset;
02777 for (; pos < maxOffset; ++ pos)
02778 {
02779 numbers [compVertices [pos]] = pos - offset;
02780 components [compVertices [pos]] = comp;
02781 }
02782 offset = pos;
02783 }
02784
02785
02786 wType minWeight (0);
02787 for (int_t comp = 0; comp < countSCC; ++ comp)
02788 {
02789 int_t offset = comp ? compEnds [comp - 1] :
02790 static_cast<int_t> (0);
02791 int_t compSize = compEnds [comp] - offset;
02792 for (int_t i = 0; i <= compSize; ++ i)
02793 finite [i]. clearall (compSize);
02794 FUpper [0] [0] = 0;
02795 FLower [0] [0] = 0;
02796 finite [0]. set (0);
02797
02798 for (int_t len = 1; len <= compSize; ++ len)
02799 {
02800
02801 for (int_t i = 0; i < compSize; ++ i)
02802 {
02803 if (!finite [len - 1]. test (i))
02804 continue;
02805 wType prevUpper = FUpper [len - 1] [i];
02806 wType prevLower = FLower [len - 1] [i];
02807 int_t source = compVertices [offset + i];
02808
02809
02810 int_t edgeOffset = source ?
02811 edgeEnds [source - 1] :
02812 static_cast<int_t> (0);
02813 int_t edgeEnd = edgeEnds [source];
02814 for (; edgeOffset < edgeEnd; ++ edgeOffset)
02815 {
02816 int_t target = edges [edgeOffset];
02817 if (components [target] != comp)
02818 continue;
02819 int_t j = numbers [target];
02820 wType newUpper = rounding. add_up
02821 (prevUpper,
02822 weights [edgeOffset]);
02823 wType newLower = rounding. add_down
02824 (prevLower,
02825 weights [edgeOffset]);
02826 if (!finite [len]. test (j))
02827 {
02828 finite [len]. set (j);
02829 FUpper [len] [j] = newUpper;
02830 FLower [len] [j] = newLower;
02831 }
02832 else
02833 {
02834 wType &curUpper =
02835 FUpper [len] [j];
02836 if (newUpper < curUpper)
02837 curUpper = newUpper;
02838 wType &curLower =
02839 FLower [len] [j];
02840 if (newLower < curLower)
02841 curLower = newLower;
02842 }
02843 }
02844 }
02845 }
02846
02847
02848 wType minCompWeight (0);
02849 bool firstMin = true;
02850 for (int_t vert = 0; vert < compSize; ++ vert)
02851 {
02852 if (!finite [compSize]. test (vert))
02853 continue;
02854 bool firstAverage = true;
02855 wType maxAverage = 0;
02856 for (int_t first = 0; first < compSize; ++ first)
02857 {
02858 if (!finite [first]. test (vert))
02859 continue;
02860 const wType diff = rounding. sub_down
02861 (FLower [compSize] [vert],
02862 FUpper [first] [vert]);
02863 wType average = rounding. div_down
02864 (diff, compSize - first);
02865 if (firstAverage)
02866 {
02867 maxAverage = average;
02868 firstAverage = false;
02869 }
02870 else if (maxAverage < average)
02871 maxAverage = average;
02872 }
02873 if (firstMin || (maxAverage < minCompWeight))
02874 {
02875 if (firstAverage)
02876 throw "Bug in Karp's algorithm";
02877 minCompWeight = maxAverage;
02878 firstMin = false;
02879 }
02880 }
02881
02882
02883 if (!comp || (minCompWeight < minWeight))
02884 minWeight = minCompWeight;
02885 }
02886
02887
02888 delete [] components;
02889 delete [] numbers;
02890 for (int_t i = 0; i < maxCompSize; ++ i)
02891 {
02892 finite [i]. free ();
02893 delete [] (FUpper [i]);
02894 delete [] (FLower [i]);
02895 }
02896 delete [] finite;
02897 delete [] FUpper;
02898 delete [] FLower;
02899
02900
02901 return minWeight;
02902 }
02903
02904 template <class wType>
02905 template <class arrayType, class roundType>
02906 wType diGraph<wType>::minMeanPathWeight (const roundType &rounding,
02907 const arrayType &starting, int_t n) const
02908 {
02909
02910 const int nIndices = 2;
02911 wType **F = new wType * [nIndices];
02912 BitField *finite = new BitField [nIndices];
02913 for (int i = 0; i < nIndices; ++ i)
02914 {
02915 F [i] = new wType [nVertices];
02916 finite [i]. allocate (nVertices);
02917 }
02918
02919
02920 for (int_t i = 0; i < n; ++ i)
02921 {
02922 int_t v = starting [i];
02923 if ((v < 0) || (v >= nVertices))
02924 throw "Starting vertex out of range.";
02925 F [0] [v] = 0;
02926 finite [0]. set (v);
02927 }
02928
02929
02930 wType minWeight (0);
02931 bool firstWeight = true;
02932 for (int_t len = 1; len <= nVertices; ++ len)
02933 {
02934
02935 int_t prevIndex = (len - 1) & 1;
02936 int_t curIndex = len & 1;
02937 finite [curIndex]. clearall (nVertices);
02938
02939
02940 for (int_t source = 0; source < nVertices; ++ source)
02941 {
02942 if (!finite [prevIndex]. test (source))
02943 continue;
02944 wType prevWeight = F [prevIndex] [source];
02945
02946
02947 int_t edgeOffset = source ?
02948 edgeEnds [source - 1] :
02949 static_cast<int_t> (0);
02950 int_t edgeEnd = edgeEnds [source];
02951 for (; edgeOffset < edgeEnd; ++ edgeOffset)
02952 {
02953 int_t target = edges [edgeOffset];
02954 wType newWeight = rounding. add_down
02955 (prevWeight, weights [edgeOffset]);
02956 if (!finite [curIndex]. test (target))
02957 {
02958 finite [curIndex]. set (target);
02959 F [curIndex] [target] = newWeight;
02960 }
02961 else if (newWeight < F [curIndex] [target])
02962 F [curIndex] [target] = newWeight;
02963 }
02964 }
02965
02966
02967 for (int_t vert = 0; vert < nVertices; ++ vert)
02968 {
02969 if (!finite [curIndex]. test (vert))
02970 continue;
02971 wType average = rounding. div_down
02972 (F [curIndex] [vert], len);
02973 if (firstWeight)
02974 {
02975 minWeight = average;
02976 firstWeight = false;
02977 }
02978 else if (average < minWeight)
02979 minWeight = average;
02980 }
02981 }
02982
02983
02984 for (int i = 0; i < nIndices; ++ i)
02985 {
02986 finite [i]. free ();
02987 delete [] (F [i]);
02988 }
02989 delete [] finite;
02990 delete [] F;
02991
02992
02993 return minWeight;
02994 }
02995
02996 template <class wType>
02997 template <class arrayType>
02998 wType diGraph<wType>::minMeanPathWeight (const arrayType &starting, int_t n)
02999 const
03000 {
03001 const dummyRounding<wType> rounding = dummyRounding<wType> ();
03002 return minMeanPathWeight (rounding, starting, n);
03003 }
03004
03005
03006
03007
03008
03009
03011 template <class wType>
03012 inline int_t addRenumEdges (const diGraph<wType> &g, int_t vertex,
03013 const int_t *newNum, int_t cur, int_t *srcVert,
03014 diGraph<wType> &result)
03015 {
03016 int_t nEdges = g. countEdges (vertex);
03017
03018 for (int_t edge = 0; edge < nEdges; ++ edge)
03019 {
03020
03021 int_t dest = newNum [g. getEdge (vertex, edge)];
03022
03023 if (dest == cur)
03024 continue;
03025
03026
03027 if (srcVert [dest] == cur)
03028 continue;
03029
03030
03031 srcVert [dest] = cur;
03032
03033 result. addEdge (dest);
03034 }
03035 return 0;
03036 }
03037
03043 template <class wType, class Table1, class Table2>
03044 inline int_t collapseVertices (const diGraph<wType> &g,
03045 int_t compNum, Table1 &compVertices, Table2 &compEnds,
03046 diGraph<wType> &result, int_t *newNumbers = 0)
03047 {
03048
03049 int_t nVert = g. countVertices ();
03050 if (!nVert)
03051 return 0;
03052
03053
03054
03055 int_t *newNum = newNumbers ? newNumbers : new int_t [nVert];
03056 for (int_t i = 0; i < nVert; ++ i)
03057 newNum [i] = -1;
03058 int_t cur = 0;
03059 int_t pos = 0;
03060 while (cur < compNum)
03061 {
03062 int_t posEnd = compEnds [cur];
03063 while (pos < posEnd)
03064 newNum [compVertices [pos ++]] = cur;
03065 ++ cur;
03066 }
03067 for (int_t i = 0; i < nVert; ++ i)
03068 {
03069 if (newNum [i] < 0)
03070 newNum [i] = cur ++;
03071 }
03072
03073
03074
03075 int_t newVert = nVert - (compNum ? compEnds [compNum - 1] :
03076 static_cast<int_t> (0)) + compNum;
03077
03078 if (cur != newVert)
03079 throw "DEBUG: Wrong numbers.";
03080 int_t *srcVert = new int_t [newVert];
03081 for (int_t i = 0; i < newVert; ++ i)
03082 srcVert [i] = -1;
03083
03084
03085
03086 cur = 0, pos = 0;
03087 while (cur < compNum)
03088 {
03089
03090 result. addVertex ();
03091
03092 int_t posEnd = compEnds [cur];
03093 while (pos < posEnd)
03094 {
03095
03096 int_t vertex = compVertices [pos ++];
03097
03098 addRenumEdges (g, vertex, newNum, cur,
03099 srcVert, result);
03100 }
03101 ++ cur;
03102 }
03103
03104 for (int_t vertex = 0; vertex < nVert; ++ vertex)
03105 {
03106
03107 if (newNum [vertex] > cur)
03108 throw "DEBUG: Wrong order.";
03109
03110 if (newNum [vertex] != cur)
03111 continue;
03112
03113 result. addVertex ();
03114 addRenumEdges (g, vertex, newNum, cur, srcVert, result);
03115 ++ cur;
03116 }
03117
03118
03119 delete [] srcVert;
03120 if (!newNumbers)
03121 delete [] newNum;
03122 return 0;
03123 }
03124
03126 template <class wType, class TabSets>
03127 inline int_t addRenumEdges2 (const diGraph<wType> &g, int_t vertex,
03128 const int_t *newNum, TabSets &numSets,
03129 int_t cur, int_t *srcVert, diGraph<wType> &result)
03130 {
03131 int_t nEdges = g. countEdges (vertex);
03132
03133
03134 for (int_t edge = 0; edge < nEdges; ++ edge)
03135 {
03136
03137 int_t destNumber = newNum [g. getEdge (vertex, edge)];
03138
03139
03140 int_t destSize = (destNumber < 0) ?
03141 numSets [-destNumber]. size () :
03142 static_cast<int_t> (1);
03143 for (int_t i = 0; i < destSize; ++ i)
03144 {
03145
03146 int_t dest = (destNumber < 0) ?
03147 numSets [-destNumber] [i] : destNumber;
03148
03149
03150 if (dest == cur)
03151 continue;
03152
03153
03154
03155 if (srcVert [dest] == cur)
03156 continue;
03157
03158
03159 result. addEdge (dest);
03160 }
03161 }
03162 return 0;
03163 }
03164
03169 template <class wType, class Table1, class Table2>
03170 inline int_t collapseVertices2 (const diGraph<wType> &g,
03171 int_t compNum, Table1 &compVertices, Table2 &compEnds,
03172 diGraph<wType> &result)
03173 {
03174
03175 int_t nVert = g. countVertices ();
03176 if (!nVert)
03177 return 0;
03178
03179
03180
03181
03182
03183 int_t *newNum = new int_t [nVert];
03184 for (int_t i = 0; i < nVert; ++ i)
03185 newNum [i] = -1;
03186
03187
03188
03189 multitable<hashedset<int_t> > numSets;
03190
03191 int_t numSetCur = 2;
03192
03193 int_t cur = 0;
03194 int_t pos = 0;
03195 while (cur < compNum)
03196 {
03197 int_t posEnd = compEnds [cur];
03198 while (pos < posEnd)
03199 {
03200 int_t number = compVertices [pos ++];
03201 if (newNum [number] == -1)
03202 newNum [number] = cur;
03203 else if (newNum [number] < 0)
03204 numSets [-newNum [number]]. add (cur);
03205 else
03206 {
03207 numSets [numSetCur]. add (newNum [number]);
03208 numSets [numSetCur]. add (cur);
03209 newNum [number] = -(numSetCur ++);
03210 }
03211 }
03212 ++ cur;
03213 }
03214 for (int_t i = 0; i < nVert; ++ i)
03215 {
03216 if (newNum [i] == -1)
03217 newNum [i] = cur ++;
03218 }
03219
03220
03221
03222 int_t newVert = cur;
03223 int_t *srcVert = new int_t [newVert];
03224 for (int_t i = 0; i < newVert; ++ i)
03225 srcVert [i] = -1;
03226
03227
03228
03229 cur = 0;
03230 pos = 0;
03231 while (cur < compNum)
03232 {
03233
03234 result. addVertex ();
03235
03236
03237 int_t posEnd = compEnds [cur];
03238 while (pos < posEnd)
03239 {
03240
03241 int_t vertex = compVertices [pos ++];
03242
03243
03244 addRenumEdges2 (g, vertex, newNum, numSets, cur,
03245 srcVert, result);
03246 }
03247 ++ cur;
03248 }
03249
03250
03251 for (int_t vertex = 0; vertex < nVert; ++ vertex)
03252 {
03253
03254 if (newNum [vertex] > cur)
03255 throw "DEBUG: Wrong order 2.";
03256
03257
03258 if (newNum [vertex] != cur)
03259 continue;
03260
03261
03262 result. addVertex ();
03263 addRenumEdges2 (g, vertex, newNum, numSets, cur,
03264 srcVert, result);
03265 ++ cur;
03266 }
03267
03268
03269 delete [] srcVert;
03270 delete [] newNum;
03271 return 0;
03272 }
03273
03282 template <class wType>
03283 inline int_t connectionGraph (const diGraph<wType> &g, int_t nVert,
03284 diGraph<wType> &result)
03285 {
03286
03287 int_t nVertG = g. countVertices ();
03288 if (!nVertG)
03289 return 0;
03290
03291
03292 BitField visited;
03293 visited. allocate (nVertG);
03294 visited. clearall (nVertG);
03295
03296
03297 for (int_t startVertex = 0; startVertex < nVert; ++ startVertex)
03298 {
03299
03300 result. addVertex ();
03301
03302
03303 int_t nVisited = 0;
03304 std::stack<int_t> s_visited;
03305
03306
03307 std::stack<int_t> s_vertex;
03308 std::stack<int_t> s_edge;
03309
03310
03311 visited. set (startVertex);
03312 s_visited. push (startVertex);
03313 ++ nVisited;
03314
03315
03316 int_t vertex = startVertex;
03317 int_t edge = 0;
03318 while (1)
03319 {
03320
03321
03322 if (edge >= g. countEdges (vertex))
03323 {
03324
03325
03326 if (s_vertex. empty ())
03327 break;
03328
03329
03330 vertex = s_vertex. top ();
03331 s_vertex. pop ();
03332 edge = s_edge. top ();
03333 s_edge. pop ();
03334 continue;
03335 }
03336
03337
03338 int_t next = g. getEdge (vertex, edge ++);
03339
03340
03341 if (!visited. test (next))
03342 {
03343
03344 if (next < nVert)
03345 result. addEdge (next);
03346
03347
03348 s_vertex. push (vertex);
03349 s_edge. push (edge);
03350
03351
03352 vertex = next;
03353 edge = 0;
03354
03355
03356 visited. set (vertex);
03357 s_visited. push (vertex);
03358 ++ nVisited;
03359 }
03360 }
03361
03362
03363 if (startVertex == nVert - 1)
03364 break;
03365
03366
03367 if (nVisited > (nVertG >> 6))
03368 {
03369 visited. clearall (nVertG);
03370 }
03371 else
03372 {
03373 while (!s_visited. empty ())
03374 {
03375 int_t vertex = s_visited. top ();
03376 s_visited. pop ();
03377 visited. clear (vertex);
03378 }
03379 }
03380 }
03381
03382
03383 visited. free ();
03384 return 0;
03385 }
03386
03392 template <class GraphType>
03393 inline int_t computePeriod (const GraphType &g)
03394 {
03395
03396 int_t nVertG = g. countVertices ();
03397 if (!nVertG)
03398 return 0;
03399
03400
03401 std::vector<int_t> visited (nVertG, 0);
03402
03403
03404
03405 std::stack<int_t> s_vertex;
03406 std::stack<int_t> s_edge;
03407
03408
03409 visited [0] = 1;
03410
03411
03412 int_t vertex = 0;
03413 int_t edge = 0;
03414 int_t level = 1;
03415 int_t period = 0;
03416 while (1)
03417 {
03418
03419
03420 if (edge >= g. countEdges (vertex))
03421 {
03422
03423 if (s_vertex. empty ())
03424 break;
03425
03426
03427 vertex = s_vertex. top ();
03428 s_vertex. pop ();
03429 edge = s_edge. top ();
03430 s_edge. pop ();
03431 -- level;
03432 continue;
03433 }
03434
03435
03436 int_t next = g. getEdge (vertex, edge ++);
03437
03438
03439 if (visited [next])
03440 {
03441
03442 int_t newPeriod = visited [next] - level - 1;
03443 if (newPeriod < 0)
03444 newPeriod = -newPeriod;
03445
03446
03447 int_t a = newPeriod;
03448 int_t b = period;
03449 while (b)
03450 {
03451 int_t t = b;
03452 b = a % b;
03453 a = t;
03454 }
03455 period = a;
03456
03457
03458
03459 if (period == 1)
03460 return period;
03461 }
03462
03463
03464 else
03465 {
03466
03467 s_vertex. push (vertex);
03468 s_edge. push (edge);
03469
03470
03471 vertex = next;
03472 edge = 0;
03473 ++ level;
03474
03475
03476 visited [vertex] = level;
03477 }
03478 }
03479
03480
03481 return period;
03482 }
03483
03489 template <class wType>
03490 inline int_t inclusionGraph (const diGraph<wType> &g, int_t nVert,
03491 diGraph<wType> &result)
03492 {
03493
03494 int_t nVertG = g. countVertices ();
03495 if (!nVertG)
03496 return 0;
03497
03498
03499 BitField visited;
03500 visited. allocate (nVertG);
03501 visited. clearall (nVertG);
03502
03503
03504 BitSets lists (nVertG, nVert);
03505
03506
03507 std::stack<int_t> s_vertex;
03508 std::stack<int_t> s_edge;
03509
03510
03511 int_t startVertex = 0;
03512 int_t vertex = 0;
03513 int_t edge = 0;
03514 visited. set (vertex);
03515 while (1)
03516 {
03517
03518
03519 if (edge >= g. countEdges (vertex))
03520 {
03521
03522
03523 if (s_vertex. empty ())
03524 {
03525 while ((startVertex < nVertG) &&
03526 (visited. test (startVertex)))
03527 ++ startVertex;
03528 if (startVertex >= nVertG)
03529 break;
03530 vertex = startVertex;
03531 edge = 0;
03532 visited. set (vertex);
03533 continue;
03534 }
03535
03536
03537 int_t prev = s_vertex. top ();
03538
03539
03540
03541
03542 if (vertex >= nVert)
03543 lists. addset (prev, vertex);
03544
03545
03546 vertex = prev;
03547 s_vertex. pop ();
03548 edge = s_edge. top ();
03549 s_edge. pop ();
03550 continue;
03551 }
03552
03553
03554 int_t next = g. getEdge (vertex, edge ++);
03555
03556
03557 if (next < nVert)
03558 lists. add (vertex, next);
03559
03560
03561 if (!visited. test (next))
03562 {
03563
03564 s_vertex. push (vertex);
03565 s_edge. push (edge);
03566
03567
03568 vertex = next;
03569 edge = 0;
03570 visited. set (vertex);
03571 }
03572
03573
03574
03575
03576 else if (next >= nVert)
03577 {
03578 lists. addset (vertex, next);
03579 }
03580 }
03581
03582
03583 for (int_t vertex = 0; vertex < nVert; ++ vertex)
03584 {
03585 result. addVertex ();
03586 int_t edge = lists. get (vertex);
03587 while (edge >= 0)
03588 {
03589 result. addEdge (edge);
03590 edge = lists. get (vertex, edge + 1);
03591 }
03592 }
03593
03594
03595 visited. free ();
03596 return 0;
03597 }
03598
03599
03600
03609 template<class wType, class TConn>
03610 inline int_t inclusionGraph (const diGraph<wType> &g, int_t nVert,
03611 diGraph<wType> &result, TConn &connections)
03612 {
03613
03614 int_t nVertG = g. countVertices ();
03615 if (!nVertG)
03616 return 0;
03617
03618
03619 BitField visited;
03620 visited. allocate (nVertG);
03621 visited. clearall (nVertG);
03622
03623
03624 BitSets forwardlists (nVertG, nVert);
03625
03626
03627 std::stack<int_t> s_vertex;
03628 std::stack<int_t> s_edge;
03629
03630
03631 int_t startVertex = 0;
03632 int_t vertex = 0;
03633 int_t edge = 0;
03634 visited. set (vertex);
03635 while (1)
03636 {
03637
03638
03639 if (edge >= g. countEdges (vertex))
03640 {
03641
03642
03643 if (s_vertex. empty ())
03644 {
03645 while ((startVertex < nVertG) &&
03646 (visited. test (startVertex)))
03647 ++ startVertex;
03648 if (startVertex >= nVertG)
03649 break;
03650 vertex = startVertex;
03651 edge = 0;
03652 visited. set (vertex);
03653 continue;
03654 }
03655
03656
03657 int_t prev = s_vertex. top ();
03658
03659
03660
03661
03662 if (vertex >= nVert)
03663 forwardlists. addset (prev, vertex);
03664
03665
03666 vertex = prev;
03667 s_vertex. pop ();
03668 edge = s_edge. top ();
03669 s_edge. pop ();
03670 continue;
03671 }
03672
03673
03674 int_t next = g. getEdge (vertex, edge ++);
03675
03676
03677 if (next < nVert)
03678 forwardlists. add (vertex, next);
03679
03680
03681 if (!visited. test (next))
03682 {
03683
03684 s_vertex. push (vertex);
03685 s_edge. push (edge);
03686
03687
03688 vertex = next;
03689 edge = 0;
03690 visited. set (vertex);
03691 }
03692
03693
03694
03695
03696 else if (next >= nVert)
03697 {
03698 forwardlists. addset (vertex, next);
03699 }
03700 }
03701
03702
03703
03704
03705 BitSets backlists (nVertG, nVert);
03706
03707 diGraph<wType> gT;
03708 g. transpose (gT);
03709
03710
03711 if (!s_vertex. empty () || !s_edge. empty ())
03712 throw "DEBUG: Nonempty stacks in 'inclusionGraph'.";
03713
03714
03715 visited. clearall (nVertG);
03716
03717
03718 startVertex = 0;
03719 vertex = 0;
03720 edge = 0;
03721 visited. set (vertex);
03722 while (1)
03723 {
03724
03725
03726 if (edge >= gT. countEdges (vertex))
03727 {
03728
03729
03730 if (s_vertex. empty ())
03731 {
03732 while ((startVertex < nVertG) &&
03733 (visited. test (startVertex)))
03734 ++ startVertex;
03735 if (startVertex >= nVertG)
03736 break;
03737 vertex = startVertex;
03738 edge = 0;
03739 visited. set (vertex);
03740 continue;
03741 }
03742
03743
03744 int_t prev = s_vertex. top ();
03745
03746
03747
03748
03749 if (vertex >= nVert)
03750 backlists. addset (prev, vertex);
03751
03752
03753 vertex = prev;
03754 s_vertex. pop ();
03755 edge = s_edge. top ();
03756 s_edge. pop ();
03757 continue;
03758 }
03759
03760
03761 int_t next = gT. getEdge (vertex, edge ++);
03762
03763
03764 if (next < nVert)
03765 backlists. add (vertex, next);
03766
03767
03768 if (!visited. test (next))
03769 {
03770
03771 s_vertex. push (vertex);
03772 s_edge. push (edge);
03773
03774
03775 vertex = next;
03776 edge = 0;
03777 visited. set (vertex);
03778 }
03779
03780
03781
03782
03783 else if (next >= nVert)
03784 {
03785 backlists. addset (vertex, next);
03786 }
03787 }
03788
03789
03790
03791
03792 for (int_t v = nVert; v < nVertG; ++ v)
03793 {
03794 int_t bvertex = backlists. get (v);
03795 while (bvertex >= 0)
03796 {
03797 int_t fvertex = forwardlists. get (v);
03798 while (fvertex >= 0)
03799 {
03800 connections (bvertex, fvertex, v);
03801 fvertex = forwardlists. get (v, fvertex + 1);
03802 }
03803 bvertex = backlists. get (v, bvertex + 1);
03804 }
03805 }
03806
03807
03808
03809
03810 for (int_t vertex = 0; vertex < nVert; ++ vertex)
03811 {
03812 result. addVertex ();
03813 int_t edge = forwardlists. get (vertex);
03814 while (edge >= 0)
03815 {
03816 result. addEdge (edge);
03817 edge = forwardlists. get (vertex, edge + 1);
03818 }
03819 }
03820
03821
03822 visited. free ();
03823 return 0;
03824 }
03825
03826
03827
03831 template <class wType, class matrix>
03832 inline void graph2matrix (const diGraph<wType> &g, matrix &m)
03833 {
03834 int_t nVert = g. countVertices ();
03835 for (int_t v = 0; v < nVert; ++ v)
03836 {
03837 int_t nEdges = g. countEdges (v);
03838 for (int_t e = 0; e < nEdges; ++ e)
03839 {
03840 int_t w = g. getEdge (v, e);
03841 m [v] [w] = 1;
03842 }
03843 }
03844 return;
03845 }
03846
03851 template <class wType, class matrix>
03852 inline void matrix2graph (const matrix &m, int_t n, diGraph<wType> &g)
03853 {
03854 for (int_t v = 0; v < n; ++ v)
03855 {
03856 g. addVertex ();
03857 for (int_t w = 0; w < n; ++ w)
03858 if (m [v] [w])
03859 g. addEdge (w);
03860 }
03861 return;
03862 }
03863
03864
03865
03869 template <class matrix>
03870 inline void transitiveClosure (matrix &m, int_t n)
03871 {
03872 for (int_t k = 0; k < n; ++ k)
03873 {
03874 for (int_t i = 0; i < n; ++ i)
03875 {
03876 for (int_t j = 0; j < n; ++ j)
03877 {
03878 if (m [i] [k] && m [k] [j])
03879 m [i] [j] = 1;
03880 }
03881 }
03882 }
03883 return;
03884 }
03885
03893 template <class matrix>
03894 inline void transitiveReduction (matrix &m, int_t n)
03895 {
03896 for (int_t k = n - 1; k >= 0; -- k)
03897 {
03898 for (int_t i = 0; i < n; ++ i)
03899 {
03900 for (int_t j = 0; j < n; ++ j)
03901 {
03902 if (m [i] [k] && m [k] [j])
03903 m [i] [j] = 0;
03904 }
03905 }
03906 }
03907 return;
03908 }
03909
03912 template <class wType>
03913 inline void transitiveReduction (const diGraph<wType> &g,
03914 diGraph<wType> &gRed)
03915 {
03916 int_t nVert = g. countVertices ();
03917 if (nVert <= 0)
03918 return;
03919 flatMatrix<char> m (nVert);
03920 m. clear (0);
03921 graph2matrix (g, m);
03922 transitiveClosure (m, nVert);
03923 transitiveReduction (m, nVert);
03924 matrix2graph (m, nVert, gRed);
03925 return;
03926 }
03927
03928
03929 }
03930 }
03931
03932 #endif // _CHOMP_STRUCT_DIGRAPH_H_
03933
03935