Skip to content

Commit 766da8f

Browse files
committed
Simplified SCC algorithm
1 parent c95efdc commit 766da8f

2 files changed

Lines changed: 39 additions & 42 deletions

File tree

algorithms/scc/decreasing_edges_mrv.cpp

Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include "sbg/set_fact.hpp"
2323
#include "util/logger.hpp"
2424

25+
#include <iostream>
26+
2527
namespace SBG {
2628

2729
namespace LIB {
@@ -31,7 +33,7 @@ namespace LIB {
3133
////////////////////////////////////////////////////////////////////////////////
3234

3335
LtEdgesMRV::LtEdgesMRV() : _dsbg(), _smap(PWMAP_FACT.createPWMap())
34-
, _visitedSE(SET_FACT.createSet()) {}
36+
, _visitedSE(SET_FACT.createSet()), _n(0) {}
3537

3638
Set LtEdgesMRV::decreasingRepresentative(const PWMap& rmap) const
3739
{
@@ -49,55 +51,48 @@ Set LtEdgesMRV::decreasingRepresentative(const PWMap& rmap) const
4951
return result;
5052
}
5153

52-
PWMap LtEdgesMRV::recursivePaths(const PWMap& rmap
54+
PWMap LtEdgesMRV::repetitivePaths(const PWMap& rmap
5355
, const PWMap& decreasing_smap)
5456
{
5557
PWMap result = PWMAP_FACT.createPWMap();
5658

57-
// Calculate edges in paths described by _smap
59+
// Calculate edges in paths described by decreasing_smap
5860
const PWMap& mapB = _dsbg.mapB();
5961
const PWMap& mapD = _dsbg.mapD();
60-
Set ithP = decreasing_smap.composition(mapB).equalImage(mapD);
62+
Set Pj = decreasing_smap.composition(mapB).equalImage(mapD);
6163

62-
// Check if there is a recursion
64+
// Check if there is a repetition
6365
PWMap Emap = _dsbg.Emap();
64-
Set ithSE = Emap.image(ithP);
65-
Set repeatedSE = _visitedSE.intersection(ithSE);
66+
Set repeatedSE = _visitedSE.intersection(Emap.image(Pj));
6667
if (!repeatedSE.isEmpty()) {
67-
Set P = _smap.composition(mapB).equalImage(mapD);
68-
Set ith_start = _smap.domain().difference(_smap.image());
69-
Set ithE = mapB.preImage(ith_start).intersection(P);
70-
if (!ithE.isEmpty()) {
71-
Set E = SET_FACT.createSet();
72-
bool exit_condition = true;
73-
do {
74-
exit_condition = !repeatedSE.intersection(Emap.image(E)).isEmpty();
75-
ithE = mapB.preImage(ith_start).intersection(P);
76-
ith_start = mapD.image(ithE);
77-
E = std::move(E).disjointCup(std::move(ithE));
78-
} while (!exit_condition);
79-
// Take out edges that reach a MRV different from that of the recursion
80-
PWMap ithP_rmap = rmap.composition(mapD.restrict(ithP));
81-
Set ithP_mrvs = ithP_rmap.image();
82-
E = E.intersection(ithP_rmap.preImage(ithP_mrvs));
83-
84-
Set E_plus = Emap.preImage(Emap.image(E));
85-
// In the presence of a cycle, if the minimum vertex belongs to the
86-
// recursion, it will be assigned a successor. This results in a cycling
87-
// smap, which is an error. For example, if there's a cycle
88-
// 1 -> 2 -> ... -> 10 -> 1, this function calculates smap(1) = 2,
89-
// when it should be smap(1) = 1. To avoid this, we erase outgoing edges
90-
// from vertices that already reach the desired MRV.
91-
Set outgoing = mapB.preImage(rmap.preImage(ithP_mrvs));
92-
E_plus = E_plus.difference(outgoing);
93-
94-
PWMap mapB_plus = _dsbg.mapB().restrict(E_plus);
95-
PWMap mapD_plus = _dsbg.mapD().restrict(E_plus);
96-
result = mapB_plus.minAdj(mapD_plus);
68+
Set Vi = decreasing_smap.domain().difference(decreasing_smap.image());
69+
Set V = Vi;
70+
for (unsigned int j = 0; j < _n; ++j) {
71+
Vi = _smap.image(Vi);
72+
V = V.disjointCup(Vi);
9773
}
98-
_visitedSE = _visitedSE.difference(Emap.image(P));
74+
PWMap rec_smap = _smap.restrict(V);
75+
Set E_repetition = rec_smap.composition(mapB).equalImage(mapD);
76+
77+
Set E_plus = Emap.preImage(Emap.image(E_repetition));
78+
// In the presence of a cycle, if the minimum vertex belongs to the
79+
// repetition, it will be assigned a successor. This results in a cycling
80+
// smap, which is an error. For example, if there's a cycle
81+
// 1 -> 2 -> ... -> 10 -> 1, this function calculates smap(1) = 2,
82+
// when it should be smap(1) = 1. To avoid this, we erase outgoing edges
83+
// from the MRVs of the repetition.
84+
Set outgoing = mapB.preImage(rmap.image(V));
85+
E_plus = E_plus.difference(outgoing);
86+
87+
PWMap mapB_plus = _dsbg.mapB().restrict(E_plus);
88+
PWMap mapD_plus = _dsbg.mapD().restrict(E_plus);
89+
result = mapB_plus.minAdj(mapD_plus);
90+
91+
_visitedSE = _visitedSE.difference(Emap.image(E_repetition));
92+
_n = 0;
9993
} else {
100-
_visitedSE = std::move(_visitedSE).disjointCup(std::move(ithSE));
94+
_visitedSE = std::move(_visitedSE).disjointCup(std::move(Emap.image(Pj)));
95+
++_n;
10196
}
10297

10398
return result;
@@ -117,6 +112,7 @@ PWMap LtEdgesMRV::calculate(const DirectedSBG& dsbg)
117112
PWMap rmap = _smap;
118113

119114
if (!_dsbg.V().isEmpty() && !_dsbg.E().isEmpty()) {
115+
_n = 0;
120116
PWMap old_rmap = PWMAP_FACT.createPWMap();
121117
Set E = SET_FACT.createSet();
122118
do {
@@ -129,8 +125,8 @@ PWMap LtEdgesMRV::calculate(const DirectedSBG& dsbg)
129125
PWMap decreasing_smap = decreasingB.minAdj(decreasingD);
130126
_smap = decreasing_smap.combine(std::move(_smap));
131127

132-
// Recursive paths
133-
_smap = recursivePaths(rmap, decreasing_smap).combine(std::move(_smap));
128+
// Repetitive paths
129+
_smap = repetitivePaths(rmap, decreasing_smap).combine(std::move(_smap));
134130

135131
// Calculate representatives map
136132
rmap = _smap.mapInf();

algorithms/scc/decreasing_edges_mrv.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,12 @@ class LtEdgesMRV : public MRVContext<LtEdgesMRV> {
6767
/*
6868
* @brief Calculates the MRV for recursive paths.
6969
*/
70-
PWMap recursivePaths(const PWMap& rmap, const PWMap& decreasing_smap);
70+
PWMap repetitivePaths(const PWMap& rmap, const PWMap& decreasing_smap);
7171

7272
DirectedSBG _dsbg;
7373
PWMap _smap;
7474
Set _visitedSE;
75+
unsigned int _n;
7576
};
7677

7778
} // namespace LIB

0 commit comments

Comments
 (0)