Skip to content

Commit 0cf7fcb

Browse files
committed
more tests
1 parent 817c3fc commit 0cf7fcb

File tree

7 files changed

+298
-61
lines changed

7 files changed

+298
-61
lines changed

include/maxplus/base/analysis/mcm/mcm.h

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,45 @@
4949

5050
namespace Graphs {
5151

52-
/**
53-
* maximumCycleMeanKarp ()
54-
* The function computes the maximum cycle mean of an MCMgraph using Karp's
55-
* algorithm.
56-
*/
52+
/// <summary>
53+
/// The function computes the maximum cycle mean of an MCMgraph using Karp's
54+
/// algorithm.
55+
/// Assumes thal all nodes of the graph have an outgoing edge.
56+
/// Assumes that the edge weights are integer (!)
57+
/// </summary>
58+
/// <param name="g">graph to analyse</param>
59+
/// <returns>The maximum cycle mean of the graph.</returns>
5760
CDouble maximumCycleMeanKarp(MCMgraph& g);
58-
CDouble maximumCycleMeanKarpDouble(MCMgraph& g, const MCMnode **criticalNode = nullptr);
61+
62+
/// <summary>
63+
/// The function computes the maximum cycle mean of an MCMgraph using Karp's
64+
/// algorithm.
65+
/// </summary>
66+
/// <param name="g">graph to analyse</param>
67+
/// <param name="criticalNodeg">optional, will point to an arbitrary node on the cycle with the maximum cycle mean.</param>
68+
/// <returns>The maximum cycle mean of the graph and optionally a critical node.</returns>
69+
CDouble maximumCycleMeanKarpDouble(MCMgraph &g, const MCMnode **criticalNode = nullptr);
70+
71+
/// <summary>
72+
/// The function computes the maximum cycle mean of an MCMgraph using Karp's
73+
/// algorithm.
74+
/// Does not require that all nodes of the graph have an outgoing edge.
75+
/// Assumes that the edge weights are integer (!)
76+
/// </summary>
77+
/// <param name="g">graph to analyse</param>
78+
/// <returns>The maximum cycle mean of the graph.</returns>
79+
CDouble maximumCycleMeanKarpGeneral(MCMgraph &g);
80+
81+
/// <summary>
82+
/// The function computes the maximum cycle mean of an MCMgraph using Karp's
83+
/// algorithm.
84+
/// Does not require that all nodes of the graph have an outgoing edge.
85+
/// </summary>
86+
/// <param name="g">graph to analyse</param>
87+
/// <param name="criticalNodeg">optional, will point to an arbitrary node on the cycle with the maximum cycle mean.</param>
88+
/// <returns>The maximum cycle mean of the graph and optionally a critical node.</returns>
89+
CDouble maximumCycleMeanKarpDoubleGeneral(MCMgraph &g, const MCMnode **criticalNode = nullptr);
90+
5991

6092
/**
6193
* mcmGetAdjacentActors ()

include/maxplus/base/analysis/mcm/mcmhoward.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ void convertMCMgraphToMatrix(MCMgraph& g, std::shared_ptr<std::vector<int>> *ij,
7676
* NIterations: Number of iterations of the algorithm
7777
* NComponents: Number of connected components of the optimal policy
7878
*
79+
* ASSUMPTIONS
80+
* The graph has a non-zero number of nodes
81+
* The graph has a non-zero number of edges
82+
* Every node in the graph has outgoing directed edges
7983
*/
8084

8185
void Howard(const std::vector<int> &ij,
@@ -88,8 +92,37 @@ void Howard(const std::vector<int> &ij,
8892
int *nr_iterations,
8993
int *nr_components);
9094

95+
/**
96+
* maximumCycleMeanHoward ()
97+
* Howard Policy Iteration Algorithm for Max Plus Matrices.
98+
*
99+
* INPUT MCMgraph which must have outoing edges from every node
100+
*
101+
* OUTPUT:
102+
* maximum cycle mean
103+
* a node on the cycle with maximum cycle mean
104+
*
105+
* ASSUMPTIONS
106+
* The graph has a non-zero number of nodes
107+
* The graph has a non-zero number of edges
108+
* Every node in the graph has outgoing directed edges
109+
*
110+
*/
91111
CDouble maximumCycleMeanHoward(MCMgraph &g, MCMnode **criticalNode);
92112

113+
/**
114+
* maximumCycleMeanHowardGeneral ()
115+
* Howard Policy Iteration Algorithm for Max Plus Matrices.
116+
*
117+
* INPUT MCMgraph which can be arbitrary
118+
*
119+
* OUTPUT:
120+
* maximum cycle mean
121+
* a node on the cycle with maximum cycle mean
122+
*
123+
*/
124+
CDouble maximumCycleMeanHowardGeneral(MCMgraph &g, MCMnode **criticalNode);
125+
93126

94127
} // namespace Graphs
95128
#endif

include/maxplus/base/analysis/mcm/mcmyto.h

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -106,19 +106,19 @@ using graph = struct Graph {
106106
*/
107107
CDouble maxCycleMeanYoungTarjanOrlin(MCMgraph& mcmGraph);
108108

109-
/**
110-
* maxCycleMeanAndCriticalCycleYoungTarjanOrlin ()
111-
* The function computes the maximum cycle mean of edge weight of
112-
* an MCMgraph using Young-Tarjan-Orlin's algorithm.
113-
* It returns both the MCM and a critical cycle
114-
* The critical cycle is only returned if cycle and len are not NULL. Then *cycle points
115-
* to an array of *MCMEdges of the critical cycle and *len indicates the length of the cycle.
116-
* *cycle is a freshly allocated array and it is the caller's obligation to deallocate it
117-
* in due time.
118-
*/
109+
110+
/// The function computes the maximum cycle mean of edge weight of
111+
/// an MCMgraph using Young-Tarjan-Orlin's algorithm.
112+
/// It returns both
113+
/// The critical cycle is only returned if cycle is not NULL. Then *cycle points
114+
/// to an array of *MCMEdges of the critical cycle.
115+
/// @param mcmGraph The graph to analyze
116+
/// @param cycle Pointer to the critical cycle
117+
/// @return the MCM and a critical cycle
119118
CDouble
120119
maxCycleMeanAndCriticalCycleYoungTarjanOrlin(MCMgraph& mcmGraph, std::shared_ptr<std::vector<const MCMedge*>> *cycle);
121120

121+
122122
/**
123123
* maxCycleRatioYoungTarjanOrlin ()
124124
* The function computes the maximum cycle ratio of edge weight over delay of
@@ -131,10 +131,8 @@ CDouble maxCycleRatioYoungTarjanOrlin(MCMgraph& mcmGraph);
131131
* The function computes the maximum cycle ratio of edge weight over delay of
132132
* an MCMgraph using Young-Tarjan-Orlin's algorithm.
133133
* It returns both the MCR and a critical cycle
134-
* The critical cycle is only returned if cycle and len are not NULL. Then *cycle points
135-
* to an array of *MCMEdges of the critical cycle and *len indicates the length of the cycle.
136-
* *cycle is a freshly allocated array and it is the caller's obligation to deallocate it
137-
* in due time.
134+
* The critical cycle is only returned if cycle is not NULL. Then *cycle points
135+
* to an array of *MCMEdges of the critical cycle/
138136
*/
139137
CDouble
140138
maxCycleRatioAndCriticalCycleYoungTarjanOrlin(MCMgraph& mcmGraph, std::shared_ptr<std::vector<const MCMedge*>> *cycle);
@@ -151,10 +149,8 @@ CDouble minCycleRatioYoungTarjanOrlin(MCMgraph& mcmGraph);
151149
* The function computes the minimum cycle ratio of edge weight over delay of
152150
* an MCMgraph using Young-Tarjan-Orlin's algorithm.
153151
* It returns both the MCR and a critical cycle
154-
* The critical cycle is only returned if cycle and len are not NULL. Then *cycle points
155-
* to an array of *MCMEdges of the critical cycle and *len indicates the length of the cycle.
156-
* *cycle is a freshly allocated array and it is the caller's obligation to deallocate it
157-
* in due time.
152+
* The critical cycle is only returned if cycle is not NULL. Then *cycle points
153+
* to an array of *MCMEdges of the critical cycle.
158154
*/
159155
CDouble
160156
minCycleRatioAndCriticalCycleYoungTarjanOrlin(MCMgraph& mcmGraph, std::shared_ptr<std::vector<const MCMedge*>> *cycle);

src/base/analysis/mcm/mcmhoward.cc

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class AlgHoward {
9999
*chi = std::make_shared<std::vector<CDouble>>(nr_nodes);
100100
*v = std::make_shared<std::vector<CDouble>>(nr_nodes);
101101

102-
Security_Check();
102+
Safety_Check();
103103
Allocate_Memory();
104104
Epsilon(&epsilon);
105105
Initial_Policy();
@@ -379,9 +379,11 @@ class AlgHoward {
379379
}
380380

381381
void Check_Rows() {
382+
// check if every node has outgoing edges.
382383
std::vector<int> u(nr_nodes);
383384

384385
for (int i = 0; i < narcs; i++) {
386+
// ij[2*k] is the source node number of edge number k
385387
u[ij[2 * i]] = 1;
386388
}
387389

@@ -392,7 +394,7 @@ class AlgHoward {
392394
}
393395
}
394396

395-
void Security_Check() {
397+
void Safety_Check() {
396398
if (nr_nodes < 1) {
397399
throw CException("Howard: number of nodes must be a positive integer.");
398400
}
@@ -482,7 +484,6 @@ void Howard(const std::vector<int> &ij,
482484
void convertMCMgraphToMatrix(MCMgraph &g,
483485
std::shared_ptr<std::vector<int>> *ij,
484486
std::shared_ptr<std::vector<CDouble>> *A) {
485-
int k = 0;
486487
uint i = 0;
487488
uint j = 0;
488489
v_uint mapId(g.getNodes().size());
@@ -502,8 +503,9 @@ void convertMCMgraphToMatrix(MCMgraph &g,
502503
auto& Ar = *(*A);
503504

504505
// Create an entry in the matrices for each edge
506+
int k = 0;
505507
for (const auto &e : g.getEdges()) {
506-
// Is the edge a existing edge in the graph?
508+
// Is the edge an existing edge in the graph?
507509
if (e.visible) {
508510
ijr[2 * k] = mapId[e.src->id];
509511
ijr[2 * k + 1] = mapId[e.dst->id];
@@ -563,5 +565,31 @@ CDouble maximumCycleMeanHoward(MCMgraph& g, MCMnode* *criticalNode) {
563565
return mcm;
564566
}
565567

568+
CDouble maximumCycleMeanHowardGeneral(MCMgraph &g, MCMnode **criticalNode) {
569+
570+
MCMgraphs sccs;
571+
stronglyConnectedMCMgraph(g, sccs, false);
572+
573+
CDouble mcm = -INFINITY;
574+
if (criticalNode != nullptr) {
575+
*criticalNode = nullptr;
576+
}
577+
for (auto &scc : sccs) {
578+
std::map<int, int> nodeMap;
579+
scc->relabelNodeIds(&nodeMap);
580+
MCMnode *sccCriticalNode = nullptr;
581+
;
582+
CDouble cmcm = maximumCycleMeanHoward(*scc, &sccCriticalNode);
583+
if (cmcm > mcm) {
584+
mcm = cmcm;
585+
if (criticalNode != nullptr) {
586+
*criticalNode = g.getNode(nodeMap[sccCriticalNode->id]);
587+
}
588+
}
589+
}
590+
591+
return mcm;
592+
}
593+
566594

567595
} // namespace Graphs

src/base/analysis/mcm/mcmkarp.cc

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,16 @@
4747
namespace Graphs {
4848
/**
4949
* mcmKarp ()
50-
* The function computes the maximum cycle mean of an MCMgGraph using Karp's
50+
* The function computes the maximum cycle mean of an MCMgraph using Karp's
5151
* algorithm.
5252
* Note that the following assumptions are made about the MCMgraph
5353
* 1. it is assumed that the edge weights have integer values.
5454
* 2. it is assumed that all nodes in the graph are 'visible'
5555
* 3. it is assumed that the node have id's ranging from 0 up to the number of nodes.
56+
* 4. it is assumed that all nodes have an outgoing directed edge
5657
*
57-
* The critical cycle is only returned if cycle and len are not nullptr. Then *cycle points
58-
* to an array of MCMEdges of the critical cycle and *len indicates the length of the cycle.
59-
* *cycle is a freshly allocated array and it is the caller's obligation to deallocate it
60-
* in due time.
58+
* The critical cycle is only returned if cycle is not nullptr. Then *cycle points
59+
* to an array of MCMEdges of the critical cycle.
6160
* cycle - pointers to arcs on maximum ratio cycle,
6261
* ordered in array from top to bottom with
6362
* respect to subsequent arcs on cycle
@@ -106,6 +105,26 @@ CDouble maximumCycleMeanKarp(MCMgraph &mcmGraph) {
106105
return l;
107106
}
108107

108+
CDouble maximumCycleMeanKarpGeneral(MCMgraph& g) {
109+
MCMgraphs sccs;
110+
stronglyConnectedMCMgraph(g, sccs, false);
111+
112+
CDouble mcm = -INFINITY;
113+
for (auto &scc : sccs) {
114+
std::map<int, int> nodeMap;
115+
scc->relabelNodeIds(&nodeMap);
116+
MCMnode *sccCriticalNode = nullptr;
117+
;
118+
CDouble cmcm = maximumCycleMeanKarp(*scc);
119+
if (cmcm > mcm) {
120+
mcm = cmcm;
121+
}
122+
}
123+
124+
return mcm;
125+
}
126+
127+
109128
/**
110129
* maximumCycleMeanKarpDouble ()
111130
* The function computes the maximum cycle mean of an MCMgGraph using Karp's
@@ -166,4 +185,29 @@ CDouble maximumCycleMeanKarpDouble(MCMgraph &mcmGraph, const MCMnode **criticalN
166185
return l;
167186
}
168187

188+
CDouble maximumCycleMeanKarpDoubleGeneral(MCMgraph &g, const MCMnode **criticalNode) {
189+
MCMgraphs sccs;
190+
stronglyConnectedMCMgraph(g, sccs, false);
191+
192+
CDouble mcm = -INFINITY;
193+
if (criticalNode != nullptr) {
194+
*criticalNode = nullptr;
195+
}
196+
for (auto &scc : sccs) {
197+
std::map<int, int> nodeMap;
198+
scc->relabelNodeIds(&nodeMap);
199+
const MCMnode *sccCriticalNode = nullptr;
200+
;
201+
CDouble cmcm = maximumCycleMeanKarpDouble(*scc, &sccCriticalNode);
202+
if (cmcm > mcm) {
203+
mcm = cmcm;
204+
if (criticalNode != nullptr) {
205+
*criticalNode = g.getNode(nodeMap[sccCriticalNode->id]);
206+
}
207+
}
208+
}
209+
210+
return mcm;
211+
}
212+
169213
} // namespace Graphs

src/base/analysis/mcm/mcmyto.cc

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,10 +1066,8 @@ CDouble getDelay(const MCMedge& e) { return e.d; }
10661066
* The function computes the maximum cycle mean of edge weight of
10671067
* an MCMgraph using Young-Tarjan-Orlin's algorithm.
10681068
* It returns both the MCM and a critical cycle
1069-
* The critical cycle is only returned if cycle and len are not nullptr. Then *cycle points
1070-
* to an array of *MCMEdges of the critical cycle and *len indicates the length of the cycle.
1071-
* *cycle is a freshly allocated array and it is the caller's obligation to deallocate it
1072-
* in due time.
1069+
* The critical cycle is only returned if cycle is not nullptr. Then *cycle points
1070+
* to an array of *MCMEdges of the critical cycle.
10731071
*
10741072
* Note that the following assumed are made about the MCMgraph
10751073
* 1. it is assumed that all nodes in the graph are 'visible'
@@ -1126,11 +1124,8 @@ CDouble maxCycleMeanYoungTarjanOrlin(MCMgraph &mcmGraph) {
11261124
* The function computes the maximum cycle ratio of edge weight over delay of
11271125
* an MCMgraph using Young-Tarjan-Orlin's algorithm.
11281126
* It returns both the MCR and a critical cycle
1129-
* Since MCM is in C-style code, let's do it the C-way.
1130-
* The critical cycle is only returned if cycle and len are not nullptr. Then *cycle points
1131-
* to an array of MCMEdges of the critical cycle and *len indicates the length of the cycle.
1132-
* *cycle is a freshly allocated array and it is the caller's obligation to deallocate it
1133-
* in due time.
1127+
* The critical cycle is only returned if cycle is not nullptr. Then *cycle points
1128+
* to a vector of MCMEdges of the critical cycle.
11341129
*/
11351130

11361131
CDouble maxCycleRatioAndCriticalCycleYoungTarjanOrlin(MCMgraph &mcmGraph,
@@ -1191,10 +1186,8 @@ CDouble maxCycleRatioYoungTarjanOrlin(MCMgraph &mcmGraph) {
11911186
* The function computes the minimum cycle ratio of edge weight over delay of
11921187
* an MCMgraph using Young-Tarjan-Orlin's algorithm.
11931188
* It returns both the MCR and a critical cycle
1194-
* The critical cycle is only returned if cycle and len are not nullptr. Then *cycle points
1195-
* to an array of MCMEdges of the critical cycle and *len indicates the length of the cycle.
1196-
* *cycle is a freshly allocated array and it is the caller's obligation to deallocate it
1197-
* in due time.
1189+
* The critical cycle is only returned if cycle is not nullptr. Then *cycle points
1190+
* to an array of MCMEdges of the critical cycle.
11981191
*/
11991192

12001193
CDouble minCycleRatioAndCriticalCycleYoungTarjanOrlin(MCMgraph &mcmGraph,

0 commit comments

Comments
 (0)