Skip to content

Commit 3b5db80

Browse files
committed
- Add calculate for toposort that considers scc rmap
1 parent adaf825 commit 3b5db80

7 files changed

Lines changed: 139 additions & 2 deletions

File tree

algorithms/toposort/min_vertex_ts.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,76 @@ PWMap MinVertexTopoSort::calculate(const DSBG& dsbg) const
114114
return smap.compact();
115115
}
116116

117+
PWMap MinVertexTopoSort::calculate(const DSBG& dsbg, const PWMap& rmap) const
118+
{
119+
Util::DEBUG_LOG << "Topological sort dsbg:\n" << dsbg << "\n\n";
120+
121+
auto begin = std::chrono::high_resolution_clock::now();
122+
PWMap mapB = dsbg.mapB(), mapD = dsbg.mapD(), Vmap = dsbg.Vmap();
123+
PWMap smap = PW_FACT.createPWMap();
124+
Set U = dsbg.V(), Nd = U.difference(mapB.image());
125+
if (!Nd.isEmpty()) {
126+
MD_NAT vsucc = Nd.minElem();
127+
Set SV = SET_FACT.createSet(), E = dsbg.E();
128+
do {
129+
Set vsucc_set = SET_FACT.createSet(SetPiece(vsucc));
130+
Set Nd_vsucc = Nd.intersection(Vmap.preImage(Vmap.image(vsucc_set)));
131+
Set Nd_vsucc_scc = Nd.intersection(rmap.preImage(rmap.image(vsucc_set)));
132+
MD_NAT v = Nd_vsucc_scc.isEmpty() ? Nd.minElem() : Nd_vsucc_scc.minElem();
133+
if (!Nd_vsucc.isEmpty())
134+
v = Nd_vsucc.minElem();
135+
Set d = SET_FACT.createSet(v);
136+
Exp e = calculateExp(v, vsucc);
137+
vsucc = v;
138+
139+
Set SVd = Vmap.image(d);
140+
bool cond = SVd.intersection(SV).isEmpty();
141+
if (!cond) {
142+
Set dvs = Vmap.preImage(SVd);
143+
for (const Map& map : smap.restrict(dvs)) {
144+
if (e == map.exp()) {
145+
d = dvs.difference(smap.dom());
146+
break;
147+
}
148+
}
149+
}
150+
smap.emplaceBack(Map(d, e));
151+
152+
Set Nsucc = U.difference(smap.dom());
153+
Set S = smap.dom().difference(smap.preImage(Nsucc));
154+
155+
E = E.difference(mapD.preImage(S));
156+
mapB = mapB.restrict(E);
157+
mapD = mapD.restrict(E);
158+
159+
U = U.difference(S);
160+
Nd = U.difference(mapB.image());
161+
SV = SV.cup(SVd);
162+
if (S == smap.dom()) {
163+
Set start = smap.dom().difference(smap.image());
164+
if (!start.isEmpty())
165+
vsucc = start.minElem();
166+
}
167+
168+
Util::DEBUG_LOG << "S: " << S << "\n";
169+
Util::DEBUG_LOG << "U: " << U << "\n";
170+
Util::DEBUG_LOG << "E: " << E << "\n";
171+
Util::DEBUG_LOG << "Nd: " << Nd << "\n";
172+
Util::DEBUG_LOG << "smap: " << smap << "\n\n";
173+
} while (!U.isEmpty());
174+
}
175+
auto end = std::chrono::high_resolution_clock::now();
176+
177+
auto total = std::chrono::duration_cast<std::chrono::microseconds>(
178+
end - begin
179+
);
180+
Util::SBG_LOG << "Total topological sort exec time: " << total.count() << " [μs]\n\n";
181+
182+
Util::DEBUG_LOG << "Topological sort result:\n" << smap.compact() << "\n\n";
183+
184+
return smap.compact();
185+
}
186+
117187
} // namespace LIB
118188

119189
} // namespace SBG

algorithms/toposort/min_vertex_ts.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class MinVertexTopoSort : public TSStrategy {
4343
MinVertexTopoSort();
4444

4545
PWMap calculate(const DSBG& dsbg) const override;
46+
47+
PWMap calculate(const DSBG& dsbg, const PWMap& rmap) const override;
4648
};
4749

4850
} // namespace LIB

algorithms/toposort/topo_sort.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ PWMap TopoSort::calculate(const DSBG& dsbg) const
4343
return strategy_->calculate(dsbg);
4444
}
4545

46+
PWMap TopoSort::calculate(const DSBG& dsbg, const PWMap& rmap) const
47+
{
48+
return strategy_->calculate(dsbg, rmap);
49+
}
50+
4651
} // namespace LIB
4752

4853
} // namespace SBG

algorithms/toposort/topo_sort.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class TSStrategy {
4545
TSStrategy();
4646

4747
virtual PWMap calculate(const DSBG& dsbg) const = 0;
48+
49+
virtual PWMap calculate(const DSBG& dsbg, const PWMap& rmap) const = 0;
4850
};
4951

5052
////////////////////////////////////////////////////////////////////////////////
@@ -59,6 +61,8 @@ class TopoSort {
5961
TopoSort(TSStratPtr strat);
6062

6163
PWMap calculate(const DSBG& dsbg) const;
64+
65+
PWMap calculate(const DSBG& dsbg, const PWMap& rmap) const;
6266
};
6367

6468
} // namespace LIB

