35#ifndef _CHOMP_STRUCT_DIGRAPH_H_
36#define _CHOMP_STRUCT_DIGRAPH_H_
67template <
class numType>
72 static inline numType
add_down (
const numType &x,
const numType &y)
76 static inline numType
add_up (
const numType &x,
const numType &y)
80 static inline numType
sub_down (
const numType &x,
const numType &y)
84 static inline numType
sub_up (
const numType &x,
const numType &y)
88 static inline numType
mul_down (
const numType &x,
const numType &y)
92 static inline numType
mul_up (
const numType &x,
const numType &y)
96 static inline numType
div_down (
const numType &x,
const numType &y)
104 static inline numType
div_up (
const numType &x,
const numType &y)
141template <
class wType =
int>
178 template <
class Table>
211 template <
class Table>
217 template <
class Table>
221 template <
class wType1>
223 bool copyweights =
false)
const;
228 template <
class Table,
class wType1>
230 bool copyweights =
false)
const;
235 template <
class Table,
class Color>
236 void DFScolor (Table &tab,
const Color &color,
237 int_t vertex = 0)
const;
240 template <
class Table,
class Color>
242 int_t vertex = 0)
const;
245 template <
class Table,
class Color>
247 int_t vertex = 0)
const;
251 template <
class Table>
263 template <
class Table1,
class Table2,
class Table3>
265 Table3 &compEnds,
bool nontrivial =
false,
288 template <
class lenTable,
class weightsType,
class roundType>
290 lenTable &len, weightsType &edgeWeights)
const;
293 template <
class lenTable,
class roundType>
295 lenTable &len)
const;
298 template <
class lenTable>
311 template <
class lenTable,
class predTable,
class roundType>
313 lenTable &len, wType *infinity, predTable pred)
const;
316 template <
class lenTable,
class predTable>
318 predTable pred)
const;
323 template <
class roundType>
354 template <
class arrayType,
class roundType>
355 wType
FloydWarshall (
const roundType &rounding, arrayType &arr,
356 bool setInfinity =
true,
bool ignoreNegLoop =
false)
const;
359 template <
class arrayType>
360 wType
FloydWarshall (arrayType &arr,
bool setInfinity =
true,
361 bool ignoreNegLoop =
false)
const;
371 template <
class arrayType,
class roundType>
372 wType
Johnson (
const roundType &rounding, arrayType &arr,
373 bool setInfinity =
true,
bool ignoreNegLoop =
false)
const;
376 template <
class arrayType>
377 wType
Johnson (arrayType &arr,
bool setInfinity =
true,
378 bool ignoreNegLoop =
false)
const;
389 template <
class roundType>
391 bool ignoreNegLoop =
false,
int sparseGraph = -1)
const;
395 int sparseGraph = -1)
const;
411 template <
class roundType>
422 template <
class roundType,
class predType>
427 template <
class roundType>
436 template <
class arrayType,
class roundType>
438 const arrayType &starting,
int_t n)
const;
441 template <
class arrayType>
446 template <
class wType1,
class wType2>
451 template <
class outType>
452 outType &
show (outType &out,
bool showWeights =
false)
const;
470 template <
class Table>
472 int_t &counter)
const;
475 template <
class Table>
477 int_t &counter)
const;
481 template <
class Table1,
class Table2>
483 int_t treeNumber,
int_t countTrees, Table2 &compVertices,
488 template <
class Table1,
class Table2>
490 int_t treeNumber,
int_t countTrees, Table2 &compVertices,
584template <
class wType>
586 edgeEnds (1024), edges (4096), weights (4096)
591template <
class wType>
599template <
class wType1,
class wType2>
603 if (g1. nVertices != g2. nVertices)
607 for (
int_t i = 0; i < g1. nVertices; ++ i)
609 if (g1. edgeEnds [i] != g2. edgeEnds [i])
612 int_t nEdges = g1. edgeEnds [g1. nVertices - 1];
613 for (
int_t i = 0; i < nEdges; ++ i)
615 if (g1. edges [i] != g2. edges [i])
621template <
class wType1,
class wType2>
630template <
class wType>
634 edgeEnds.
swap (g. edgeEnds);
635 edges.
swap (g. edges);
636 weights.
swap (g. weights);
640template <
class wType>
643 edgeEnds [nVertices] = nVertices ? edgeEnds [nVertices - 1] :
644 static_cast<int_t> (0);
649template <
class wType>
653 throw "Trying to add an edge to an empty graph.";
657 throw "Trying to add an edge to a negative vertex.";
658 int_t &offset = edgeEnds [nVertices - 1];
660 throw "Too many edges in a diGraph (limit = 2,147,483,647).";
661 edges [offset] = target;
666template <
class wType>
670 throw "Trying to add an edge to an empty graph.";
674 throw "Trying to add an edge to a negative vertex.";
675 int_t &offset = edgeEnds [nVertices - 1];
677 throw "Too many edges in a diGraph (limit = 2,147,483,647).";
678 edges [offset] = target;
679 weights [offset] = weight;
684template <
class wType>
689 weights [i] = weight;
691 weights [edgeEnds [vertex - 1] + i] = weight;
695template <
class wType>
698 weights [edge] = weight;
702template <
class wType>
template <
class Table>
707 int_t nEdges = edgeEnds [nVertices - 1];
708 for (
int_t i = 0; i < nEdges; ++ i)
709 weights [i] = tab [i];
713template <
class wType>
717 throw "Trying to remove a vertex from the empty graph.";
722template <
class wType>
726 if ((vertex < 0) || (vertex >= nVertices))
727 throw "Trying to remove a vertex that is not in the graph.";
733 for (
int_t v = 0; v < nVertices; ++ v)
736 if (!skipped && (v == vertex))
738 curEdge = edgeEnds [v];
744 int_t maxEdge = edgeEnds [v];
745 for (; curEdge < maxEdge; ++ curEdge)
747 if (edges [curEdge] == vertex)
749 int_t target = edges [curEdge];
750 edges [newEdge] = (target < vertex) ? target :
753 weights [newEdge] = weights [curEdge];
756 edgeEnds [v - skipped] = newEdge;
760 nVertices -= skipped;
765template <
class wType>
771template <
class wType>
777 return edgeEnds [nVertices - 1];
780template <
class wType>
786 return edgeEnds [vertex] - edgeEnds [vertex - 1];
789template <
class wType>
795 return edges [edgeEnds [vertex - 1] + i];
798template <
class wType>
804 return weights [edgeEnds [vertex - 1] + i];
807template <
class wType>
810 return weights [edge];
813template <
class wType>
template <
class Table>
818 int_t nEdges = edgeEnds [nVertices - 1];
819 for (
int_t i = 0; i < nEdges; ++ i)
820 tab [i] = weights [i];
824template <
class wType>
template <
class Table>
828 for (
int_t curVertex = 0; curVertex < nVertices; ++ curVertex)
830 int_t maxEdge = edgeEnds [curVertex];
831 while (curEdge < maxEdge)
833 tab [curEdge] [0] = curVertex;
834 tab [curEdge] [1] = edges [curEdge];
841template <
class wType>
template <
class wType1>
843 bool copyweights)
const
846 result. nVertices = nVertices;
851 for (
int_t i = 0; i < nVertices; ++ i)
852 result. edgeEnds [i] = 0;
853 int_t nEdges = edgeEnds [nVertices - 1];
854 for (
int_t i = 0; i < nEdges; ++ i)
856 if (edges [i] < nVertices - 1)
857 ++ result. edgeEnds [edges [i] + 1];
859 for (
int_t i = 2; i < nVertices; ++ i)
860 result. edgeEnds [i] += result. edgeEnds [i - 1];
864 for (
int_t i = 0; i < nVertices; ++ i)
866 for (; curEdge < edgeEnds [i]; ++ curEdge)
868 int_t j = edges [curEdge];
869 int_t &offset = result. edgeEnds [j];
870 result. edges [offset] = i;
872 result. weights [offset] = weights [curEdge];
879template <
class wType>
template <
class Table,
class wType1>
881 const Table &tab,
bool copyweights)
const
886 for (
int_t i = 0; i < nVertices; ++ i)
889 numbers [i] = curNumber ++;
895 for (
int_t i = 0; i < nVertices; ++ i)
900 int_t firstEdge = i ? edgeEnds [i - 1] :
901 static_cast<int_t> (0);
902 int_t endEdge = edgeEnds [i];
903 for (
int_t j = firstEdge; j < endEdge; ++ j)
905 int_t edgeEnd = edges [j];
906 if (numbers [edgeEnd] >= 0)
909 g. addEdge (numbers [edgeEnd],
912 g. addEdge (numbers [edgeEnd]);
924template <
class wType>
template <
class Table,
class Color>
926 const Color &color,
int_t vertex)
const
928 tab [vertex] = color;
929 int_t maxEdge = edgeEnds [vertex];
930 for (
int_t i = vertex ? edgeEnds [vertex - 1] :
931 static_cast<int_t> (0); i < maxEdge; ++ i)
933 int_t next = edges [i];
934 if (tab [next] != color)
935 DFScolorRecurrent (tab, color, next);
940template <
class wType>
template <
class Table,
class Color>
945 std::stack<int_t> s_vertex;
946 std::stack<int_t> s_edge;
947 std::stack<int_t> s_maxedge;
950 tab [vertex] = color;
953 int_t edge = vertex ? edgeEnds [vertex - 1] :
954 static_cast<int_t> (0);
955 int_t maxedge = edgeEnds [vertex];
964 if (s_vertex. empty ())
968 vertex = s_vertex. top ();
970 edge = s_edge. top ();
972 maxedge = s_maxedge. top ();
978 int_t next = edges [edge ++];
979 if (tab [next] != color)
982 s_vertex. push (vertex);
984 s_maxedge. push (maxedge);
990 tab [vertex] = color;
993 edge = vertex ? edgeEnds [vertex - 1] :
994 static_cast<int_t> (0);
995 maxedge = edgeEnds [vertex];
1000template <
class wType>
template <
class Table,
class Color>
1004 DFScolorStack (tab, color, vertex);
1010template <
class wType>
template <
class Table>
1018 for (
int_t edge = vertex ? edgeEnds [vertex - 1] :
1019 static_cast<int_t> (0);
1020 edge < edgeEnds [vertex]; ++ edge)
1022 int_t next = edges [edge];
1024 DFSfinishTimeRecurrent (tab, next, counter);
1028 tab [vertex] = ++ counter;
1032template <
class wType>
template <
class Table>
1034 int_t &counter)
const
1037 std::stack<int_t> s_vertex;
1038 std::stack<int_t> s_edge;
1039 std::stack<int_t> s_maxedge;
1045 int_t edge = vertex ? edgeEnds [vertex - 1] :
1046 static_cast<int_t> (0);
1047 int_t maxedge = edgeEnds [vertex];
1053 if (edge >= maxedge)
1057 tab [vertex] = ++ counter;
1060 if (s_vertex. empty ())
1064 vertex = s_vertex. top ();
1066 edge = s_edge. top ();
1068 maxedge = s_maxedge. top ();
1074 int_t next = edges [edge ++];
1078 s_vertex. push (vertex);
1079 s_edge. push (edge);
1080 s_maxedge. push (maxedge);
1089 edge = vertex ? edgeEnds [vertex - 1] :
1090 static_cast<int_t> (0);
1091 maxedge = edgeEnds [vertex];
1098template <
class wType>
template <
class Table>
1102 for (
int_t i = 0; i < nVertices; ++ i)
1107 for (
int_t i = 0; i < nVertices; ++ i)
1110 DFSfinishTimeStack (tab, i, counter);
1113 #ifdef DIGRAPH_DEBUG
1115 for (
int_t i = 0; i < nVertices; ++ i)
1117 int_t counterdebug = 0;
1118 for (
int_t i = 0; i < nVertices; ++ i)
1120 DFSfinishTimeRecurrent (tabdebug, i, counterdebug);
1121 if (counter != counterdebug)
1122 throw "DFSfinishTime: Wrong counter.";
1123 for (
int_t i = 0; i < nVertices; ++ i)
1125 if (tab [i] != tabdebug [i])
1127 sbug <<
"\nDFSfinishTime error: tabRec [" << i <<
1128 "] = " << tab [i] <<
", tabStack [" << i <<
1129 "] = " << tabdebug [i] <<
".\n";
1130 throw "DFSfinishTime: Wrong numbers.";
1133 sbug <<
"DEBUG: DFSfinishTime OK. ";
1140template <
class wType>
template <
class Table1,
class Table2>
1143 Table2 &compVertices,
int_t &curVertex,
1147 compVertices [curVertex ++] = vertex;
1150 tab [vertex] = treeNumber;
1156 for (
int_t edge = vertex ? edgeEnds [vertex - 1] :
1157 static_cast<int_t> (0);
1158 edge < edgeEnds [vertex]; ++ edge)
1160 int_t next = edges [edge];
1162 loop |= DFSforestRecurrent (tab, ntab, next,
1163 treeNumber, countTrees, compVertices,
1164 curVertex, sccGraph, sccEdgeAdded);
1165 else if (tab [next] == treeNumber)
1169 int_t target = ntab [treeNumber - 1];
1170 if (sccEdgeAdded [target] != treeNumber)
1172 sccGraph -> addEdge (target);
1173 sccEdgeAdded [target] = treeNumber;
1180 int_t target = ntab [tab [next] - 1];
1181 if ((target >= 0) &&
1182 (sccEdgeAdded [target] != treeNumber))
1184 sccGraph -> addEdge (target);
1185 sccEdgeAdded [target] = treeNumber;
1193template <
class wType>
template <
class Table1,
class Table2>
1196 Table2 &compVertices,
int_t &curVertex,
1200 std::stack<int_t> s_vertex;
1201 std::stack<int_t> s_edge;
1202 std::stack<int_t> s_maxedge;
1203 std::stack<bool> s_loop;
1206 compVertices [curVertex ++] = vertex;
1209 tab [vertex] = treeNumber;
1215 int_t edge = vertex ? edgeEnds [vertex - 1] :
1216 static_cast<int_t> (0);
1217 int_t maxedge = edgeEnds [vertex];
1222 if (edge >= maxedge)
1225 if (s_vertex. empty ())
1229 vertex = s_vertex. top ();
1231 edge = s_edge. top ();
1233 maxedge = s_maxedge. top ();
1235 loop |= s_loop. top ();
1241 int_t next = edges [edge ++];
1245 s_vertex. push (vertex);
1246 s_edge. push (edge);
1247 s_maxedge. push (maxedge);
1248 s_loop. push (loop);
1254 compVertices [curVertex ++] = vertex;
1257 tab [vertex] = treeNumber;
1261 edge = vertex ? edgeEnds [vertex - 1] :
1262 static_cast<int_t> (0);
1263 maxedge = edgeEnds [vertex];
1265 else if (tab [next] == treeNumber)
1269 int_t target = ntab [treeNumber - 1];
1270 if (sccEdgeAdded [target] != treeNumber)
1272 sccGraph -> addEdge (target);
1273 sccEdgeAdded [target] = treeNumber;
1280 int_t target = ntab [tab [next] - 1];
1281 if ((target >= 0) &&
1282 (sccEdgeAdded [target] != treeNumber))
1284 sccGraph -> addEdge (target);
1285 sccEdgeAdded [target] = treeNumber;
1293template <
class wType>
template <
class Table1,
class Table2,
class Table3>
1295 Table2 &compVertices, Table3 &compEnds,
bool nontrivial,
1301 for (
int_t i = 0; i < nVertices; ++ i)
1311 int_t *sccEdgeAdded = sccGraph ?
new int_t [nVertices] :
1312 static_cast<int_t *
> (0);
1315 for (
int_t n = 0; n < nVertices; ++ n)
1316 sccEdgeAdded [n] = -1;
1320 int_t treeNumber = 0;
1323 int_t countTrees = 0;
1324 int_t curVertex = 0;
1327 for (
int_t i = 0; i < nVertices; ++ i)
1330 int_t vertex = ordered [i];
1338 sccGraph -> addVertex ();
1341 int_t prevVertex = curVertex;
1345 ntab [treeNumber] = countTrees;
1347 bool loop = DFSforestStack (tab, ntab, vertex,
1348 treeNumber, countTrees, compVertices,
1349 curVertex, sccGraph, sccEdgeAdded);
1352 compEnds [countTrees ++] = curVertex;
1355 if (nontrivial && !loop)
1358 curVertex = prevVertex;
1361 ntab [treeNumber - 1] = -1;
1362 sccGraph -> removeVertex ();
1367 #ifdef DIGRAPH_DEBUG
1374 for (
int_t i = 0; i < nVertices; ++ i)
1383 int_t *sccEdgeAddeddebug = sccGraph ?
new int_t [nVertices] :
1384 static_cast<int_t> (0);
1387 for (
int_t n = 0; n < nVertices; ++ n)
1388 sccEdgeAddeddebug [n] = -1;
1391 int_t treeNumberdebug = 0;
1394 int_t countTreesdebug = 0;
1395 int_t curVertexdebug = 0;
1397 int_t *compVerticesdebug =
new int_t [nVertices];
1398 int_t *compEndsdebug =
new int_t [nVertices];
1401 for (
int_t i = 0; i < nVertices; ++ i)
1404 int_t vertex = ordered [i];
1407 if (tabdebug [vertex])
1412 sccGraphdebug -> addVertex ();
1415 int_t prevVertex = curVertexdebug;
1419 ntabdebug [treeNumberdebug] = countTreesdebug;
1421 bool loop = DFSforestRecurrent (tabdebug, ntabdebug, vertex,
1422 treeNumberdebug, countTreesdebug, compVerticesdebug,
1423 curVertexdebug, sccGraphdebug, sccEdgeAddeddebug);
1426 compEndsdebug [countTreesdebug ++] = curVertexdebug;
1429 if (nontrivial && !loop)
1432 curVertexdebug = prevVertex;
1435 ntabdebug [treeNumberdebug - 1] = -1;
1436 sccGraphdebug -> removeVertex ();
1440 if (countTrees != countTreesdebug)
1441 throw "DFSforest: Wrong countTrees.";
1442 for (
int_t i = 0; i < countTrees; ++ i)
1443 if (compEnds [i] != compEndsdebug [i])
1444 throw "DFSforest: Wrong compEnds.";
1445 for (
int_t i = 0; i < compEndsdebug [countTrees - 1]; ++ i)
1446 if (compVertices [i] != compVerticesdebug [i])
1447 throw "DFSforest: Wrong vertices.";
1448 if (curVertex != curVertexdebug)
1449 throw "DFSforest: Wrong curVertex.";
1450 for (
int_t i = 0; i < nVertices; ++ i)
1451 if (tab [i] != tabdebug [i])
1452 throw "DFSforest: Wrong tab.";
1455 for (
int_t i = 0; i < nVertices; ++ i)
1456 if (ntab [i] != ntabdebug [i])
1457 throw "DFSforest: Wrong ntab.";
1458 if (*sccGraph != *sccGraphdebug)
1459 throw "DFSforest: Wrong graph.";
1463 for (
int_t i = 0; i < nVertices; ++ i)
1464 if (sccEdgeAdded [i] != sccEdgeAddeddebug [i])
1465 throw "DFSforest: Wrong sccEdgeAdded.";
1467 if (treeNumber != treeNumberdebug)
1468 throw "DFSforest: Wrong treeNumber.";
1469 sbug <<
"DEBUG: DFSforest OK. ";
1471 sbug <<
"(Graphs not compared.) ";
1472 delete [] compVerticesdebug;
1473 delete [] compEndsdebug;
1475 delete sccGraphdebug;
1476 delete [] ntabdebug;
1478 if (sccEdgeAddeddebug)
1479 delete [] sccEdgeAddeddebug;
1483 delete [] sccEdgeAdded;
1489template <
class wType>
1494 if ((source < 0) || (source >= nVertices) ||
1495 (destination < 0) || (destination >= nVertices))
1497 throw "diGraph - shortest path: Wrong vertex number.";
1503 visited. allocate (nVertices);
1504 visited. clearall (nVertices);
1507 std::queue<int_t> q_vertex;
1508 std::queue<int_t> q_depth;
1511 int_t vertex = source;
1517 visited. set (vertex);
1523 int_t firstedge = vertex ? edgeEnds [vertex - 1] :
1524 static_cast<int_t> (0);
1525 int_t maxedge = edgeEnds [vertex];
1528 for (
int_t edge = firstedge; edge < maxedge; ++ edge)
1531 int_t next = edges [edge];
1537 if (next == destination)
1544 if (visited. test (next))
1548 q_vertex. push (next);
1549 q_depth. push (depth);
1555 if (q_vertex. empty ())
1562 vertex = q_vertex. front ();
1564 depth = q_depth. front ();
1569template <
class wType>
1572 return shortestPath (origin, origin);
1575template <
class wType>
1576template <
class lenTable,
class weightsType,
class roundType>
1578 int_t source, lenTable &len, weightsType &edgeWeights)
const
1585 for (
int_t v = 0; v < nVertices; ++ v)
1590 int_t number = Q. Insert (w);
1593 throw "Wrong implementation of Fibonacci heap "
1594 "for this version of Dijkstra.";
1600 for (
int_t i = 0; i < nVertices; ++ i)
1603 int_t minVertex = Q. Minimum ();
1604 posWeight minWeight = Q. ExtractMinimum ();
1606 if (minWeight. isInfinity ())
1608 len [minVertex] = -1;
1611 wType minValue = minWeight. getValue ();
1612 len [minVertex] = minValue;
1616 int_t edge = minVertex ? edgeEnds [minVertex - 1] :
1617 static_cast<int_t> (0);
1618 int_t maxEdge = edgeEnds [minVertex];
1619 for (; edge < maxEdge; ++ edge)
1622 int_t nextVertex = edges [edge];
1626 const posWeight &nextWeight = Q. Value (nextVertex);
1627 wType newWeight = rounding. add_down (minValue,
1628 edgeWeights [edge]);
1631 if (nextWeight. isInfinity () ||
1632 (newWeight < nextWeight. getValue ()))
1634 Q. DecreaseKey (nextVertex,
1642template <
class wType>
1643template <
class lenTable,
class roundType>
1645 int_t source, lenTable &len)
const
1647 this -> Dijkstra (rounding, source, len,
this -> weights);
1651template <
class wType>
1652template <
class lenTable>
1656 this -> Dijkstra (rounding, source, len);
1660template <
class wType>
template <
class lenTable,
class predTable,
1663 int_t source, lenTable &len, wType *infinity, predTable pred)
const
1666 if ((source < 0) || (source >= nVertices))
1667 throw "Bellman-Ford: Wrong source vertex number.";
1671 finite. allocate (nVertices);
1672 finite. clearall (nVertices);
1673 finite. set (source);
1677 int_t countNegative = 0;
1680 for (
int_t i = 0; i < nVertices; ++ i)
1684 bool noNegativeLoop =
false;
1686 for (; counter <= nVertices; ++ counter)
1688 bool modified =
false;
1690 for (
int_t vertex = 0; vertex < nVertices; ++ vertex)
1692 int_t maxEdge = edgeEnds [vertex];
1693 if (!finite. test (vertex))
1698 for (; curEdge < maxEdge; ++ curEdge)
1700 int_t next = edges [curEdge];
1701 wType newlen = rounding. add_down
1702 (len [vertex], weights [curEdge]);
1703 if (!finite. test (next))
1707 len [next] = newlen;
1708 pred [next] = vertex;
1712 else if (newlen < len [next])
1715 if (!(len [next] < 0) &&
1720 len [next] = newlen;
1721 pred [next] = vertex;
1725 if (countNegative == nVertices)
1727 noNegativeLoop =
false;
1733 noNegativeLoop =
true;
1743 counter << ((counter > 1) ?
" loops (" :
" loop (") <<
1744 nVertices <<
" vertices, " << countNegative <<
1746 (noNegativeLoop ?
"No negative loops.\n" :
1747 "A negative loop found.\n");
1751 if (infinity && noNegativeLoop)
1755 for (
int_t i = 0; i < nVertices; ++ i)
1757 if (!finite. test (i))
1764 else if (infty < len [i])
1770 for (
int_t i = 0; i < nVertices; ++ i)
1772 if (!finite. test (i))
1779 return noNegativeLoop;
1782template <
class wType>
template <
class lenTable,
class predTable>
1784 wType *infinity, predTable pred)
const
1787 return this -> BellmanFord (rounding, source, len, infinity, pred);
1790template <
class wType>
template <
class roundType>
1795 wType *len = len_ptr. get ();
1796 wType *infinity = 0;
1798 return BellmanFord (rounding, source, len, infinity, tab);
1801template <
class wType>
1805 return BellmanFord (rounding, source);
1808template <
class wType>
1812 std::vector<edgeTriple> edgeTriples (countEdges ());
1815 for (
int_t vert = 0; vert < nVertices; ++ vert)
1817 while (curEdge < edgeEnds [vert])
1821 e. vert2 = edges [curEdge];
1822 e. weight = weights [curEdge];
1827 std::sort (edgeTriples. begin (), edgeTriples. end ());
1831 int_t *root = root_ptr. get ();
1832 for (
int_t vert = 0; vert < nVertices; ++ vert)
1838 wType totalWeight = 0;
1839 int_t nEdges = countEdges ();
1840 for (
int_t curEdge = 0; curEdge < nEdges; ++ curEdge)
1845 int_t root1 = e. vert1;
1846 while (root [root1] >= 0)
1848 root1 = root [root1];
1850 int_t vert1 = e. vert1;
1851 while (root [vert1] >= 0)
1853 int_t next = root [vert1];
1854 root [vert1] = root1;
1857 int_t root2 = e. vert2;
1858 while (root [root2] >= 0)
1860 root2 = root [root2];
1862 int_t vert2 = e. vert2;
1863 while (root [vert2] >= 0)
1865 int_t next = root [vert2];
1866 root [vert2] = root2;
1875 totalWeight += e. weight;
1878 root [root1] = root2;
1883template <
class wType>
1887 std::vector<edgeTriple> edgeTriples (countEdges ());
1890 for (
int_t vert = 0; vert < nVertices; ++ vert)
1892 while (curEdge < edgeEnds [vert])
1896 e. vert2 = edges [curEdge];
1897 e. weight = weights [curEdge];
1902 std::sort (edgeTriples. begin (), edgeTriples. end ());
1906 (
new int_t [nVertices]);
1907 int_t *forest = forest_ptr. get ();
1909 (
new int_t [nVertices]);
1910 int_t *next = next_ptr. get ();
1912 (
new int_t [nVertices]);
1913 int_t *prev = prev_ptr. get ();
1914 for (
int_t vert = 0; vert < nVertices; ++ vert)
1916 forest [vert] = vert;
1922 wType totalWeight = 0;
1923 int_t nEdges = countEdges ();
1924 for (
int_t curEdge = 0; curEdge < nEdges; ++ curEdge)
1928 if (forest [e. vert1] == forest [e. vert2])
1932 totalWeight += e. weight;
1935 int_t vert1 = e. vert1;
1936 while (next [vert1] >= 0)
1938 vert1 = next [vert1];
1942 int_t vert2 = e. vert2;
1943 while (prev [vert2] >= 0)
1945 vert2 = prev [vert2];
1949 next [vert1] = vert2;
1950 prev [vert2] = vert1;
1951 int_t treeNumber = forest [vert1];
1954 forest [vert2] = treeNumber;
1955 vert2 = next [vert2];
1961template <
class wType>
1962template <
class arrayType,
class roundType>
1964 arrayType &arr,
bool setInfinity,
bool ignoreNegLoop)
const
1972 for (
int_t i = 0; i < nVertices; ++ i)
1974 finite [i]. allocate (nVertices);
1975 finite [i]. clearall (nVertices);
1980 for (
int_t source = 0; source < nVertices; ++ source)
1982 bool diagset =
false;
1983 while (curEdge < edgeEnds [source])
1985 int_t target = edges [curEdge];
1986 const wType &weight = weights [curEdge];
1987 if (source == target)
1991 arr [source] [target] = weight;
1997 arr [source] [target] = weight;
1998 finite [source]. set (target);
2003 arr [source] [source] = 0;
2004 finite [source]. set (source);
2008 for (
int_t k = 0; k < nVertices; ++ k)
2010 for (
int_t i = 0; i < nVertices; ++ i)
2012 if (!finite [i]. test (k))
2014 for (
int_t j = 0; j < nVertices; ++ j)
2016 if (!finite [k]. test (j))
2018 const wType sum = rounding. add_down
2019 (arr [i] [k], arr [k] [j]);
2020 if (finite [i]. test (j))
2022 if (sum < arr [i] [j])
2028 finite [i]. set (j);
2038 for (
int_t i = 0; i < nVertices; ++ i)
2040 if (arr [i] [i] < 0)
2041 throw "Negative loop in Floyd-Warshall.";
2052 wType &infinity = result;
2053 for (
int_t i = 0; i < nVertices; ++ i)
2055 for (
int_t j = 0; j < nVertices; ++ j)
2057 if (finite [i]. test (j) &&
2058 (infinity <= arr [i] [j]))
2060 infinity = rounding. add_up
2065 for (
int_t i = 0; i < nVertices; ++ i)
2067 for (
int_t j = 0; j < nVertices; ++ j)
2069 if (!finite [i]. test (j))
2070 arr [i] [j] = infinity;
2078 wType &minWeight = result;
2079 bool firstTime =
true;
2080 for (
int_t i = 0; i < nVertices; ++ i)
2082 for (
int_t j = 0; j < nVertices; ++ j)
2084 if (finite [i]. test (j))
2088 minWeight = arr [i] [j];
2091 else if (arr [i] [j] < minWeight)
2093 minWeight = arr [i] [j];
2101 for (
int_t i = 0; i < nVertices; ++ i)
2102 finite [i]. free ();
2108template <
class wType>
2109template <
class arrayType>
2111 bool setInfinity,
bool ignoreNegLoop)
const
2114 return FloydWarshall (rounding, arr, setInfinity, ignoreNegLoop);
2117template <
class wType>
2118template <
class arrayType,
class roundType>
2120 arrayType &arr,
bool setInfinity,
bool ignoreNegLoop)
const
2123 if (
false &&
sbug. show)
2126 wType res = FloydWarshall (rounding,
2127 arr, setInfinity, ignoreNegLoop);
2129 ", " << (double) stopWatch <<
" sec]\n";
2141 wType *len =
new wType [nVertices];
2142 for (
int_t i = 0; i < nVertices; ++ i)
2146 bool noNegativeLoop =
false;
2148 for (; counter <= nVertices; ++ counter)
2150 bool modified =
false;
2152 for (
int_t vertex = 0; vertex < nVertices; ++ vertex)
2154 int_t maxEdge = edgeEnds [vertex];
2155 for (; curEdge < maxEdge; ++ curEdge)
2157 int_t next = edges [curEdge];
2158 wType newlen = rounding. add_down
2159 (len [vertex], weights [curEdge]);
2160 if (newlen < len [next])
2164 if (counter > nVertices)
2166 std::cout << vertex;
2169 len [next] = newlen;
2175 noNegativeLoop =
true;
2180 if (!ignoreNegLoop && !noNegativeLoop)
2181 throw "Negative loop found in Johnson's algorithm.";
2184 wType *newWeights =
new wType [edgeEnds [nVertices - 1]];
2186 for (
int_t vertex = 0; vertex < nVertices; ++ vertex)
2188 int_t maxEdge = edgeEnds [vertex];
2189 for (; edge < maxEdge; ++ edge)
2191 wType w = weights [edge];
2192 w = rounding. add_down (w, len [vertex]);
2193 w = rounding. sub_down (w, len [edges [edge]]);
2194 newWeights [edge] = (w < 0) ?
2195 static_cast<wType
> (0) : w;
2202 for (
int_t u = 0; u < nVertices; ++ u)
2204 this -> Dijkstra (rounding, u, arr [u], newWeights);
2206 delete [] newWeights;
2214 wType &infinity = result;
2215 for (
int_t u = 0; u < nVertices; ++ u)
2217 for (
int_t v = 0; v < nVertices; ++ v)
2219 wType w = arr [u] [v];
2222 w = rounding. add_down (w, len [v]);
2223 w = rounding. sub_down (w, len [u]);
2226 infinity = rounding. add_up (w, 1);
2229 for (
int_t u = 0; u < nVertices; ++ u)
2231 for (
int_t v = 0; v < nVertices; ++ v)
2233 wType w = arr [u] [v];
2236 arr [u] [v] = infinity;
2239 w = rounding. add_down (w, len [v]);
2241 rounding. sub_down (w, len [u]);
2247 wType &minWeight = result;
2248 bool firstTime =
true;
2249 for (
int_t u = 0; u < nVertices; ++ u)
2251 for (
int_t v = 0; v < nVertices; ++ v)
2253 wType w = arr [u] [v];
2256 w = rounding. add_down (w, len [v]);
2257 w = rounding. sub_down (w, len [u]);
2263 else if (w < minWeight)
2271 if (
false &&
sbug. show)
2280template <
class wType>
2281template <
class arrayType>
2283 bool setInfinity,
bool ignoreNegLoop)
const
2286 return Johnson (rounding, arr, setInfinity, ignoreNegLoop);
2289template <
class wType>
2290template <
class roundType>
2292 bool ignoreNegLoop,
int sparseGraph)
const
2299 wType **arr =
new wType * [nVertices];
2300 for (
int_t i = 0; i < nVertices; ++ i)
2301 arr [i] =
new wType [nVertices];
2305 bool sparse =
false;
2306 if (sparseGraph == 1)
2308 else if (sparseGraph != 0)
2310 double nEdgesD =
this -> countEdges ();
2311 double nVerticesD =
this -> countVertices ();
2312 if ((nVerticesD > 3000) && (nEdgesD < nVerticesD * 1000) &&
2313 (nEdgesD < nVerticesD * nVerticesD / 50))
2320 wType minWeight = sparse ?
2321 this -> Johnson (rounding, arr,
false, ignoreNegLoop) :
2322 this -> FloydWarshall (rounding, arr,
false, ignoreNegLoop);
2337 for (
int_t i = 0; i < nVertices; ++ i)
2338 delete [] (arr [i]);
2344template <
class wType>
2349 return this -> minPathWeight (rounding, ignoreNegLoop, sparseGraph);
2352template <
class wType>
template <
class outType>
2355 out <<
"; Directed graph: " << nVertices <<
" vertices.\n";
2357 for (
int_t i = 0; i < nVertices; ++ i)
2359 for (; curEdge < edgeEnds [i]; ++ curEdge)
2361 out << i <<
" -> " << edges [curEdge];
2363 out <<
" [" << weights [curEdge] <<
"]\n";
2368 out <<
"; This is the end of the graph.\n";
2376template <
class wType>
2379 return g. show (out,
false);
2391template <
class wType,
class Table1,
class Table2>
2397 int_t nVert = g. countVertices ();
2402 g. DFSfinishTime (tab);
2403 for (
int_t i = 0; i < nVert; ++ i)
2404 ordered [nVert - tab [i]] = i;
2411 g. transpose (*transposed, copyweights);
2414 int_t n = transposed -> DFSforest (ordered, compVertices, compEnds,
2433template <
class wType,
class Table1,
class Table2>
2438 int_t nVertices = g. countVertices ();
2444 std::vector<int_t> dfsIndex (nVertices, 0);
2448 std::vector<int_t> lowLink (nVertices, 0);
2451 std::stack<int_t> s_nodes;
2456 inTheStack. allocate (nVertices);
2457 inTheStack. clearall (nVertices);
2460 int_t nComponents = 0;
2463 int_t posVertices = 0;
2467 int_t vertexToScan = 0;
2470 int_t discoveryTime = 0;
2473 std::stack<int_t> s_vertex;
2474 std::stack<int_t> s_edge;
2475 std::stack<int_t> s_maxedge;
2488 if (edge >= maxedge)
2491 if ((vertex >= 0) && (lowLink [vertex] ==
2497 v = s_nodes. top ();
2499 inTheStack. clear (v);
2500 compVertices [posVertices ++] = v;
2501 }
while (v != vertex);
2502 compEnds [nComponents ++] = posVertices;
2507 if (s_vertex. empty ())
2510 while ((vertexToScan < nVertices) &&
2511 (dfsIndex [vertexToScan] != 0))
2517 if (vertexToScan == nVertices)
2519 inTheStack. free ();
2524 vertex = vertexToScan ++;
2528 dfsIndex [vertex] = ++ discoveryTime;
2529 lowLink [vertex] = discoveryTime;
2532 s_nodes. push (vertex);
2533 inTheStack. set (vertex);
2537 maxedge = g. countEdges (vertex);
2544 int_t lowLink2 = lowLink [vertex];
2547 vertex = s_vertex. top ();
2549 edge = s_edge. top ();
2551 maxedge = s_maxedge. top ();
2555 if (lowLink [vertex] > lowLink2)
2556 lowLink [vertex] = lowLink2;
2564 int_t next = g. getEdge (vertex, edge ++);
2567 if (dfsIndex [next] == 0)
2570 s_vertex. push (vertex);
2571 s_edge. push (edge);
2572 s_maxedge. push (maxedge);
2578 dfsIndex [vertex] = ++ discoveryTime;
2579 lowLink [vertex] = discoveryTime;
2582 s_nodes. push (vertex);
2583 inTheStack. set (vertex);
2587 maxedge = g. countEdges (vertex);
2592 else if (inTheStack. test (next))
2594 if (lowLink [vertex] > dfsIndex [next])
2595 lowLink [vertex] = dfsIndex [next];
2601 inTheStack. free ();
2607template <
class wType>
2612 bool copyweights = !!transposed;
2613 int_t countSCC =
SCC (*
this, compVertices, compEnds,
2619 int_t maxCompSize = compEnds [0];
2620 for (
int_t comp = 1; comp < countSCC; ++ comp)
2622 int_t compSize = compEnds [comp] - compEnds [comp - 1];
2623 if (maxCompSize < compSize)
2624 maxCompSize = compSize;
2628 wType **F =
new wType * [maxCompSize + 1];
2630 for (
int_t i = 0; i <= maxCompSize; ++ i)
2632 F [i] =
new wType [maxCompSize];
2633 finite [i]. allocate (maxCompSize);
2639 for (
int_t i = 0; i < nVertices; ++ i)
2640 components [i] = -1;
2642 for (
int_t comp = 0; comp < countSCC; ++ comp)
2644 int_t maxOffset = compEnds [comp];
2646 for (; pos < maxOffset; ++ pos)
2648 numbers [compVertices [pos]] = pos - offset;
2649 components [compVertices [pos]] = comp;
2655 wType minWeight (0);
2656 for (
int_t comp = 0; comp < countSCC; ++ comp)
2658 int_t offset = comp ? compEnds [comp - 1] :
2659 static_cast<int_t> (0);
2660 int_t compSize = compEnds [comp] - offset;
2661 for (
int_t i = 0; i <= compSize; ++ i)
2662 finite [i]. clearall (compSize);
2664 finite [0]. set (0);
2666 for (
int_t len = 1; len <= compSize; ++ len)
2669 for (
int_t i = 0; i < compSize; ++ i)
2671 if (!finite [len - 1]. test (i))
2673 wType prevWeight = F [len - 1] [i];
2674 int_t source = compVertices [offset + i];
2677 int_t edgeOffset = source ?
2678 edgeEnds [source - 1] :
2679 static_cast<int_t> (0);
2680 int_t edgeEnd = edgeEnds [source];
2681 for (; edgeOffset < edgeEnd; ++ edgeOffset)
2683 int_t target = edges [edgeOffset];
2684 if (components [target] != comp)
2686 int_t j = numbers [target];
2687 wType newWeight = prevWeight +
2688 weights [edgeOffset];
2689 if (!finite [len]. test (j))
2691 finite [len]. set (j);
2692 F [len] [j] = newWeight;
2694 else if (newWeight < F [len] [j])
2695 F [len] [j] = newWeight;
2701 wType minCompWeight (0);
2702 bool firstMin =
true;
2703 for (
int_t vert = 0; vert < compSize; ++ vert)
2705 if (!finite [compSize]. test (vert))
2707 bool firstAverage =
true;
2708 wType maxAverage = 0;
2709 for (
int_t first = 0; first < compSize; ++ first)
2711 if (!finite [first]. test (vert))
2713 wType average = (F [compSize] [vert] -
2718 maxAverage = average;
2719 firstAverage =
false;
2721 else if (maxAverage < average)
2722 maxAverage = average;
2724 if (firstMin || (maxAverage < minCompWeight))
2727 throw "Bug in Karp's algorithm";
2728 minCompWeight = maxAverage;
2734 if (!comp || (minCompWeight < minWeight))
2735 minWeight = minCompWeight;
2739 delete [] components;
2741 for (
int_t i = 0; i <= maxCompSize; ++ i)
2743 finite [i]. free ();
2753template <
class wType>
2754template <
class roundType>
2760 bool copyweights = !!transposed;
2761 int_t countSCC =
SCC (*
this, compVertices, compEnds,
2767 int_t maxCompSize = compEnds [0];
2768 for (
int_t comp = 1; comp < countSCC; ++ comp)
2770 int_t compSize = compEnds [comp] - compEnds [comp - 1];
2771 if (maxCompSize < compSize)
2772 maxCompSize = compSize;
2776 wType **FUpper =
new wType * [maxCompSize + 1];
2777 wType **FLower =
new wType * [maxCompSize + 1];
2779 for (
int_t i = 0; i <= maxCompSize; ++ i)
2781 FUpper [i] =
new wType [maxCompSize];
2782 FLower [i] =
new wType [maxCompSize];
2783 finite [i]. allocate (maxCompSize);
2789 for (
int_t i = 0; i < nVertices; ++ i)
2790 components [i] = -1;
2792 for (
int_t comp = 0; comp < countSCC; ++ comp)
2794 int_t maxOffset = compEnds [comp];
2796 for (; pos < maxOffset; ++ pos)
2798 numbers [compVertices [pos]] = pos - offset;
2799 components [compVertices [pos]] = comp;
2805 wType minWeight (0);
2806 for (
int_t comp = 0; comp < countSCC; ++ comp)
2808 int_t offset = comp ? compEnds [comp - 1] :
2809 static_cast<int_t> (0);
2810 int_t compSize = compEnds [comp] - offset;
2811 for (
int_t i = 0; i <= compSize; ++ i)
2812 finite [i]. clearall (compSize);
2815 finite [0]. set (0);
2817 for (
int_t len = 1; len <= compSize; ++ len)
2820 for (
int_t i = 0; i < compSize; ++ i)
2822 if (!finite [len - 1]. test (i))
2824 wType prevUpper = FUpper [len - 1] [i];
2825 wType prevLower = FLower [len - 1] [i];
2826 int_t source = compVertices [offset + i];
2829 int_t edgeOffset = source ?
2830 edgeEnds [source - 1] :
2831 static_cast<int_t> (0);
2832 int_t edgeEnd = edgeEnds [source];
2833 for (; edgeOffset < edgeEnd; ++ edgeOffset)
2835 int_t target = edges [edgeOffset];
2836 if (components [target] != comp)
2838 int_t j = numbers [target];
2839 wType newUpper = rounding. add_up
2841 weights [edgeOffset]);
2842 wType newLower = rounding. add_down
2844 weights [edgeOffset]);
2845 if (!finite [len]. test (j))
2847 finite [len]. set (j);
2848 FUpper [len] [j] = newUpper;
2849 FLower [len] [j] = newLower;
2855 if (newUpper < curUpper)
2856 curUpper = newUpper;
2859 if (newLower < curLower)
2860 curLower = newLower;
2867 wType minCompWeight (0);
2868 bool firstMin =
true;
2869 for (
int_t vert = 0; vert < compSize; ++ vert)
2871 if (!finite [compSize]. test (vert))
2873 bool firstAverage =
true;
2874 wType maxAverage = 0;
2875 for (
int_t first = 0; first < compSize; ++ first)
2877 if (!finite [first]. test (vert))
2879 const wType diff = rounding. sub_down
2880 (FLower [compSize] [vert],
2881 FUpper [first] [vert]);
2882 wType average = rounding. div_down
2883 (diff, compSize - first);
2886 maxAverage = average;
2887 firstAverage =
false;
2889 else if (maxAverage < average)
2890 maxAverage = average;
2892 if (firstMin || (maxAverage < minCompWeight))
2895 throw "Bug in Karp's algorithm";
2896 minCompWeight = maxAverage;
2902 if (!comp || (minCompWeight < minWeight))
2903 minWeight = minCompWeight;
2907 delete [] components;
2909 for (
int_t i = 0; i <= maxCompSize; ++ i)
2911 finite [i]. free ();
2912 delete [] (FUpper [i]);
2913 delete [] (FLower [i]);
2923template <
class wType>
2924template <
class roundType,
class predType>
2932 bool copyweights = !!transposed;
2933 int_t countSCC =
SCC (*
this, compVertices, compEnds,
2939 int_t maxCompSize = compEnds [0];
2940 for (
int_t comp = 1; comp < countSCC; ++ comp)
2942 int_t compSize = compEnds [comp] - compEnds [comp - 1];
2943 if (maxCompSize < compSize)
2944 maxCompSize = compSize;
2950 const int nTables (5);
2951 wType **FUpper =
new wType * [nTables];
2952 wType **FLower =
new wType * [nTables];
2953#ifdef CHECK_ROUNDING_WIDTH
2954 wType **FUpperE =
new wType * [nTables];
2955 wType **FLowerE =
new wType * [nTables];
2959 for (
int_t i = 0; i < nTables; ++ i)
2961 FUpper [i] =
new wType [maxCompSize];
2962 FLower [i] =
new wType [maxCompSize];
2963#ifdef CHECK_ROUNDING_WIDTH
2964 FUpperE [i] =
new wType [maxCompSize];
2965 FLowerE [i] =
new wType [maxCompSize];
2967 finite [i]. allocate (maxCompSize);
2973 for (
int_t i = 0; i < nVertices; ++ i)
2974 components [i] = -1;
2976 for (
int_t comp = 0; comp < countSCC; ++ comp)
2978 int_t maxOffset = compEnds [comp];
2980 for (; pos < maxOffset; ++ pos)
2982 numbers [compVertices [pos]] = pos - offset;
2983 components [compVertices [pos]] = comp;
2989 wType minWeight (0);
2990#ifdef CHECK_ROUNDING_WIDTH
2991 wType minWeightE (0);
2996 int_t minCompsize (0);
2997 for (
int_t comp = 0; comp < countSCC; ++ comp)
2999 int_t offset = comp ? compEnds [comp - 1] :
3000 static_cast<int_t> (0);
3001 int_t compSize = compEnds [comp] - offset;
3002 finite [0]. clearall (compSize);
3003 finite [4]. clearall (compSize);
3004 for (
int_t i = 0; i < compSize; ++ i)
3008#ifdef CHECK_ROUNDING_WIDTH
3009 FUpperE [0] [0] = 0;
3010 FLowerE [0] [0] = 0;
3012 finite [0]. set (0);
3015 const int_t maxLength1 (compSize + 1);
3016 for (
int_t len = 1; len < maxLength1; ++ len)
3019 int_t prevIndex ((len == 1) ?
3020 0 : (((len - 1) & 1) + 1));
3021 int_t curIndex ((len == compSize) ?
3022 3 : ((len & 1) + 1));
3023 finite [curIndex]. clearall (compSize);
3027 for (
int_t i = finite [prevIndex].
3029 (i >= 0) && (i < compSize);
3030 i = finite [prevIndex]. find
3036 int_t source = compVertices [offset + i];
3039 int_t edgeEnd = edgeEnds [source];
3040 for (
int_t edgeOffset = source ?
3041 edgeEnds [source - 1] :
3042 static_cast<int_t> (0);
3043 edgeOffset < edgeEnd; ++ edgeOffset)
3045 int_t target = edges [edgeOffset];
3046 if (components [target] != comp)
3048 int_t j = numbers [target];
3049 wType newLower = rounding. add_down
3050 (FLower [prevIndex] [i],
3051 weights [edgeOffset]);
3052#ifdef CHECK_ROUNDING_WIDTH
3053 wType newLowerE = rounding. add_up
3054 (FLowerE [prevIndex] [i],
3055 weights [edgeOffset]);
3061 if (!finite [curIndex]. test (j))
3063 finite [curIndex]. set (j);
3064 FLower [curIndex] [j] =
3066#ifdef CHECK_ROUNDING_WIDTH
3067 FLowerE [curIndex] [j] =
3070 predecessors. add (target,
3072 maxLength [j] = len;
3077 FLower [curIndex] [j])
3079 FLower [curIndex] [j] =
3081#ifdef CHECK_ROUNDING_WIDTH
3082 FLowerE [curIndex] [j] =
3085 predecessors. add (target,
3087 maxLength [j] = len;
3094 finite [4]. set (0);
3095 FLower [4] [0] = rounding. div_down (FLower [3] [0],
3097#ifdef CHECK_ROUNDING_WIDTH
3098 FLowerE [4] [0] = rounding. div_up (FLowerE [3] [0],
3104 const int_t maxLength2 (compSize);
3105 for (
int_t len = 1; len < maxLength2; ++ len)
3108 int_t prevIndex ((len == 1) ?
3109 0 : (((len - 1) & 1) + 1));
3110 int_t curIndex ((len & 1) + 1);
3111 finite [curIndex]. clearall (compSize);
3115 for (
int_t i = finite [prevIndex].
3117 (i >= 0) && (i < compSize);
3118 i = finite [prevIndex]. find
3124 int_t source = compVertices [offset + i];
3127 int_t edgeEnd = edgeEnds [source];
3128 for (
int_t edgeOffset = source ?
3129 edgeEnds [source - 1] :
3130 static_cast<int_t> (0);
3131 edgeOffset < edgeEnd; ++ edgeOffset)
3133 int_t target = edges [edgeOffset];
3134 if (components [target] != comp)
3136 int_t j = numbers [target];
3137 wType newUpper = rounding. add_up
3138 (FUpper [prevIndex] [i],
3139 weights [edgeOffset]);
3140#ifdef CHECK_ROUNDING_WIDTH
3141 wType newUpperE = rounding. add_down
3142 (FUpperE [prevIndex] [i],
3143 weights [edgeOffset]);
3148 if (!finite [curIndex]. test (j))
3150 finite [curIndex]. set (j);
3151 FUpper [curIndex] [j] =
3153#ifdef CHECK_ROUNDING_WIDTH
3154 FUpperE [curIndex] [j] =
3161 FUpper [curIndex] [j])
3163 FUpper [curIndex] [j] =
3165#ifdef CHECK_ROUNDING_WIDTH
3166 FUpperE [curIndex] [j] =
3178 if (!finite [3]. test (j))
3180 const wType diff = rounding. sub_down
3182 FUpper [curIndex] [j]);
3183#ifdef CHECK_ROUNDING_WIDTH
3184 const wType diffE = rounding. sub_up
3186 FUpperE [curIndex] [j]);
3188 const wType average = rounding.
3191#ifdef CHECK_ROUNDING_WIDTH
3192 const wType averageE = rounding.
3196 if (!finite [4]. test (j))
3198 finite [4]. set (j);
3199 FLower [4] [j] = average;
3200#ifdef CHECK_ROUNDING_WIDTH
3201 FLowerE [4] [j] = averageE;
3204 else if (FLower [4] [j] < average)
3206 FLower [4] [j] = average;
3207#ifdef CHECK_ROUNDING_WIDTH
3208 FLowerE [4] [j] = averageE;
3216 wType minCompWeight (0);
3217#ifdef CHECK_ROUNDING_WIDTH
3218 wType minCompWeightE (0);
3221 int_t minCompVert (0);
3222 int_t maxCompLength (0);
3223 for (
int_t vert = 0; vert < compSize; ++ vert)
3225 if (!finite [4]. test (vert))
3227 if (!vert || (FLower [4] [vert] < minCompWeight))
3229 minCompWeight = FLower [4] [vert];
3230#ifdef CHECK_ROUNDING_WIDTH
3231 minCompWeightE = FLowerE [4] [vert];
3233 minCompVert = compVertices [offset + vert];
3234 maxCompLength = maxLength [vert];
3239 if (!comp || (minCompWeight < minWeight))
3241 minWeight = minCompWeight;
3242#ifdef CHECK_ROUNDING_WIDTH
3243 minWeightE = minCompWeightE;
3245 minVert = minCompVert;
3246 minCompsize = maxCompLength;
3251 predecessors. add (minVert, minVert, -minCompsize);
3254 delete [] components;
3256 for (
int_t i = 0; i < nTables; ++ i)
3258 finite [i]. free ();
3259 delete [] (FUpper [i]);
3260 delete [] (FLower [i]);
3261#ifdef CHECK_ROUNDING_WIDTH
3262 delete [] (FUpperE [i]);
3263 delete [] (FLowerE [i]);
3267 delete [] maxLength;
3270#ifdef CHECK_ROUNDING_WIDTH
3275#ifdef CHECK_ROUNDING_WIDTH
3278 minWeight <<
", " << minWeightE <<
3279 "], width: " << (minWeightE - minWeight) <<
".\n";
3309 template <
class VectorType>
3310 void getCycle (VectorType &cycle)
const;
3327 searchStart (-1), compSize (0)
3337 pred [stage] [vertex] = predecessor;
3347template <
class VectorType>
3358 std::vector<int_t> path;
3361 for (
size_t n = 0; n < path. size (); ++ n)
3363 if (path [n] == current)
3365 for (
size_t m = path. size ();
3368 cycle. push_back (path [m - 1]);
3373 path. push_back (current);
3374 current =
pred [stage] [current];
3379template <
class wType>
3380template <
class roundType>
3385 return this -> minMeanCycleWeightMem (rounding, transposed,
3386 predecessorsIgnore);
3389template <
class wType>
3390template <
class arrayType,
class roundType>
3392 const arrayType &starting,
int_t n)
const
3395 const int nIndices = 2;
3396 wType **F =
new wType * [nIndices];
3398 for (
int i = 0; i < nIndices; ++ i)
3400 F [i] =
new wType [nVertices];
3401 finite [i]. allocate (nVertices);
3405 for (
int_t i = 0; i < n; ++ i)
3407 int_t v = starting [i];
3408 if ((v < 0) || (v >= nVertices))
3409 throw "Starting vertex out of range.";
3411 finite [0]. set (v);
3415 wType minWeight (0);
3416 bool firstWeight =
true;
3417 int_t maxLength (nVertices + 1);
3418 for (
int_t len = 1; len < maxLength; ++ len)
3421 int_t prevIndex = (len - 1) & 1;
3422 int_t curIndex = len & 1;
3423 finite [curIndex]. clearall (nVertices);
3426 for (
int_t source = 0; source < nVertices; ++ source)
3428 if (!finite [prevIndex]. test (source))
3430 wType prevWeight = F [prevIndex] [source];
3433 int_t edgeOffset = source ?
3434 edgeEnds [source - 1] :
3435 static_cast<int_t> (0);
3436 int_t edgeEnd = edgeEnds [source];
3437 for (; edgeOffset < edgeEnd; ++ edgeOffset)
3439 int_t target = edges [edgeOffset];
3440 wType newWeight = rounding. add_down
3441 (prevWeight, weights [edgeOffset]);
3442 if (!finite [curIndex]. test (target))
3444 finite [curIndex]. set (target);
3445 F [curIndex] [target] = newWeight;
3447 else if (newWeight < F [curIndex] [target])
3448 F [curIndex] [target] = newWeight;
3453 for (
int_t vert = 0; vert < nVertices; ++ vert)
3455 if (!finite [curIndex]. test (vert))
3457 wType average = rounding. div_down
3458 (F [curIndex] [vert], len);
3461 minWeight = average;
3462 firstWeight =
false;
3464 else if (average < minWeight)
3465 minWeight = average;
3470 for (
int i = 0; i < nIndices; ++ i)
3472 finite [i]. free ();
3482template <
class wType>
3483template <
class arrayType>
3488 return minMeanPathWeight (rounding, starting, n);
3497template <
class wType>
3502 int_t nEdges = g. countEdges (vertex);
3504 for (
int_t edge = 0; edge < nEdges; ++ edge)
3507 int_t dest = newNum [g. getEdge (vertex, edge)];
3513 if (srcVert [dest] == cur)
3517 srcVert [dest] = cur;
3519 result. addEdge (dest);
3529template <
class wType,
class Table1,
class Table2>
3531 int_t compNum, Table1 &compVertices, Table2 &compEnds,
3535 int_t nVert = g. countVertices ();
3541 int_t *newNum = newNumbers ? newNumbers :
new int_t [nVert];
3542 for (
int_t i = 0; i < nVert; ++ i)
3546 while (cur < compNum)
3548 int_t posEnd = compEnds [cur];
3549 while (pos < posEnd)
3550 newNum [compVertices [pos ++]] = cur;
3553 for (
int_t i = 0; i < nVert; ++ i)
3556 newNum [i] = cur ++;
3561 int_t newVert = nVert - (compNum ? compEnds [compNum - 1] :
3562 static_cast<int_t> (0)) + compNum;
3565 throw "DEBUG: Wrong numbers.";
3567 for (
int_t i = 0; i < newVert; ++ i)
3573 while (cur < compNum)
3576 result. addVertex ();
3578 int_t posEnd = compEnds [cur];
3579 while (pos < posEnd)
3582 int_t vertex = compVertices [pos ++];
3590 for (
int_t vertex = 0; vertex < nVert; ++ vertex)
3593 if (newNum [vertex] > cur)
3594 throw "DEBUG: Wrong order.";
3596 if (newNum [vertex] != cur)
3599 result. addVertex ();
3612template <
class wType,
class TabSets>
3614 const int_t *newNum, TabSets &numSets,
3617 int_t nEdges = g. countEdges (vertex);
3620 for (
int_t edge = 0; edge < nEdges; ++ edge)
3623 int_t destNumber = newNum [g. getEdge (vertex, edge)];
3626 int_t destSize = (destNumber < 0) ?
3627 numSets [-destNumber]. size () :
3628 static_cast<int_t> (1);
3629 for (
int_t i = 0; i < destSize; ++ i)
3632 int_t dest = (destNumber < 0) ?
3633 numSets [-destNumber] [i] : destNumber;
3641 if (srcVert [dest] == cur)
3645 result. addEdge (dest);
3655template <
class wType,
class Table1,
class Table2>
3657 int_t compNum, Table1 &compVertices, Table2 &compEnds,
3661 int_t nVert = g. countVertices ();
3670 for (
int_t i = 0; i < nVert; ++ i)
3677 int_t numSetCur = 2;
3681 while (cur < compNum)
3683 int_t posEnd = compEnds [cur];
3684 while (pos < posEnd)
3686 int_t number = compVertices [pos ++];
3687 if (newNum [number] == -1)
3688 newNum [number] = cur;
3689 else if (newNum [number] < 0)
3690 numSets [-newNum [number]]. add (cur);
3693 numSets [numSetCur]. add (newNum [number]);
3694 numSets [numSetCur]. add (cur);
3695 newNum [number] = -(numSetCur ++);
3700 for (
int_t i = 0; i < nVert; ++ i)
3702 if (newNum [i] == -1)
3703 newNum [i] = cur ++;
3708 int_t newVert = cur;
3710 for (
int_t i = 0; i < newVert; ++ i)
3717 while (cur < compNum)
3720 result. addVertex ();
3723 int_t posEnd = compEnds [cur];
3724 while (pos < posEnd)
3727 int_t vertex = compVertices [pos ++];
3737 for (
int_t vertex = 0; vertex < nVert; ++ vertex)
3740 if (newNum [vertex] > cur)
3741 throw "DEBUG: Wrong order 2.";
3744 if (newNum [vertex] != cur)
3748 result. addVertex ();
3768template <
class wType>
3773 int_t nVertG = g. countVertices ();
3779 visited. allocate (nVertG);
3780 visited. clearall (nVertG);
3783 for (
int_t startVertex = 0; startVertex < nVert; ++ startVertex)
3786 result. addVertex ();
3790 std::stack<int_t> s_visited;
3793 std::stack<int_t> s_vertex;
3794 std::stack<int_t> s_edge;
3797 visited. set (startVertex);
3798 s_visited. push (startVertex);
3802 int_t vertex = startVertex;
3808 if (edge >= g. countEdges (vertex))
3812 if (s_vertex. empty ())
3816 vertex = s_vertex. top ();
3818 edge = s_edge. top ();
3824 int_t next = g. getEdge (vertex, edge ++);
3827 if (!visited. test (next))
3831 result. addEdge (next);
3834 s_vertex. push (vertex);
3835 s_edge. push (edge);
3842 visited. set (vertex);
3843 s_visited. push (vertex);
3849 if (startVertex == nVert - 1)
3853 if (nVisited > (nVertG >> 6))
3855 visited. clearall (nVertG);
3859 while (!s_visited. empty ())
3861 int_t vertex = s_visited. top ();
3863 visited. clear (vertex);
3878template <
class GraphType>
3882 int_t nVertG = g. countVertices ();
3887 std::vector<int_t> visited (nVertG, 0);
3891 std::stack<int_t> s_vertex;
3892 std::stack<int_t> s_edge;
3906 if (edge >= g. countEdges (vertex))
3909 if (s_vertex. empty ())
3913 vertex = s_vertex. top ();
3915 edge = s_edge. top ();
3922 int_t next = g. getEdge (vertex, edge ++);
3928 int_t newPeriod = visited [next] - level - 1;
3930 newPeriod = -newPeriod;
3933 int_t a = newPeriod;
3953 s_vertex. push (vertex);
3954 s_edge. push (edge);
3962 visited [vertex] = level;
3975template <
class wType>
3980 int_t nVertG = g. countVertices ();
3986 visited. allocate (nVertG);
3987 visited. clearall (nVertG);
3990 BitSets lists (nVertG, nVert);
3993 std::stack<int_t> s_vertex;
3994 std::stack<int_t> s_edge;
3997 int_t startVertex = 0;
4000 visited. set (vertex);
4005 if (edge >= g. countEdges (vertex))
4009 if (s_vertex. empty ())
4011 while ((startVertex < nVertG) &&
4012 (visited. test (startVertex)))
4014 if (startVertex >= nVertG)
4016 vertex = startVertex;
4018 visited. set (vertex);
4023 int_t prev = s_vertex. top ();
4028 if (vertex >= nVert)
4029 lists. addset (prev, vertex);
4034 edge = s_edge. top ();
4040 int_t next = g. getEdge (vertex, edge ++);
4044 lists. add (vertex, next);
4047 if (!visited. test (next))
4050 s_vertex. push (vertex);
4051 s_edge. push (edge);
4056 visited. set (vertex);
4062 else if (next >= nVert)
4064 lists. addset (vertex, next);
4069 for (
int_t vertex = 0; vertex < nVert; ++ vertex)
4071 result. addVertex ();
4072 int_t edge = lists. get (vertex);
4075 result. addEdge (edge);
4076 edge = lists. get (vertex, edge + 1);
4095template<
class wType,
class TConn>
4100 int_t nVertG = g. countVertices ();
4106 visited. allocate (nVertG);
4107 visited. clearall (nVertG);
4110 BitSets forwardlists (nVertG, nVert);
4113 std::stack<int_t> s_vertex;
4114 std::stack<int_t> s_edge;
4117 int_t startVertex = 0;
4120 visited. set (vertex);
4125 if (edge >= g. countEdges (vertex))
4129 if (s_vertex. empty ())
4131 while ((startVertex < nVertG) &&
4132 (visited. test (startVertex)))
4134 if (startVertex >= nVertG)
4136 vertex = startVertex;
4138 visited. set (vertex);
4143 int_t prev = s_vertex. top ();
4148 if (vertex >= nVert)
4149 forwardlists. addset (prev, vertex);
4154 edge = s_edge. top ();
4160 int_t next = g. getEdge (vertex, edge ++);
4164 forwardlists. add (vertex, next);
4167 if (!visited. test (next))
4170 s_vertex. push (vertex);
4171 s_edge. push (edge);
4176 visited. set (vertex);
4182 else if (next >= nVert)
4184 forwardlists. addset (vertex, next);
4191 BitSets backlists (nVertG, nVert);
4197 if (!s_vertex. empty () || !s_edge. empty ())
4198 throw "DEBUG: Nonempty stacks in 'inclusionGraph'.";
4201 visited. clearall (nVertG);
4207 visited. set (vertex);
4212 if (edge >= gT. countEdges (vertex))
4216 if (s_vertex. empty ())
4218 while ((startVertex < nVertG) &&
4219 (visited. test (startVertex)))
4221 if (startVertex >= nVertG)
4223 vertex = startVertex;
4225 visited. set (vertex);
4230 int_t prev = s_vertex. top ();
4235 if (vertex >= nVert)
4236 backlists. addset (prev, vertex);
4241 edge = s_edge. top ();
4247 int_t next = gT. getEdge (vertex, edge ++);
4251 backlists. add (vertex, next);
4254 if (!visited. test (next))
4257 s_vertex. push (vertex);
4258 s_edge. push (edge);
4263 visited. set (vertex);
4269 else if (next >= nVert)
4271 backlists. addset (vertex, next);
4278 for (
int_t v = nVert; v < nVertG; ++ v)
4280 int_t bvertex = backlists. get (v);
4281 while (bvertex >= 0)
4283 int_t fvertex = forwardlists. get (v);
4284 while (fvertex >= 0)
4286 connections (bvertex, fvertex, v);
4287 fvertex = forwardlists. get (v, fvertex + 1);
4289 bvertex = backlists. get (v, bvertex + 1);
4296 for (
int_t vertex = 0; vertex < nVert; ++ vertex)
4298 result. addVertex ();
4299 int_t edge = forwardlists. get (vertex);
4302 result. addEdge (edge);
4303 edge = forwardlists. get (vertex, edge + 1);
4317template <
class wType,
class matrix>
4320 int_t nVert = g. countVertices ();
4321 for (
int_t v = 0; v < nVert; ++ v)
4323 int_t nEdges = g. countEdges (v);
4324 for (
int_t e = 0; e < nEdges; ++ e)
4326 int_t w = g. getEdge (v, e);
4337template <
class wType,
class matrix>
4340 for (
int_t v = 0; v < n; ++ v)
4343 for (
int_t w = 0; w < n; ++ w)
4355template <
class matrix>
4358 for (
int_t k = 0; k < n; ++ k)
4360 for (
int_t i = 0; i < n; ++ i)
4362 for (
int_t j = 0; j < n; ++ j)
4364 if (m [i] [k] && m [k] [j])
4379template <
class matrix>
4382 for (
int_t k = n - 1; k >= 0; -- k)
4384 for (
int_t i = 0; i < n; ++ i)
4386 for (
int_t j = 0; j < n; ++ j)
4388 if (m [i] [k] && m [k] [j])
4398template <
class wType>
4402 int_t nVert = g. countVertices ();
An auto_array template that mimics selected behaviors of the std::auto_ptr template,...
This file contains the definition of a bitfield class which works an array of bits.
This file defines a class that uses bit representation of a set to store many small sets.
This class defines a bit field that is part of some larger array or that uses an allocated piece of m...
This class uses bit representation to store many small sets.
This template contains the definition of a Fibonacci heap that can be used as an efficient priority q...
A helper class for determining a cycle that realizes the minimum.
void getCycle(VectorType &cycle) const
Fills in a vector with a cycle that realizes the minimum, using the push_back method to add the conse...
PredecessorsCycle()
The default constructor.
void add(int_t vertex, int_t predecessor, int_t stage)
Adds a predecessor information for the given vertex at the given stage (path progression length).
chomp::homology::multitable< chomp::homology::multitable< int_t > > pred
The array of predecessors at each stage.
int_t searchStart
The vertex number to start back-tracing the cycle from.
int_t compSize
The size of the component with the cycle to search.
An auto_array template that mimics selected behaviors of the std::auto_ptr template,...
A class for representing a positive number with negative values serving as the infinity (used in the ...
const wType & getValue() const
Returns the value stored in this object.
bool isInfinity() const
Returns true iff the value corresponds to the infinity.
wType value
The actual number.
posWeight(const wType &_value)
An optional constructor.
posWeight()
The default constructor.
void setInfinity()
Sets the value to the infinity.
friend bool operator<(const posWeight &x, const posWeight &y)
The < operator for comparing the numbers.
friend std::ostream & operator<<(std::ostream &out, const posWeight &x)
The operator for showing the number to the output stream.
This class defines a directed graph with very limited number of operations, and a few specific algori...
const wType & getWeight(int_t vertex, int_t i) const
Retrieves the weight of the given edge.
void writeEdges(Table &tab) const
Fills out a table that represents all the edges of the graph.
void swap(diGraph< wType > &g)
Swaps the data with another graph.
bool DFSforestStack(Table1 &tab, Table1 &ntab, int_t vertex, int_t treeNumber, int_t countTrees, Table2 &compVertices, int_t &curVertex, diGraph *sccGraph, int_t *sccEdgeAdded) const
A stack version of the recurrent procedure for DFSforest.
diGraph()
The default constructor of an empty graph.
int_t DFSforest(const Table1 &ordered, Table2 &compVertices, Table3 &compEnds, bool nontrivial=false, diGraph< wType > *sccGraph=0) const
Computes the DFS forest.
wType minPathWeight(const roundType &rounding, bool ignoreNegLoop=false, int sparseGraph=-1) const
Uses the Floyd-Warshall algorithm or Johnson's algorithm, depending on the number of edges,...
wType Edmonds() const
Runs the Edmonds algorithm to compute the shortest path that runs through all the vertices of the gra...
multitable< int_t > edges
A table with edge target numbers.
bool DFSforestRecurrent(Table1 &tab, Table1 &ntab, int_t vertex, int_t treeNumber, int_t countTrees, Table2 &compVertices, int_t &curVertex, diGraph *sccGraph, int_t *sccEdgeAdded) const
The recurrent procedure for DFSforest.
void addEdge(int_t target)
Adds an edge starting at the last vertex.
wType minMeanCycleWeightMem(const roundType &rounding, diGraph< wType > *transposed, predType &predecessors) const
A rigorous numerics version of Karp's algorithm modified in such a way that the memory usage is minim...
outType & show(outType &out, bool showWeights=false) const
Outputs the graph to a text stream in a human-readable format.
friend bool operator==(const diGraph< wType1 > &g1, const diGraph< wType2 > &g2)
Operator == for comparing digraphs.
wType minMeanCycleWeight(diGraph< wType > *transposed=0) const
Runs Karp's algorithm for each strongly connected component of the graph and returns the minimum mean...
int_t nVertices
The number of vertices.
void subgraph(diGraph< wType1 > &result, const Table &tab, bool copyweights=false) const
Computes a restriction of the graph to its subgraph.
void Dijkstra(const roundType &rounding, int_t source, lenTable &len, weightsType &edgeWeights) const
Dijkstra's algorithm for solving the single-source shortest paths problem if all the edge weights are...
wType minMeanPathWeight(const roundType &rounding, const arrayType &starting, int_t n) const
Runs an algorithm based on Karp's idea to compute the minimum mean path weight for paths starting at ...
void removeVertex(void)
Removes the last vertex and all the edges going out from it.
wType FloydWarshall(const roundType &rounding, arrayType &arr, bool setInfinity=true, bool ignoreNegLoop=false) const
Runs the Floyd-Warshall algorithm to compute the shortest paths between all pairs of vertices in the ...
void setWeights(const Table &tab)
Sets the weights of all the edges at a time.
int_t shortestPath(int_t source, int_t destination) const
Computes the length of the shortest nontrivial path from the given vertex to another one.
wType weight_type
The type of the weight of edges.
multitable< int_t > edgeEnds
A table with the offsets of the one-after-the-last edge of each vertex.
~diGraph()
The destructor.
int_t countVertices(void) const
Returns the number of vertices.
int_t shortestLoop(int_t origin) const
Computes the length of the shortest loop from the given vertex to itself.
void getWeights(Table &tab) const
Gets the weights of all the edges at a time.
void DFScolor(Table &tab, const Color &color, int_t vertex=0) const
Marks each vertex visited by DFS with the given color, starting with the given vertex.
void DFSfinishTime(Table &tab) const
Computes the DFS finishing time for each vertex.
void DFSfinishTimeStack(Table &tab, int_t vertex, int_t &counter) const
A stack version of the recurrent procedure for DFSfinishTime.
void setWeight(int_t vertex, int_t i, const wType &weight)
Sets the weight of the given edge.
void DFScolorStack(Table &tab, const Color &color, int_t vertex=0) const
A stack version of the recurrent procedure for DFScolor.
wType Johnson(const roundType &rounding, arrayType &arr, bool setInfinity=true, bool ignoreNegLoop=false) const
Runs Johnson's algorithm to compute the minimum path weight between any vertices in the graph.
void DFScolorRecurrent(Table &tab, const Color &color, int_t vertex=0) const
The recurrent procedure for DFScolor.
void addVertex(void)
Adds a vertex.
void DFSfinishTimeRecurrent(Table &tab, int_t vertex, int_t &counter) const
The recurrent procedure for DFSfinishTime.
bool BellmanFord(const roundType &rounding, int_t source, lenTable &len, wType *infinity, predTable pred) const
Runs the Bellman-Ford algorithm which computes the single-source shortest paths in a weighted directe...
int_t getEdge(int_t vertex, int_t i) const
Retrieves the given edge that leaves the given vertex.
void transpose(diGraph< wType1 > &result, bool copyweights=false) const
Creates a transposed graph.
wType EdmondsOld() const
An old implementation of the Edmonds algorithm (less efficient).
multitable< wType > weights
A table with edge weights.
int_t countEdges(void) const
Returns the number of edges.
A dummy array of integers that ignores all the assigned values.
dummyArray()
The constructor of a dummy array.
int_t & operator[](int_t)
Operator [] which returns a reference to a dummy value.
int_t n
A dummy number used as a dump box for assigning values.
A dummy class for rounding operations which does not actually do any rounding.
static numType mul_down(const numType &x, const numType &y)
Multiplies two numbers with the result rounded downwards.
static numType div_up(const numType &x, const numType &y)
Divides two numbers with the result rounded upwards.
static numType div_down(const numType &x, int_t y)
Divides a number by an integer with the result rounded downwards.
static numType add_down(const numType &x, const numType &y)
Adds two numbers with the result rounded downwards.
static numType sub_down(const numType &x, const numType &y)
Subtracts two numbers with the result rounded downwards.
static numType sub_up(const numType &x, const numType &y)
Subtracts two numbers with the result rounded upwards.
static numType add_up(const numType &x, const numType &y)
Adds two numbers with the result rounded upwards.
static numType mul_up(const numType &x, const numType &y)
Multiplies two numbers with the result rounded upwards.
static numType div_down(const numType &x, const numType &y)
Divides two numbers with the result rounded downwards.
This class defines a simple data structure for a flat 2-dim square matrix whose entries are stored in...
A class that stores the time at which it was initialized and then returns or displays the time used s...
This file contains the definition of a Fibonacci heap optimized for good memory usage.
This file contains the definition of a simple matrix class which is stored in a single vector,...
int int_t
Index type for indexing arrays, counting cubes, etc.
This file contains the definition of the container "hashedset" which can be used to represent a set o...
This file contains the definition of the container "multitable" which is essentially an automatically...
int_t computePeriod(const GraphType &g)
Computes the period of a strongly connected graph.
int_t inclusionGraph(const diGraph< wType > &g, int_t nVert, diGraph< wType > &result)
Computes the graph that represents flow-induced relations on Morse sets.
void graph2matrix(const diGraph< wType > &g, matrix &m)
Creates the adjacency matrix of the given graph.
void transitiveReduction(matrix &m, int_t n)
Computes the transitive reduction of a CLOSED acyclic graph defined by its adjacency matrix,...
void matrix2graph(const matrix &m, int_t n, diGraph< wType > &g)
Creates a graph based on the given adjacency matrix.
std::ostream & operator<<(std::ostream &out, const bincube< Dim, twoPower > &b)
outputstream sbug
An output stream for writing additional debug messages.
int_t collapseVertices(const diGraph< wType > &g, int_t compNum, Table1 &compVertices, Table2 &compEnds, diGraph< wType > &result, int_t *newNumbers=0)
Collapses disjoint subsets of vertices to single vertices and creates a corresponding graph in which ...
int_t addRenumEdges2(const diGraph< wType > &g, int_t vertex, const int_t *newNum, TabSets &numSets, int_t cur, int_t *srcVert, diGraph< wType > &result)
A helper function for "collapseVertices2".
int_t connectionGraph(const diGraph< wType > &g, int_t nVert, diGraph< wType > &result)
Computes the graph that represents connections between a number of the first vertices in the given gr...
void transitiveClosure(matrix &m, int_t n)
Computes the transitive closure of an acyclic graph defined by its adjacency matrix,...
int_t collapseVertices2(const diGraph< wType > &g, int_t compNum, Table1 &compVertices, Table2 &compEnds, diGraph< wType > &result)
Collapses (possibly non-disjoint) subsets of vertices to single vertices and creates a corresponding ...
bool operator!=(const typename bincube< Dim, twoPower >::neighborhood_iterator &x1, const typename bincube< Dim, twoPower >::neighborhood_iterator &x2)
int_t addRenumEdges(const diGraph< wType > &g, int_t vertex, const int_t *newNum, int_t cur, int_t *srcVert, diGraph< wType > &result)
A helper function for "collapseVertices".
bool operator==(const typename bincube< Dim, twoPower >::neighborhood_iterator &x1, const typename bincube< Dim, twoPower >::neighborhood_iterator &x2)
int_t SCC_Tarjan(const diGraph< wType > &g, Table1 &compVertices, Table2 &compEnds)
Computes strongly connected components of the graph 'g' using Tarjan's algorithm (as described in the...
int_t SCC(const diGraph< wType > &g, Table1 &compVertices, Table2 &compEnds, diGraph< wType > *scc=0, diGraph< wType > *transposed=0, bool copyweights=false)
Computes strongly connected components of the graph 'g'.
void swap(mwWorkerData &data1, mwWorkerData &data2)
This namespace contains the entire CHomP library interface.
A helper class for ignoring predecessor information.
void add(int_t, int_t, int_t)
An edge with a weight (used by the Edmonds algorithm).
wType weight
The weight of the edge.
int_t vert1
The starting and ending vertices of the edge.
friend bool operator<(const edgeTriple &x, const edgeTriple &y)
The < operator for comparing the weights of edges.
This file contains some useful functions related to the text input/output procedures.
This file defines a simple data structure which can be used to measure time used by the program (or s...