Commit 7e025138 authored by ehebrard's avatar ehebrard
Browse files

menage

parent d8cd18ad
......@@ -29,3 +29,16 @@ unsigned long schedcl::random(void) { // period 2^96-1
return z;
}
// 0 is for the origin event, 1 is for the completion event
task schedcl::TASK( event x ) {
return x/2-1;
}
event schedcl::START( task x ) {
return 2*x+2;
}
event schedcl::END( task x ) {
return 2*x+3;
}
#include "Graph.hpp"
using namespace schedcl;
// declare a new time point in the graph
Graph::Graph() : ReversibleObject() {}
void Graph::addArc(const int u, const int v) {
if (edges.newArc(u, v)) {
ReversibleObject::save();
trail.push_back(u);
trail.push_back(v);
add(Arc(u, v));
#ifdef DEBUG_SG
// cout << *this << endl;
verify("add arc");
#endif
}
}
void Graph::add(Arc a) {
for (auto l{SUCCESSOR}; l <= PREDECESSOR; ++l) {
neighbor_rank[l][a[l]].push_back(
static_cast<int>(neighbor[1 - l][a[1 - l]].size()));
}
for (auto l{SUCCESSOR}; l <= PREDECESSOR; ++l) {
neighbor[l][a[l]].push_back(a[1 - l]);
// ++numArc;
}
++numArc;
}
bool Graph::has(const int u, const int v) const { return edges.has(u, v); }
void Graph::removeVertex(const int u) {
ReversibleObject::save();
trail.push_back(u);
for (auto l{SUCCESSOR}; l <= PREDECESSOR; ++l) {
for (auto i{neighbor[l][u].size()}; i-- > 0;) {
removeIthNeighbor(u, l, i);
--numArc;
}
}
vertices.remove_back(u);
// cout << "removed " << u << endl << *this << endl;
#ifdef DEBUG_SG
// cout << *this << endl;
verify("remove vertex");
#endif
}
void Graph::removeIthNeighbor(const int u, const int l, const int ith) {
auto v{neighbor[l][u][ith]};
auto kth{neighbor_rank[l][u][ith]};
// u appears at rank r in v's neighbors
assert(ith == neighbor_rank[1 - l][v][kth]);
assert(u == neighbor[1 - l][v][kth]);
auto w{neighbor[1 - l][v].back()};
auto jth{neighbor_rank[1 - l][v].back()};
// w is the last neighbor of v
assert(neighbor_rank[l][w][jth] == neighbor[1 - l][v].size() - 1);
neighbor[1 - l][v][kth] = w;
neighbor_rank[1 - l][v][kth] = jth;
neighbor_rank[l][w][jth] = kth;
neighbor[1 - l][v].pop_back();
neighbor_rank[1 - l][v].pop_back();
}
void Graph::addIthNeighbor(const int u, const int l, const int ith) {
// int k;
auto v{neighbor[l][u][ith]};
// k = 0;
// for (auto z : neighbor[SUCCESSOR][v]) {
// cout << " " << z << "@" << neighbor_rank[SUCCESSOR][v][k++];
// }
// cout << " /";
// k = 0;
// for (auto z : neighbor[PREDECESSOR][v]) {
// cout << " " << z << "@" << neighbor_rank[PREDECESSOR][v][k++];
// }
// cout << endl;
// k = 0;
// for (auto z : neighbor[SUCCESSOR][5]) {
// cout << " " << z << "@" << neighbor_rank[SUCCESSOR][5][k++];
// }
// cout << " /";
// k = 0;
// for (auto z : neighbor[PREDECESSOR][5]) {
// cout << " " << z << "@" << neighbor_rank[PREDECESSOR][5][k++];
// }
// cout << endl;
auto kth{neighbor_rank[l][u][ith]};
// cout << " - in " << v << "'s list @" << kth << endl;
if (kth < neighbor[1 - l][v].size()) {
auto w{neighbor[1 - l][v][kth]};
auto jth{neighbor_rank[1 - l][v][kth]};
// cout << "add " << u << " as " << kth << "-th " << (l ? "suc" : "prede")
// << "cessor of " << v << " in place of " << w << endl;
assert(neighbor_rank[l][w][jth] == kth);
assert(neighbor[l][w][jth] == v);
neighbor_rank[l][w][jth] = static_cast<int>(neighbor[1 - l][v].size());
neighbor[1 - l][v].push_back(w);
neighbor_rank[1 - l][v].push_back(jth);
neighbor[1 - l][v][kth] = u;
neighbor_rank[1 - l][v][kth] = ith;
} else {
assert(kth == neighbor[1 - l][v].size());
// cout << "add " << u << " as last " << (l ? "suc" : "prede")
// << "cessor of " << v << endl;
neighbor[1 - l][v].push_back(u);
neighbor_rank[1 - l][v].push_back(ith);
}
// cout << " (in place of " << w << ")\n";
//
// k = 0;
// for (auto z : neighbor[SUCCESSOR][v]) {
// cout << " " << z << "@" << neighbor_rank[SUCCESSOR][v][k++];
// }
// cout << " /";
// k = 0;
// for (auto z : neighbor[PREDECESSOR][v]) {
// cout << " " << z << "@" << neighbor_rank[PREDECESSOR][v][k++];
// }
// cout << endl;
// k = 0;
// for (auto z : neighbor[SUCCESSOR][5]) {
// cout << " " << z << "@" << neighbor_rank[SUCCESSOR][5][k++];
// }
// cout << " /";
// k = 0;
// for (auto z : neighbor[PREDECESSOR][5]) {
// cout << " " << z << "@" << neighbor_rank[PREDECESSOR][5][k++];
// }
// cout << endl;
}
void Graph::recall(const int u) {
for (auto l{PREDECESSOR}; l >= SUCCESSOR; --l) {
// cout << (l ? "prede" : "suc") << "cessors\n";
int n{static_cast<int>(neighbor[l][u].size())};
for (int ith{0}; ith < n; ++ith) {
// cout << "add " << u << " as " << neighbor_rank[l][u][ith]
// << "-th " << (l ? "suc" : "prede") << "cessors of "
// << neighbor[l][u][ith] << endl;
addIthNeighbor(u, l, ith);
++numArc;
}
}
vertices.add(u);
// exit(1);
// // for()
//
//
// auto f{neighbor[l][z][i]};
// neighbor[1 - l][f.neighbor()][f.rank].rank =
// static_cast<int>(neighbor[l][z].size());
// neighbor[l][z].push_back(f);
// neighbor[l][z][i] = e;
#ifdef DEBUG_SG
verify("recall");
#endif
}
void Graph::undo(Arc a) {
for (auto l{SUCCESSOR}; l <= PREDECESSOR; ++l) {
assert(neighbor[l][a[l]].back() == a[1 - l]);
neighbor[l][a[l]].pop_back();
neighbor_rank[l][a[l]].pop_back();
}
edges.remove(a);
--numArc;
}
void Graph::resize(const int n) {
if (n > 0) {
buffer.resize(n, 0);
neighbor[PREDECESSOR].resize(n);
neighbor[SUCCESSOR].resize(n);
neighbor_rank[PREDECESSOR].resize(n);
neighbor_rank[SUCCESSOR].resize(n);
vertices.reserve(n);
vertices.fill();
edges.resize(this->vertices, this->neighbor[SUCCESSOR]);
}
#ifdef DEBUG_SG
// cout << *this << endl;
verify("init");
#endif
}
size_t Graph::arcCount() const { return numArc; }
size_t Graph::vertexCount() const { return vertices.count(); }
size_t Graph::size() const { return vertices.capacity(); }
//
void Graph::merge(const int u, const int v) {
// cout << *this << "\nMERGE " << v << " TO " << u << endl;
removeVertex(v);
// cout << "1/ REMOVE " << v << ":\n" << *this << endl;
// for (auto l{SUCCESSOR}; l <= PREDECESSOR; ++l) {
//
// // cout << (l+2) << "/ COMPLETE " <<
//
//
//
// buffer.set(u);
// for (auto w : neighbor[l][u]) {
// assert(w >= 0);
// assert(w < buffer.size());
// buffer.set(w);
// }
//
// for (auto w : neighbor[l][v]) {
// if (not buffer[w]) {
// addArc(u, w);
// }
// }
// }
// cout << "2/ FILL " << u << "'s successors:\n";
buffer.reset();
buffer.set(u);
for (auto w : neighbor[SUCCESSOR][u]) {
assert(w >= 0);
assert(w < buffer.size());
buffer.set(w);
}
for (auto w : neighbor[SUCCESSOR][v]) {
if (not buffer[w]) {
// cout << " -" << w << endl;
addArc(u, w);
}
}
// cout << *this << "\n2/ FILL " << u << "'s predecessors:\n";
buffer.reset();
buffer.set(u);
for (auto w : neighbor[PREDECESSOR][u]) {
assert(w >= 0);
assert(w < buffer.size());
buffer.set(w);
}
for (auto w : neighbor[PREDECESSOR][v]) {
if (not buffer[w]) {
// cout << " -" << w << endl;
addArc(w, u);
}
}
// cout << *this << endl;
}
// restore to the last saved state
void Graph::undo() {
auto v{trail.back()};
trail.pop_back();
if (vertices.has(v)) {
// undo an addArc(u, v)
auto u{trail.back()};
trail.pop_back();
undo(Arc(u, v));
} else {
// cout << "undo rm " << v << endl << *this << endl;
// undo a removeVertex
recall(v);
}
#ifdef DEBUG_SG
// cout << *this << endl;
verify("undo");
#endif
}
ostream &Graph::display(ostream &os) const {
for (auto i{0}; i < size(); ++i) {
os << setw(3) << i << ":";
// if (not vertices.has(i)) {
// os << endl;
// } else {
int k{0};
for (auto v : neighbor[SUCCESSOR][i]) {
os << " " << v
#ifdef DEBUG_SG
<< "@" << neighbor_rank[SUCCESSOR][i][k++]
#endif
;
}
os << " /";
k = 0;
for (auto v : neighbor[PREDECESSOR][i]) {
os << " " << v
#ifdef DEBUG_SG
<< "@" << neighbor_rank[PREDECESSOR][i][k++]
#endif
;
}
os << endl;
// }
}
return os;
}
#ifdef DEBUG_SG
void Graph::verify(const char *msg) {
// cout << msg << endl ;
for (auto l{SUCCESSOR}; l <= PREDECESSOR; ++l) {
int count = 0;
for (auto x : vertices) {
int rank = 0;
for (auto ith{0}; ith < neighbor[l][x].size(); ++ith) {
auto y{neighbor[l][x][ith]};
if (y == x) {
cout << msg << ": error, there is a loop on " << x << endl;
exit(1);
}
auto jth{neighbor_rank[l][x][ith]};
if (neighbor_rank[1 - l][y][jth] != ith or
neighbor[1 - l][y][jth] != x) {
cout << msg << ": error on " << x << " " << y << "\n"
<< *this << endl;
exit(1);
}
// else {
// cout << "ok " << x << " " << y << "\n";
// }
++rank;
}
count += rank;
}
assert(count == arcCount());
}
}
#endif
//
// template<typename vertices, typename neighborhood>
// void EdgeSet::resize(const vertices& V, const edges& E) {
// auto N{V.size()};
// edges.resize(N);
// edges.reset();
// for(auto u : V) {
// for(auto v : E[u]) {
// edges.set(u * N + v);
// }
// }
// }
// void EdgeSet::clear(const size_t n) {
// edges.resize(n, 0);
// }
bool EdgeSet::newArc(const int x, const int y) {
if (x != y) {
auto e{x * size_ + y};
if (not edgeset[e]) {
edgeset.set(e);
return true;
}
}
return false;
}
bool EdgeSet::has(const int x, const int y) const {
return edgeset[x * size_ + y];
}
void EdgeSet::remove(const Arc a) {
assert(edgeset[a[0] * size_ + a[1]]);
edgeset.reset(a[0] * size_ + a[1]);
}
// void EdgeSet::remove(const int x, const int y) {
// if (x != y) {
// auto e{x * size() + y};
// if (not edges[e]) {
// edges.reset(e);
// }
// }
// }
std::ostream &schedcl::operator<<(std::ostream &os, const schedcl::Graph &x) {
return x.display(os);
}
\ No newline at end of file
#include "Schedule.hpp"
// 0 is for the origin event, 1 is for the completion event
task schedcl::TASK( event x ) {
return x/2-1;
}
event schedcl::START( task x ) {
return 2*x+2;
}
event schedcl::END( task x ) {
return 2*x+3;
}
//
//
// // 0 is for the origin event, 1 is for the completion event
// task schedcl::TASK( event x ) {
// return x/2-1;
// }
//
// event schedcl::START( task x ) {
// return 2*x+2;
// }
//
// event schedcl::END( task x ) {
// return 2*x+3;
// }
bool schedcl::is_cycle(const long hint) { return static_cast<bool>(hint & 1); }
......
......@@ -7,7 +7,7 @@
#include "Global.hpp"
#include "SparseSet.hpp"
// #define DEBUG_BELLMANFORD
#define DEBUG_BELLMANFORD
using namespace std;
......@@ -23,14 +23,26 @@ public:
// 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 <typename G>
void allShortestPaths(const int s, const G &neighbors,
vector<T> &shortest_path);
template <typename G, typename D>
void allShortestPaths(const int s, const G &neighbors, const D &distance,
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 <typename G, typename D>
void allShorterPaths(const int x, const int y, const T wxy,
const G &neighbors, const D &distance,
vector<T> &shortest_path, SparseSet<> &reached);
// 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
template <typename G
#ifdef DEBUG_BELLMANFORD
,
class P
......@@ -70,10 +82,11 @@ void BellmanFord<T>::initialise(const int n) {
}
template <typename T>
template<class G>
void BellmanFord<T>::allShortestPaths(const int s, const G& neighbors, vector<T>& shortest_path
// , vector<int>& predecessor
) {
template <typename G>
void BellmanFord<T>::allShortestPaths(const int s, const G &neighbors,
vector<T> &shortest_path
// , vector<int>& predecessor
) {
shortest_path[s] = 0;
......@@ -106,6 +119,41 @@ void BellmanFord<T>::allShortestPaths(const int s, const G& neighbors, vector<T>
}
}
template <typename T>
template <typename G, typename D>
void BellmanFord<T>::allShortestPaths(const int s, const G &neighbors,
const D &distance,
vector<T> &shortest_path) {
shortest_path[s] = 0;
changed.add(s);
while (not changed.empty()) {
auto u{changed.front()};
changed.pop_front();
for (auto v : neighbors[u]) {
auto w{distance.get(u, v)};
if (w != INFTY and shortest_path[u] + w < shortest_path[v]) {
if (v == s) {
negative_cycle = true;
changed.clear();
return;
}
shortest_path[v] = shortest_path[u] + w;
if (not changed.has(v))
changed.add(v);
}
}
}
}
template <typename T>
template <class G
#ifdef DEBUG_BELLMANFORD
......@@ -183,6 +231,88 @@ void BellmanFord<T>::allShorterPaths(const int x, const int y, const T wxy,
negative_cycle = true;
changed.clear();
return;
}
// predecessor[v] = u;
shortest_path[v] = shortest_path[u] + w;
if (not changed.has(v))
changed.add(v);
if (not reached.has(v))
reached.add(v);
}
#ifdef DEBUG_BELLMANFORD
else if (debug_flag)
cout << " reject\n";