eval/visitors/expr_evaluator.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ ExprEvaluator::ExprEvaluator(EvalContext& eval_ctx) : eval_ctx_(eval_ctx)
7575
eval_ctx.insertFunction("cut", BuiltInFunctions::cutVertexEvaluator);
7676
eval_ctx.insertFunction("matchSCC", BuiltInFunctions::matchSCCEvaluator);
7777
eval_ctx.insertFunction("tearing", BuiltInFunctions::tearingEvaluator);
78+
eval_ctx.insertFunction("tearingTS", BuiltInFunctions::tearingTSEvaluator);
7879
eval_ctx.insertFunction("matchTearing", BuiltInFunctions::matchTearingEvaluator);
80+
eval_ctx.insertFunction("matchTearingTS", BuiltInFunctions::matchTearingTSEvaluator);
7981
}
8082

8183
ExprBaseType ExprEvaluator::operator()(AST::Natural v) const

eval/visitors/func_evaluator.cpp

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ ExprBaseType BuiltInFunctions::tearingEvaluator(const EBTList& args)
722722
LIB::Tearing tearing_impl = LIB::TEARING_FACT.createTearingAlgorithm();
723723
const auto tearing_evaluator = Overload {
724724
[&tearing_impl](LIB::DSBG a) {
725-
return ExprBaseType(tearing_impl.calculate(a).rmap());
725+
return ExprBaseType(tearing_impl.calculate(a).dsbg());
726726
},
727727
[](auto a) {
728728
Util::ERROR("tearingEvaluator: wrong argument ", a, " for tearing\n");
@@ -735,7 +735,7 @@ ExprBaseType BuiltInFunctions::tearingEvaluator(const EBTList& args)
735735
ExprBaseType BuiltInFunctions::matchTearingEvaluator(const EBTList& args)
736736
{
737737
Util::ERROR_UNLESS(args.size() == 2
738-
, "tearingEvaluator: wrong number of arguments");
738+
, "matchTearingEvaluator: wrong number of arguments");
739739

740740
LIB::Matching match_impl = LIB::MATCH_FACT.createMatchAlgorithm();
741741
LIB::Tearing tearing_impl = LIB::TEARING_FACT.createTearingAlgorithm();
@@ -760,6 +760,58 @@ ExprBaseType BuiltInFunctions::matchTearingEvaluator(const EBTList& args)
760760
return std::visit(match_tearing_evaluator, args[0], args[1]);
761761
}
762762

763+
764+
ExprBaseType BuiltInFunctions::tearingTSEvaluator(const EBTList& args)
765+
{
766+
Util::ERROR_UNLESS(args.size() == 1
767+
, "topoSortEvaluator: wrong number of arguments\n");
768+
769+
LIB::Tearing tearing_impl = LIB::TEARING_FACT.createTearingAlgorithm();
770+
LIB::TopoSort ts_impl = LIB::TS_FACT.createTSAlgorithm();
771+
const auto ts_evaluator = Overload {
772+
[&tearing_impl, &ts_impl](LIB::DSBG a) {
773+
LIB::DSBG tearing_dsbg = tearing_impl.calculate(a).dsbg();
774+
return ExprBaseType(ts_impl.calculate(tearing_dsbg));
775+
},
776+
[](auto a) {
777+
Util::ERROR("topoSortEvaluator: wrong argument ", a, " for sort\n");
778+
return ExprBaseType();
779+
}
780+
};
781+
return std::visit(ts_evaluator, args[0]);
782+
}
783+
784+
ExprBaseType BuiltInFunctions::matchTearingTSEvaluator(const EBTList& args)
785+
{
786+
Util::ERROR_UNLESS(args.size() == 2
787+
, "sortEvaluator: wrong number of arguments");
788+
789+
LIB::Matching match_impl = LIB::MATCH_FACT.createMatchAlgorithm();
790+
LIB::Tearing tearing_impl = LIB::TEARING_FACT.createTearingAlgorithm();
791+
LIB::TopoSort ts_impl = LIB::TS_FACT.createTSAlgorithm();
792+
const auto sort_tearing_evaluator = Overload {
793+
[&match_impl, &tearing_impl, &ts_impl](LIB::BipartiteSBG a, LIB::NAT b) {
794+
LIB::MatchData match_result = match_impl.calculate(a.copy(b));
795+
LIB::DSBG scc_dsbg = MISC::buildSCCFromMatching(match_result);
796+
LIB::DSBG tearing_dsbg = tearing_impl.calculate(scc_dsbg).dsbg();
797+
return ExprBaseType(ts_impl.calculate(tearing_dsbg));
798+
},
799+
[&match_impl, &tearing_impl, &ts_impl](LIB::BipartiteSBG a, LIB::MD_NAT b) {
800+
LIB::MatchData match_result = match_impl.calculate(a.copy(b[0]));
801+
LIB::DSBG scc_dsbg = MISC::buildSCCFromMatching(match_result);
802+
LIB::DSBG tearing_dsbg = tearing_impl.calculate(scc_dsbg).dsbg();
803+
return ExprBaseType(ts_impl.calculate(tearing_dsbg));
804+
},
805+
[](auto a, auto b) {
806+
Util::ERROR("match_tearing_evaluator: wrong arguments ", a, ", ", b
807+
, " for matchTearing\n");
808+
return ExprBaseType();
809+
}
810+
};
811+
812+
return std::visit(sort_tearing_evaluator, args[0], args[1]);
813+
}
814+
763815
/*
764816
ExprBaseType BuiltInFunctions::matchSCCTSEvaluator(const EBTList& args)
765817
{

eval/visitors/func_evaluator.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ class BuiltInFunctions {
116116
static ExprBaseType matchSCCEvaluator(const EBTList& args);
117117
static ExprBaseType tearingEvaluator(const EBTList& args);
118118
static ExprBaseType matchTearingEvaluator(const EBTList& args);
119+
static ExprBaseType tearingTSEvaluator(const EBTList& args);
120+
static ExprBaseType matchTearingTSEvaluator(const EBTList& args);
119121
};
120122

121123
} // namespace Eval

0 commit comments

Comments
 (0)