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[]) {
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 << S1.graph << endl;
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))};
// v2->set(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))
......@@ -61,7 +61,7 @@ $(MOD)/obj/%.o: $(MOD)/src/%.cpp
$(CCC) $(CFLAGS) -c $< -o $@
# Examples, one at a time
%: $(MOD)/obj/%.o $(PLIBOBJ)
%: $(MOD)/obj/%.o $(PLIBOBJ)
@echo 'link '$<
$(CCC) $(CFLAGS) $(PLIBOBJ) $(COPTIMIZE) $< -lm -o $(BIN)/$@
......
......@@ -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,133 +9,130 @@
namespace schedcl {
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);
bool negative_cycle{false};
// vector<T> shortest_path;
// SparseSet reached;
private:
SparseSet changed;
};
template <typename T>
BellmanFord<T>::BellmanFord() {
}
template <typename T>
BellmanFord<T>::BellmanFord(const int n) {
initialise(n);
}
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);
bool negative_cycle{false};
// vector<T> shortest_path;
// SparseSet reached;
private:
SparseSet changed;
};
template <typename T> BellmanFord<T>::BellmanFord() {}
template <typename T> BellmanFord<T>::BellmanFord(const int n) {
initialise(n);
}
template <typename T>
void BellmanFord<T>::initialise(const int n) {
// shortest_path.clear();
// shortest_path.resize(n, INFTY);
changed.reserve(n);
changed.clear();
// reached.reserve(n);
// reached.clear();
negative_cycle = false;
// shortest_path.clear();
// shortest_path.resize(n, INFTY);
changed.reserve(n);
changed.clear();
// reached.reserve(n);
// reached.clear();
negative_cycle = false;
}
template <typename T>
template<class G>
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]) {
auto v{e.next(u)};
auto w{e.length()};
changed.add(s);
// reached.add(s);
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) {
negative_cycle = true;
return;
}
cout << u << ":";
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))
changed.add(v);
// if(not reached.has(v))
// reached.add(v);
}
}
if (w != INFTY and shortest_path[u] + w < shortest_path[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<class G>
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;
changed.add(y);
reached.add(y);
while(not changed.empty()) {
auto u{changed.front()};
changed.pop_front();
for(auto e : neighbors[u]) {
auto v{e.next(u)};
auto w{e.length()};
if (w != INFTY and shortest_path[u] + w < shortest_path[v]) {
if (v == x and wxy + w < 0) {
negative_cycle = true;
return;
}
shortest_path[v] = shortest_path[u] + w;
if (not changed.has(v))
changed.add(v);
if (not reached.has(v))
reached.add(v);
}
}
}
shortest_path[y] = wxy;
changed.add(y);
reached.add(y);
while (not changed.empty()) {
auto u{changed.front()};
changed.pop_front();
for (auto e : neighbors[u]) {
auto v{e.next(u)};
auto w{e.length()};
if (w != INFTY and shortest_path[u] + w < shortest_path[v]) {
if (v == x and wxy + w < 0) {
negative_cycle = true;
return;
}
shortest_path[v] = shortest_path[u] + w;
if (not changed.has(v))
changed.add(v);
if (not reached.has(v))
reached.add(v);
}
}
}
}
......
......@@ -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) {
int j{predecessor[x][i].rank};
event 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});
void SparseDistanceGraph<T>::removePredecessor(const int x, const int i) {
#ifdef DEBUG_SG
cout << "remove " << i << "-th predecessor of " << x << endl;
#endif
assert(representant[x] == x);
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()) {