Commit bead5e5c authored by ehebrard's avatar ehebrard
Browse files

merge and split

parent 62e6d43f
...@@ -156,17 +156,20 @@ int main(int argc, char *argv[]) { ...@@ -156,17 +156,20 @@ int main(int argc, char *argv[]) {
cout << S1.graph << endl; cout << S1.graph << endl;
cout << "merge\n"; // cout << "merge\n";
S1.graph.merge(START(0), END(0)); for (auto i{0}; i < S1.numTask(); ++i)
S1.graph.merge(START(i), END(i));
cout << S1.graph << endl; cout << S1.graph << endl;
// cout << "undo\n"; cout << "restore to level " << ReversibleObject::env->level() << "\n";
//
// ReversibleObject::env->restore(ReversibleObject::env->level()); ReversibleObject::env->restore(ReversibleObject::env->level());
//
// cout << S1.graph << endl; cout << "OK!\n";
// cout << S1.graph << endl;
// auto v2{S2.getVariable(START(1), END(0))}; // auto v2{S2.getVariable(START(1), END(0))};
// v2->set(0); // v2->set(0);
......
...@@ -25,7 +25,7 @@ MODELS = $(wildcard $(MOD)/src/*.cpp) ...@@ -25,7 +25,7 @@ MODELS = $(wildcard $(MOD)/src/*.cpp)
BINS = $(patsubst $(MOD)/src/%, $(BIN)/%, $(MODELS:.cpp=)) BINS = $(patsubst $(MOD)/src/%, $(BIN)/%, $(MODELS:.cpp=))
PINCSRC = $(wildcard $(INC)/*.p) PINCSRC = $(wildcard $(INC)/*.hpp)
PLIBSRC = $(wildcard $(SRC)/*.cpp) PLIBSRC = $(wildcard $(SRC)/*.cpp)
PLIBAUX = $(PLIBSRC:.cpp=.o) PLIBAUX = $(PLIBSRC:.cpp=.o)
PLIBOBJ = $(patsubst $(SRC)/%, $(OBJ)/%, $(PLIBAUX)) PLIBOBJ = $(patsubst $(SRC)/%, $(OBJ)/%, $(PLIBAUX))
...@@ -61,7 +61,7 @@ $(MOD)/obj/%.o: $(MOD)/src/%.cpp ...@@ -61,7 +61,7 @@ $(MOD)/obj/%.o: $(MOD)/src/%.cpp
$(CCC) $(CFLAGS) -c $< -o $@ $(CCC) $(CFLAGS) -c $< -o $@
# Examples, one at a time # Examples, one at a time
%: $(MOD)/obj/%.o $(PLIBOBJ) %: $(MOD)/obj/%.o $(PLIBOBJ)
@echo 'link '$< @echo 'link '$<
$(CCC) $(CFLAGS) $(PLIBOBJ) $(COPTIMIZE) $< -lm -o $(BIN)/$@ $(CCC) $(CFLAGS) $(PLIBOBJ) $(COPTIMIZE) $< -lm -o $(BIN)/$@
......
...@@ -19,6 +19,9 @@ void BacktrackEnvironment::restore(const int lvl) { ...@@ -19,6 +19,9 @@ void BacktrackEnvironment::restore(const int lvl) {
assert(level() >= lvl); assert(level() >= lvl);
size_t stamp = (lvl == 0 ? 0 : stamps[lvl - 1]); size_t stamp = (lvl == 0 ? 0 : stamps[lvl - 1]);
cout << "stamp: " << stamp << " size: " << trail.size() << endl;
while (trail.size() > stamp) { while (trail.size() > stamp) {
trail.back()->undo(); trail.back()->undo();
trail.pop_back(); trail.pop_back();
......
...@@ -9,133 +9,130 @@ ...@@ -9,133 +9,130 @@
namespace schedcl { namespace schedcl {
template <typename T> template <typename T> class BellmanFord {
class BellmanFord {
public:
public: BellmanFord();
BellmanFord(const int n);
BellmanFord();
BellmanFord(const int n); void initialise(const int n);
void initialise(const int n); // updates all shortest paths from s and put them in 'shortest_path'. Sets the
// flag 'negative_cycle' if it finds a negative cycle including s
// updates all shortest paths from s and put them in 'shortest_path'. Sets the flag 'negative_cycle' if it finds a negative cycle including s template <class G>
template<class G> void allShortestPaths(const int s, const G &neighbors,
void allShortestPaths(const int s, const G& neighbors, vector<T>& shortest_path); vector<T> &shortest_path);
// updates all shortest paths from x (and through y) and put them in 'shortest_path'. Sets the flag 'negative_cycle' if it finds a negative cycle including x-y // updates all shortest paths from x (and through y) and put them in
template<class G> // 'shortest_path'. Sets the flag 'negative_cycle' if it finds a negative
void allShorterPaths(const int x, const int y, const T wxy, const G& neighbors, vector<T>& shortest_path, SparseSet& reached); // cycle including x-y
template <class G>
void allShorterPaths(const int x, const int y, const T wxy,
bool negative_cycle{false}; const G &neighbors, vector<T> &shortest_path,
SparseSet &reached);
// vector<T> shortest_path;
// SparseSet reached; bool negative_cycle{false};
private: // vector<T> shortest_path;
// SparseSet reached;
SparseSet changed;
private:
SparseSet changed;
}; };
template <typename T> template <typename T> BellmanFord<T>::BellmanFord() {}
BellmanFord<T>::BellmanFord() {
} template <typename T> BellmanFord<T>::BellmanFord(const int n) {
initialise(n);
template <typename T> }
BellmanFord<T>::BellmanFord(const int n) {
initialise(n);
}
template <typename T> template <typename T>
void BellmanFord<T>::initialise(const int n) { void BellmanFord<T>::initialise(const int n) {
// shortest_path.clear(); // shortest_path.clear();
// shortest_path.resize(n, INFTY); // shortest_path.resize(n, INFTY);
changed.reserve(n); changed.reserve(n);
changed.clear(); changed.clear();
// reached.reserve(n); // reached.reserve(n);
// reached.clear(); // reached.clear();
negative_cycle = false; negative_cycle = false;
} }
template <typename T> template <typename T>
template<class G> template<class G>
void BellmanFord<T>::allShortestPaths(const int s, const G& neighbors, vector<T>& shortest_path) { void BellmanFord<T>::allShortestPaths(const int s, const G& neighbors, vector<T>& shortest_path) {
shortest_path[s] = 0;
changed.add(s);
// reached.add(s);
while(not changed.empty()) {
auto u{changed.front()};
changed.pop_front();
cout << u << ":"; shortest_path[s] = 0;
for(auto e : neighbors[u]) { changed.add(s);
auto v{e.next(u)}; // reached.add(s);
auto w{e.length()};
cout << " (" << v << "|" << w << ")"; while (not changed.empty()) {
if (w != INFTY and shortest_path[u] + w < shortest_path[v]) { auto u{changed.front()};
changed.pop_front();
if (v == s) { cout << u << ":";
negative_cycle = true;
return;
}
shortest_path[v] = shortest_path[u] + w; for (auto e : neighbors[u]) {
auto v{e.next(u)};
auto w{e.length()};
cout << " (" << shortest_path[v] << ")"; cout << " (" << v << "|" << w << ")";
if (not changed.has(v)) if (w != INFTY and shortest_path[u] + w < shortest_path[v]) {
changed.add(v);
// if(not reached.has(v))
// reached.add(v);
}
}
cout << endl; if (v == s) {
negative_cycle = true;
return;
} }
shortest_path[v] = shortest_path[u] + w;
cout << " (" << shortest_path[v] << ")";
if (not changed.has(v))
changed.add(v);
// if(not reached.has(v))
// reached.add(v);
}
}
cout << endl;
}
} }
template <typename T> template <typename T>
template<class G> template<class G>
void BellmanFord<T>::allShorterPaths(const int x, const int y, const T wxy, const G& neighbors, vector<T>& shortest_path, SparseSet& reached) { void BellmanFord<T>::allShorterPaths(const int x, const int y, const T wxy, const G& neighbors, vector<T>& shortest_path, SparseSet& reached) {
shortest_path[y] = wxy; shortest_path[y] = wxy;
changed.add(y); changed.add(y);
reached.add(y); reached.add(y);
while(not changed.empty()) { while (not changed.empty()) {
auto u{changed.front()}; auto u{changed.front()};
changed.pop_front(); changed.pop_front();
for(auto e : neighbors[u]) { for (auto e : neighbors[u]) {
auto v{e.next(u)}; auto v{e.next(u)};
auto w{e.length()}; auto w{e.length()};
if (w != INFTY and shortest_path[u] + w < shortest_path[v]) { if (w != INFTY and shortest_path[u] + w < shortest_path[v]) {
if (v == x and wxy + w < 0) { if (v == x and wxy + w < 0) {
negative_cycle = true; negative_cycle = true;
return; return;
} }
shortest_path[v] = shortest_path[u] + w; shortest_path[v] = shortest_path[u] + w;
if (not changed.has(v)) if (not changed.has(v))
changed.add(v); changed.add(v);
if (not reached.has(v)) if (not reached.has(v))
reached.add(v); reached.add(v);
} }
} }
} }
} }
......
...@@ -5,9 +5,9 @@ ...@@ -5,9 +5,9 @@
#include <map> #include <map>
#include <vector> #include <vector>
#include <boost/dynamic_bitset.hpp>
#include "DistanceVariable.hpp" #include "DistanceVariable.hpp"
// #include "Schedule.hpp"
#include "SparseSet.hpp" #include "SparseSet.hpp"
...@@ -26,6 +26,8 @@ template <typename T> struct Edge { ...@@ -26,6 +26,8 @@ template <typename T> struct Edge {
int from() const; int from() const;
int to() const; int to() const;
int next(const int u) const; int next(const int u) const;
ostream &display(ostream &os) const;
}; };
template <typename T> T Edge<T>::length() const { return var->get(); } template <typename T> T Edge<T>::length() const { return var->get(); }
...@@ -38,6 +40,11 @@ template <typename T> int Edge<T>::next(const int u) const { ...@@ -38,6 +40,11 @@ template <typename T> int Edge<T>::next(const int u) const {
return (var->to == u ? var->from : var->to); return (var->to == u ? var->from : var->to);
} }
template <typename T> ostream &Edge<T>::display(ostream &os) const {
os << "(" << from() << "," << to() << ")@" << rank;
return os;
}
/* /*
Implementation of a graph Implementation of a graph
- It supports [adding new edges/not really]; reducing edges' weights; and - It supports [adding new edges/not really]; reducing edges' weights; and
...@@ -77,6 +84,10 @@ public: ...@@ -77,6 +84,10 @@ public:
// merges vertices a and b // merges vertices a and b
void merge(const int a, const int b); void merge(const int a, const int b);
int get(const int x);
int start(const Edge<T> &e);
int end(const Edge<T> &e);
ostream &display(ostream &os) const; ostream &display(ostream &os) const;
protected: protected:
...@@ -86,13 +97,13 @@ protected: ...@@ -86,13 +97,13 @@ protected:
vector<int> representant; vector<int> representant;
// tail[i] == last vertex mapped to i // tail[i] == last vertex mapped to i
vector<event> tail; vector<int> tail;
// next[i] == next vertex mapped to the same event as i (i, if there is // next[i] == next vertex mapped to the same int as i (i, if there is
// none) // none)
vector<event> next; vector<int> next;
// prev[i] == prev vertex mapped to the same event as i (i, if there is // prev[i] == prev vertex mapped to the same int as i (i, if there is
// none) // none)
vector<event> prev; vector<int> prev;
// The removed vertex is the first one out of vertices. The first int in // The removed vertex is the first one out of vertices. The first int in
// trail // trail
...@@ -101,15 +112,26 @@ protected: ...@@ -101,15 +112,26 @@ protected:
// the number of backward edges. They must be last in x's neighbor list // the number of backward edges. They must be last in x's neighbor list
vector<int> trail; vector<int> trail;
void removeSuccessor(const event x, const int i); void removeSuccessor(const int x, const int i);
void removePredecessor(const int x, const int i);
// add the opposite of the i-th predecessor of x // add
void addSuccessor(const event x, const int i); void addSuccessor(const int z, Edge<T> &e, const int i);
void addPredecessor(const int z, Edge<T> &e, const int i);
// add the opposite of the i-th predecessor of x // add the opposite of the i-th predecessor of x
void removeVertex(const event x); // void removeVertex(const int x);
// void unionEdges(const int x, const int y);
void split(const int a); void split(const int a);
private:
boost::dynamic_bitset<> buffer;
#ifdef DEBUG_SG
void verify(const char *msg);
#endif
}; };
// declare a new time point in the graph // declare a new time point in the graph
...@@ -134,6 +156,8 @@ void SparseDistanceGraph<T>::initialise(Schedule<T> &sched) { ...@@ -134,6 +156,8 @@ void SparseDistanceGraph<T>::initialise(Schedule<T> &sched) {
if (n > 0) { if (n > 0) {
buffer.resize(n, 0);
predecessor.resize(n); predecessor.resize(n);
successor.resize(n); successor.resize(n);
...@@ -157,6 +181,32 @@ void SparseDistanceGraph<T>::initialise(Schedule<T> &sched) { ...@@ -157,6 +181,32 @@ void SparseDistanceGraph<T>::initialise(Schedule<T> &sched) {
} }
} }
#ifdef DEBUG_SG
verify("init");
#endif
}
template <typename T> int SparseDistanceGraph<T>::get(const int y) {
auto x{y};
while (representant[x] != x)
x = representant[x];
return x;
}
template <typename T> int SparseDistanceGraph<T>::start(const Edge<T> &e) {
return get(e.from());
// auto x{e.from()};
// while(representant[x] != x)
// x = representant[x];
// return x;
}
template <typename T> int SparseDistanceGraph<T>::end(const Edge<T> &e) {
return get(e.to());
// auto x{e.to()};
// while(representant[x] != x)
// x = representant[x];
// return x;
} }
template <typename T> size_t SparseDistanceGraph<T>::edgeCount() const { template <typename T> size_t SparseDistanceGraph<T>::edgeCount() const {
...@@ -173,7 +223,13 @@ template <typename T> size_t SparseDistanceGraph<T>::size() const { ...@@ -173,7 +223,13 @@ template <typename T> size_t SparseDistanceGraph<T>::size() const {
// remove the i-th successor of x // remove the i-th successor of x
template <typename T> template <typename T>
void SparseDistanceGraph<T>::removeSuccessor(const event x, const int i) { void SparseDistanceGraph<T>::removeSuccessor(const int x, const int i) {
#ifdef DEBUG_SG
cout << "remove " << i << "-th successor of " << x << endl;
#endif
assert(representant[x] == x);
if (i < static_cast<int>(successor[x].size()) - 1) { if (i < static_cast<int>(successor[x].size()) - 1) {
// override with the last successor // override with the last successor
...@@ -184,93 +240,495 @@ void SparseDistanceGraph<T>::removeSuccessor(const event x, const int i) { ...@@ -184,93 +240,495 @@ void SparseDistanceGraph<T>::removeSuccessor(const event x, const int i) {
} }
successor[x].pop_back(); successor[x].pop_back();
#ifdef DEBUG_SG
cout << *this << endl;
#endif
} }
// add the opposite of the i-th predecessor of x // remove the i-th successor of x
template <typename T> template <typename T>
void SparseDistanceGraph<T>::addSuccessor(const event x, const int i) { void SparseDistanceGraph<T>::removePredecessor(const int x, const int i) {
int j{predecessor[x][i].rank}; #ifdef DEBUG_SG
event y{predecessor[x][i].from()}; cout << "remove " << i << "-th predecessor of " << x << endl;
#endif
if (j < successor[y].size()) {
// move and update the neighbor currently at rank j so that the undo assert(representant[x] == x);
// preserve the order
successor[y].push_back(successor[y][j]); if (i < static_cast<int>(predecessor[x].size()) - 1) {
int k = successor[y][j].rank; // override with the last predecessor
predecessor[successor[y][i].to()][k].rank = predecessor[x][i] = predecessor[x].back();
static_cast<int>(successor[y].size()) - 1; // update the oposite edge
int j = predecessor[x][i].rank;
// put the successor where it first was successor[predecessor[x][i].from()][j].rank = i;
successor[y][j] = {predecessor[x][i].var, i};
} else {
successor[y].push_back({predecessor[x][i].var, i});
} }
predecessor[x].pop_back();
#ifdef DEBUG_SG
cout << *this << endl;
#endif
} }
// add the opposite of the i-th predecessor of x //
template <typename T> void SparseDistanceGraph<T>::removeVertex(const event x) { template <typename T>
void SparseDistanceGraph<T>::merge(const int x, const int y) {
#ifdef DEBUG_SG
cout << "merge " << y << " to " << x << "\n";
#endif
ReversibleObject::save(); ReversibleObject::save();
trail.push_back(y);
buffer.set(x);
for (auto &e : successor[x]) {
// cout << x << " " << e << endl;
auto z{end(e)};
assert(z >= 0);
assert(z < buffer.size());
buffer.set(z);
}
// int count{0};
for (auto &e : successor[y]) {
auto z{end(e)};
if (not buffer[z]) {
#ifdef DEBUG_SG
cout << "move " << e << " to " << x << "'s successors\n";
#endif
auto pfrom{static_cast<int>(successor[x].size())};
successor[x].push_back(e);
predecessor[z][e.rank].rank = pfrom;
// predecessor[z].push_back({e.var, pfrom});
// ++count;