Commit bead5e5c authored by ehebrard's avatar ehebrard
Browse files

merge and split

parent 62e6d43f
......@@ -156,16 +156,19 @@ int main(int argc, char *argv[]) {
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 << "undo\n";
//
// ReversibleObject::env->restore(ReversibleObject::env->level());
//
cout << "restore to level " << ReversibleObject::env->level() << "\n";
ReversibleObject::env->restore(ReversibleObject::env->level());
cout << "OK!\n";
// cout << S1.graph << endl;
// auto v2{S2.getVariable(START(1), END(0))};
......
......@@ -25,7 +25,7 @@ MODELS = $(wildcard $(MOD)/src/*.cpp)
BINS = $(patsubst $(MOD)/src/%, $(BIN)/%, $(MODELS:.cpp=))
PINCSRC = $(wildcard $(INC)/*.p)
PINCSRC = $(wildcard $(INC)/*.hpp)
PLIBSRC = $(wildcard $(SRC)/*.cpp)
PLIBAUX = $(PLIBSRC:.cpp=.o)
PLIBOBJ = $(patsubst $(SRC)/%, $(OBJ)/%, $(PLIBAUX))
......
......@@ -19,6 +19,9 @@ void BacktrackEnvironment::restore(const int lvl) {
assert(level() >= lvl);
size_t stamp = (lvl == 0 ? 0 : stamps[lvl - 1]);
cout << "stamp: " << stamp << " size: " << trail.size() << endl;
while (trail.size() > stamp) {
trail.back()->undo();
trail.pop_back();
......
......@@ -9,45 +9,42 @@
namespace schedcl {
template <typename T>
class BellmanFord {
public:
template <typename T> class BellmanFord {
public:
BellmanFord();
BellmanFord(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
template<class G>
void allShortestPaths(const int s, const G& neighbors, 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
template<class G>
void allShorterPaths(const int x, const int y, const T wxy, const G& neighbors, vector<T>& shortest_path, SparseSet& reached);
// 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>
void allShortestPaths(const int s, const G &neighbors,
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
template <class G>
void allShorterPaths(const int x, const int y, const T wxy,
const G &neighbors, vector<T> &shortest_path,
SparseSet &reached);
bool negative_cycle{false};
// vector<T> shortest_path;
// SparseSet reached;
private:
private:
SparseSet changed;
};
template <typename T> BellmanFord<T>::BellmanFord() {}
};
template <typename T>
BellmanFord<T>::BellmanFord() {
}
template <typename T>
BellmanFord<T>::BellmanFord(const int n) {
template <typename T> BellmanFord<T>::BellmanFord(const int n) {
initialise(n);
}
}
template <typename T>
void BellmanFord<T>::initialise(const int n) {
......@@ -69,14 +66,14 @@ void BellmanFord<T>::allShortestPaths(const int s, const G& neighbors, vector<T>
changed.add(s);
// reached.add(s);
while(not changed.empty()) {
while (not changed.empty()) {
auto u{changed.front()};
changed.pop_front();
cout << u << ":";
for(auto e : neighbors[u]) {
for (auto e : neighbors[u]) {
auto v{e.next(u)};
auto w{e.length()};
......@@ -113,11 +110,11 @@ void BellmanFord<T>::allShorterPaths(const int x, const int y, const T wxy, cons
changed.add(y);
reached.add(y);
while(not changed.empty()) {
while (not changed.empty()) {
auto u{changed.front()};
changed.pop_front();
for(auto e : neighbors[u]) {
for (auto e : neighbors[u]) {
auto v{e.next(u)};
auto w{e.length()};
......
......@@ -5,9 +5,9 @@
#include <map>
#include <vector>
#include <boost/dynamic_bitset.hpp>
#include "DistanceVariable.hpp"
// #include "Schedule.hpp"
#include "SparseSet.hpp"
......@@ -26,6 +26,8 @@ template <typename T> struct Edge {
int from() const;
int to() const;
int next(const int u) const;
ostream &display(ostream &os) const;
};
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 {
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
- It supports [adding new edges/not really]; reducing edges' weights; and
......@@ -77,6 +84,10 @@ public:
// merges vertices a and 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;
protected:
......@@ -86,13 +97,13 @@ protected:
vector<int> representant;
// tail[i] == last vertex mapped to i
vector<event> tail;
// next[i] == next vertex mapped to the same event as i (i, if there is
vector<int> tail;
// next[i] == next vertex mapped to the same int as i (i, if there is
// none)
vector<event> next;
// prev[i] == prev vertex mapped to the same event as i (i, if there is
vector<int> next;
// prev[i] == prev vertex mapped to the same int as i (i, if there is
// none)
vector<event> prev;
vector<int> prev;
// The removed vertex is the first one out of vertices. The first int in
// trail
......@@ -101,15 +112,26 @@ protected:
// the number of backward edges. They must be last in x's neighbor list
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
void addSuccessor(const event x, const int i);
// add
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
void removeVertex(const event x);
// void removeVertex(const int x);
// void unionEdges(const int x, const int y);
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
......@@ -134,6 +156,8 @@ void SparseDistanceGraph<T>::initialise(Schedule<T> &sched) {
if (n > 0) {
buffer.resize(n, 0);
predecessor.resize(n);
successor.resize(n);
......@@ -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 {
......@@ -173,7 +223,13 @@ template <typename T> size_t SparseDistanceGraph<T>::size() const {
// remove the i-th successor of x
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) {
// override with the last successor
......@@ -184,93 +240,495 @@ void SparseDistanceGraph<T>::removeSuccessor(const event x, const int i) {
}
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>
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};
event y{predecessor[x][i].from()};
#ifdef DEBUG_SG
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
// preserve the order
successor[y].push_back(successor[y][j]);
int k = successor[y][j].rank;
predecessor[successor[y][i].to()][k].rank =
static_cast<int>(successor[y].size()) - 1;
assert(representant[x] == x);
// put the successor where it first was
successor[y][j] = {predecessor[x][i].var, i};
} else {
successor[y].push_back({predecessor[x][i].var, i});
if (i < static_cast<int>(predecessor[x].size()) - 1) {
// override with the last predecessor
predecessor[x][i] = predecessor[x].back();
// update the oposite edge
int j = predecessor[x][i].rank;
successor[predecessor[x][i].from()][j].rank = 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();
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;
} else {
#ifdef DEBUG_SG
cout << "remove " << e << "\n";
#endif
removePredecessor(z, e.rank);
--numEdge;
}
}
// trail.push_back(count);
buffer.reset();
// cout << buffer.size() << endl;
buffer.set(x);
for (auto &e : predecessor[x]) {
int y = e.from();
int i = e.rank;
removeSuccessor(y, i);
auto z{start(e)};
assert(z >= 0);
assert(z < buffer.size());
buffer.set(z);
}
vertices.remove_back(x);
for (auto &e : predecessor[y]) {
auto z{start(e)};
if (not buffer[z]) {
#ifdef DEBUG_SG
cout << "move " << e << " to " << x << "'s predecessors\n";
#endif
auto pto{static_cast<int>(predecessor[x].size())};
predecessor[x].push_back(e);
successor[z][e.rank].rank = pto;
// successor[z].push_back({e.var, pfrom});
} else {
#ifdef DEBUG_SG
cout << "remove " << e << "\n";
#endif
removeSuccessor(z, e.rank);
--numEdge;
}
}
representant[y] = x;
vertices.remove_back(y);
#ifdef DEBUG_SG
cout << *this << endl;
verify("after merge");
#endif
cout << vertices << endl;
}
// add the opposite of the i-th predecessor of x
template <typename T>
void SparseDistanceGraph<T>::addSuccessor(const int z, Edge<T> &e,
const int i) {
#ifdef DEBUG_SG
cout << "add " << e << " to successor[" << z << "], at rank " << i << "\n";
#endif
auto f{successor[z][i]};
predecessor[end(f)][f.rank].rank = static_cast<int>(successor[z].size());
successor[z].push_back(f);
successor[z][i] = e;
//
// int j{predecessor[x][i].rank};
// int y{predecessor[x][i].from()};
//
// if (j < successor[y].size()) {
// // move and update the neighbor currently at rank j so that the undo
// // preserve the order
// successor[y].push_back(successor[y][j]);
// int k = successor[y][j].rank;
// predecessor[successor[y][i].to()][k].rank =
// static_cast<int>(successor[y].size()) - 1;
//
// // put the successor where it first was
// successor[y][j] = {predecessor[x][i].var, i};
// } else {
// successor[y].push_back({predecessor[x][i].var, i});
// }
//
#ifdef DEBUG_SG
cout << *this << endl;
#endif
}
template <typename T>
void SparseDistanceGraph<T>::addPredecessor(const int z, Edge<T> &e,
const int i) {
#ifdef DEBUG_SG
cout << "add " << e << " to predecessor[" << z << "], at rank " << i << "\n";
#endif
auto f{predecessor[z][i]};
cout << "swap with " << f << endl;
trail.push_back(0);
trail.push_back(0);
trail.push_back(x);
successor[start(f)][f.rank].rank = static_cast<int>(predecessor[z].size());
predecessor[z].push_back(f);
predecessor[z][i] = e;
#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 int x)
// {
//
// #ifdef DEBUG_SG
// cout << "remove " << x << endl;
// #endif
//
// ReversibleObject::save();
//
// for (auto &e : predecessor[x]) {
// int y = e.from();
// int i = e.rank;
// removeSuccessor(y, i);
// }
//
// for (auto &e : successor[x]) {
// int y = e.to();
// int i = e.rank;
// removePredecessor(y, i);
// }
//
// // vertices.remove_back(x);
// //
// // trail.push_back(x);
//
// // collect x's sucessors in buffer
// buffer.set(x);
// for (auto &e : successor[x]) {
// buffer.set(e.to());
// }
//
// int count{0};
//
//
// for (auto &e : successor[y]) {
// if(not buffer[e.to()])
// {
// // e.to() is not a successor of x, instead of removing
// // 1/ we add it
// successor[x].push_back(e);
//
// // 2/ we redirect the edge in e.to()'s predecessors
// auto pfrom{static_cast<int>(successor[x].size())};
// // predecessor[e.to()].push_back({e.var, pfrom});
// predecessor[e.to()][e.rank]
//
// ++count;
// }
// }
//
// trail.push_back(count);
//
// buffer.reset();
// // cout << buffer.size() << endl;
// buffer.set(x);
// for (auto &e : predecessor[x]) {
//
// // cout << x << " " << e << endl;
//
// assert(e.from() >= 0);
// assert(e.from() < buffer.size());
// buffer.set(e.from());
// }
//
// for (auto &e : predecessor[y]) {
// if(not buffer[e.from()])
// {
// auto pfrom{static_cast<int>(predecessor[x].size())};
//
// predecessor[x].push_back(e);
// predecessor[e.from()].push_back({e.var, pfrom});
// ++count;
// }
// }
//
// numEdge -= (successor[y].size() - count);
//
//
// trail.push_back(count);
//
//
// #ifdef DEBUG_SG
// cout << *this << endl;
// #endif
//
// }
// restore to the last saved state
template <typename T> void SparseDistanceGraph<T>::undo() {
auto x{trail.back()};
trail.pop_back();
#ifdef DEBUG_SG
cout << "undo\n";
#endif
// auto nforward{trail.back()};
// trail.pop_back();
// auto nbackward{trail.back()};
// trail.pop_back();
auto y{trail.back()};
trail.pop_back();
assert(not vertices.has(x));
assert(*vertices.end() == x);
vertices.add(x);
for (auto &e : predecessor[x]) {
int y = e.from();
int i = e.rank;
addSuccessor(y, i);
}
split(y);
split(x);