Skip to content

Commit 7059f23

Browse files
author
Marc Geilen
committed
Merge branch 'more-tests' into main
2 parents e92cf36 + bc6b16c commit 7059f23

File tree

12 files changed

+446
-85
lines changed

12 files changed

+446
-85
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/mcmdg.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@
1414
* Function : Compute the MCM for a graph using Dasdan-Gupta's
1515
* algorithm.
1616
*
17+
* @article{Dasdan1998FasterMA,
18+
* title={Faster maximum and minimum mean cycle algorithms for system-performance analysis},
19+
* author={Ali Dasdan and Rajesh K. Gupta},
20+
* journal={IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.},
21+
* year={1998},
22+
* volume={17},
23+
* pages={889-899}
24+
* }
25+
*
1726
* History :
1827
* 08-11-05 : Initial version.
1928
*
@@ -48,9 +57,10 @@ namespace Graphs {
4857

4958
/**
5059
* mcmDG ()
51-
* The function computes the maximum cycle mean of a HSDF graph using
60+
* The function computes the maximum cycle mean of an MCM graph using
5261
* Dasdan-Gupta's algorithm.
5362
* Note: this algorithm assumes that edge weights are integer valued !
63+
*
5464
* @todo
5565
* check if algorithm can be generalized to float edge weights
5666
*/

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ class MCMgraph {
105105
MCMgraph &operator=(MCMgraph &&) = delete;
106106
MCMgraph &operator=(const MCMgraph &other) = delete;
107107

108+
[[nodiscard]] unsigned int numberOfNodes() { return static_cast<unsigned int>(this->nodes.size()); };
108109
[[nodiscard]] MCMnodes &getNodes() { return nodes; };
109110
[[nodiscard]] MCMnodeRefs getNodeRefs();
110111
[[nodiscard]] MCMedgeRefs getEdgeRefs();
@@ -127,6 +128,7 @@ class MCMgraph {
127128
return nullptr;
128129
};
129130

131+
[[nodiscard]] unsigned int numberOfEdges() { return static_cast<unsigned int>(this->edges.size()); };
130132
[[nodiscard]] MCMedges &getEdges() { return edges; };
131133

132134
MCMedge *getEdge(CId id) {
@@ -196,7 +198,7 @@ class MCMgraph {
196198
e.dst->in.remove(&e);
197199
}
198200

199-
void relabelNodeIds(std::map<int, int> &nodeIdMap);
201+
void relabelNodeIds(std::map<int, int> *nodeIdMap = nullptr);
200202

201203
// reduce the MCM graph by removing obviously redundant edges
202204
// in particular if there are multiple edges between the same pair

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

Lines changed: 36 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,5 +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+
*/
111+
CDouble maximumCycleMeanHoward(MCMgraph &g, MCMnode **criticalNode);
112+
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+
126+
91127
} // namespace Graphs
92128
#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/algebra/mpmatrix.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,7 @@ Matrix::mp_generalized_eigenvectors() const {
10901090

10911091
// MCM calculation requires node relabelling
10921092
std::map<int, int> sccNodeIdMap;
1093-
scc->relabelNodeIds(sccNodeIdMap);
1093+
scc->relabelNodeIds(&sccNodeIdMap);
10941094

10951095
if (scc->nrVisibleEdges() > 0) {
10961096
// compute MCM mu and critical node n of scc

src/base/analysis/mcm/mcmdg.cc

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@
1414
* Function : Compute the MCM for an HSDF graph using Dasdan-Gupta's
1515
* algorithm.
1616
*
17+
* @article{Dasdan1998FasterMA,
18+
* title={Faster maximum and minimum mean cycle algorithms for system-performance analysis},
19+
* author={Ali Dasdan and Rajesh K. Gupta},
20+
* journal={IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.},
21+
* year={1998},
22+
* volume={17},
23+
* pages={889-899}
24+
* }
25+
*
1726
* History :
1827
* 08-11-05 : Initial version.
1928
*
@@ -46,15 +55,11 @@
4655
#include <memory>
4756

4857
namespace Graphs {
49-
/**
50-
* mcmDG ()
51-
* The function computes the maximum cycle mean of a HSDF graph using
52-
* Dasdan-Gupta's algorithm.
53-
* Note: this algorithm assumes that edge weights are integer valued !
54-
* @todo
55-
* check if algorithm can be generalized to float edge weights
56-
*/
57-
CDouble mcmDG(MCMgraph &mcmGraph) {
58+
59+
// assumes teh graph is strongly connected and assumes the node ids are 0...N-1,
60+
// where N is the number of nodes
61+
CDouble mcmDG_SCC(MCMgraph &mcmGraph) {
62+
5863
// Allocate memory
5964
const int n = mcmGraph.nrVisibleNodes();
6065
std::vector<int> level(n);
@@ -70,17 +75,17 @@ CDouble mcmDG(MCMgraph &mcmGraph) {
7075
level[0] = 0;
7176
std::list<int> Q_k;
7277
Q_k.push_back(0);
73-
std::list<MCMnode*> Q_u;
78+
std::list<MCMnode *> Q_u;
7479
Q_u.push_back(&(mcmGraph.getNodes().front()));
7580

7681
// Compute the distances
7782
int k = Q_k.front();
7883
Q_k.pop_front();
79-
MCMnode* u = Q_u.front();
84+
MCMnode *u = Q_u.front();
8085
Q_u.pop_front();
8186
do {
82-
for (auto& e: u->out) {
83-
MCMnode* v = e->dst;
87+
for (auto &e : u->out) {
88+
MCMnode *v = e->dst;
8489

8590
if (level[v->id] < static_cast<int>(k + 1)) {
8691
Q_k.push_back(k + 1);
@@ -99,7 +104,7 @@ CDouble mcmDG(MCMgraph &mcmGraph) {
99104

100105
// Compute lambda using Karp's theorem
101106
CDouble l = -INT_MAX;
102-
for (const auto & u : mcmGraph.getNodes()) {
107+
for (const auto &u : mcmGraph.getNodes()) {
103108

104109
if (level[u.id] == n) {
105110
CDouble ld = INT_MAX;
@@ -114,5 +119,31 @@ CDouble mcmDG(MCMgraph &mcmGraph) {
114119

115120
return l;
116121
}
122+
123+
124+
/**
125+
* mcmDG ()
126+
* The function computes the maximum cycle mean of an MCM graph using
127+
* Dasdan-Gupta's algorithm.
128+
* Note: this algorithm assumes that edge weights are integer valued !
129+
* @todo
130+
* check if algorithm can be generalized to float edge weights
131+
*/
132+
CDouble mcmDG(MCMgraph &mcmGraph) {
133+
134+
MCMgraphs sccs;
135+
stronglyConnectedMCMgraph(mcmGraph, sccs, false);
136+
137+
CDouble mcm = -INFINITY;
138+
for (auto &scc : sccs) {
139+
scc->relabelNodeIds();
140+
CDouble cmcm = mcmDG_SCC(*scc);
141+
if (cmcm > mcm) {
142+
mcm = cmcm;
143+
}
144+
}
145+
146+
return mcm;
147+
}
117148

118149
} // namespace Graphs

src/base/analysis/mcm/mcmgraph.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -755,11 +755,13 @@ CDouble MCMgraph::calculateMaximumCycleRatioAndCriticalCycleYoungTarjanOrlin(
755755
return maxCycleRatioAndCriticalCycleYoungTarjanOrlin(*this, cycle);
756756
}
757757

758-
void MCMgraph::relabelNodeIds(std::map<int, int> &nodeIdMap) {
758+
void MCMgraph::relabelNodeIds(std::map<int, int> *nodeIdMap) {
759759
int k = 0;
760760
for (auto &i : this->nodes) {
761761
MCMnode &n = i;
762-
nodeIdMap[k] = static_cast<int>(n.id);
762+
if (nodeIdMap != nullptr) {
763+
(*nodeIdMap)[k] = static_cast<int>(n.id);
764+
}
763765
n.id = k;
764766
k++;
765767
}

0 commit comments

Comments
 (0)