@@ -49,58 +49,55 @@ Set LtEdgesMRV::decreasingRepresentative(const PWMap& rmap) const
4949 return result;
5050}
5151
52- Set LtEdgesMRV::edgesInPaths (const PWMap& smap) const
53- {
54- PWMap mapB = _dsbg.mapB ();
55- PWMap mapD = _dsbg.mapD ();
56-
57- // Vertices that are successors of other vertices in a path
58- Set not_fixed = smap.domain ().difference (smap.fixedPoints ());
59- Set succs = smap.restrict (not_fixed).image ();
60- // Edges whose endings are successors
61- Set ending_edges = mapD.preImage (succs);
62- // Map from a 'successor' edge to its start
63- PWMap auxB = mapB.restrict (ending_edges);
64- // Map from edge to the successor of its start
65- PWMap map_succs = smap.composition (auxB);
66-
67- return map_succs.equalImage (mapD);
68- }
69-
70- PWMap LtEdgesMRV::recursivePaths (const Set& ith_paths_edges, const Set& outgoing)
52+ PWMap LtEdgesMRV::recursivePaths (const PWMap& rmap
53+ , const PWMap& decreasing_smap)
7154{
7255 PWMap result = PWMAP_FACT.createPWMap ();
7356
57+ // Calculate edges in paths described by _smap
58+ const PWMap& mapB = _dsbg.mapB ();
59+ const PWMap& mapD = _dsbg.mapD ();
60+ Set ithP = decreasing_smap.composition (mapB).equalImage (mapD);
61+
62+ // Check if there is a recursion
7463 PWMap Emap = _dsbg.Emap ();
75- Set ithSE = Emap.image (ith_paths_edges);
76- _visitedSE = std::move (_visitedSE).cup (ithSE);
64+ Set ithSE = Emap.image (ithP);
7765 Set repeatedSE = _visitedSE.intersection (ithSE);
7866 if (!repeatedSE.isEmpty ()) {
79- PWMap mapB = _dsbg.mapB ();
80- PWMap mapD = _dsbg.mapD ();
81-
67+ Set P = _smap.composition (mapB).equalImage (mapD);
8268 Set ith_start = _smap.domain ().difference (_smap.image ());
83- Set E = SET_FACT.createSet ();
84- Set ithE = mapB.preImage (ith_start).intersection (ith_paths_edges);
69+ Set ithE = mapB.preImage (ith_start).intersection (P);
8570 if (!ithE.isEmpty ()) {
71+ Set E = SET_FACT.createSet ();
8672 bool exit_condition = true ;
8773 do {
88- ithE = mapB.preImage (ith_start).intersection (ith_paths_edges);
89- E = std::move (E).disjointCup (std::move (ithE));
90- ith_start = mapD.image (ithE);
9174 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));
9278 } 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);
9397 }
94-
95- Set smap_edges = edgesInPaths (_smap);
96- Set adj = mapB.preImage (mapB.image (smap_edges));
97-
98- Set E_plus = Emap.preImage (Emap.image (E));
99- E_plus = E_plus.difference (mapB.preImage (outgoing));
100- E_plus = E_plus.difference (adj);
101- PWMap mapB_plus = _dsbg.mapB ().restrict (E_plus);
102- PWMap mapD_plus = _dsbg.mapD ().restrict (E_plus);
103- result = mapB_plus.minAdj (mapD_plus);
98+ _visitedSE = _visitedSE.difference (Emap.image (P));
99+ } else {
100+ _visitedSE = std::move (_visitedSE).disjointCup (std::move (ithSE));
104101 }
105102
106103 return result;
@@ -122,7 +119,6 @@ PWMap LtEdgesMRV::calculate(const DirectedSBG& dsbg)
122119 if (!_dsbg.V ().isEmpty () && !_dsbg.E ().isEmpty ()) {
123120 PWMap old_rmap = PWMAP_FACT.createPWMap ();
124121 Set E = SET_FACT.createSet ();
125- Set paths_edges = SET_FACT.createSet ();
126122 do {
127123 old_rmap = rmap;
128124
@@ -134,10 +130,7 @@ PWMap LtEdgesMRV::calculate(const DirectedSBG& dsbg)
134130 _smap = decreasing_smap.combine (std::move (_smap));
135131
136132 // Recursive paths
137- Set ith_paths_edges = edgesInPaths (decreasing_smap);
138- Set outgoing = rmap.image (mapD.image (ith_paths_edges));
139- PWMap smap_plus = recursivePaths (ith_paths_edges, outgoing);
140- _smap = std::move (smap_plus).combine (std::move (_smap));
133+ _smap = recursivePaths (rmap, decreasing_smap).combine (std::move (_smap));
141134
142135 // Calculate representatives map
143136 rmap = _smap.mapInf ();
0 commit comments