Commit d09c3598 authored by ehebrard's avatar ehebrard
Browse files

refactoring

parent 354c2407
......@@ -7,7 +7,7 @@ Graph::Graph() : ReversibleObject() {}
void Graph::addArc(const int u, const int v) {
if (edges.newArc(u, v)) {
// if (edges.newArc(u, v)) {
ReversibleObject::save();
trail.push_back(u);
trail.push_back(v);
......@@ -18,7 +18,7 @@ void Graph::addArc(const int u, const int v) {
// cout << *this << endl;
verify("add arc");
#endif
}
// }
// cout << edges << endl;
}
......@@ -41,7 +41,7 @@ void Graph::add(Arc a) {
++numArc;
}
bool Graph::has(const int u, const int v) const { return edges.has(u, v); }
// bool Graph::has(const int u, const int v) const { return edges.has(u, v); }
void Graph::removeVertex(const int u) {
......@@ -222,7 +222,7 @@ void Graph::undo(Arc a) {
neighbor_rank[l][a[l]].pop_back();
}
edges.remove(a);
// edges.remove(a);
--numArc;
}
......@@ -243,7 +243,7 @@ void Graph::resize(const int n) {
// cout << "before resize " << edges << endl;
edges.resize(this->vertices, this->neighbor[SUCCESSOR]);
// edges.resize(this->vertices, this->neighbor[SUCCESSOR]);
// cout << "after resize " << edges << endl;
}
......@@ -397,7 +397,7 @@ ostream &Graph::display(ostream &os) const {
}
os << edges << endl;
// os << edges << endl;
return os;
......@@ -420,14 +420,14 @@ void Graph::verify(const char *msg) {
}
if(l==SUCCESSOR)
if(not edges.has(x,y)) {
cout << msg << ": error, edge (" << x << "," << y << ") is not in edge set"
<< endl << *this << endl;
cout << edges << endl;
exit(1);
}
// if(not edges.has(x,y)) {
// cout << msg << ": error, edge (" << x << "," << y << ") is not in edge set"
// << endl << *this << endl;
//
// cout << edges << endl;
//
// exit(1);
// }
auto jth{neighbor_rank[l][x][ith]};
......@@ -515,6 +515,55 @@ ostream& EdgeSet::display(ostream& os) const {
size_t EdgeSet::count() const { return edgeset.count(); }
bool ReversibleEdgeSet::newArc(const int x, const int y) {
if (x != y) {
auto e{x * size_ + y};
if (not edgeset[e]) {
ReversibleObject::save();
trail.push_back(x);
trail.push_back(y);
edgeset.set(e);
return true;
}
}
return false;
}
bool ReversibleEdgeSet::has(const int x, const int y) const {
return edgeset[x * size_ + y];
}
void ReversibleEdgeSet::remove(const Arc a) {
assert(edgeset[a[0] * size_ + a[1]]);
edgeset.reset(a[0] * size_ + a[1]);
}
ostream& ReversibleEdgeSet::display(ostream& os) const {
for(auto u{0}; u<size_; ++u) {
for(auto v{0}; v<size_; ++v) {
if(has(u,v))
os << " (" << u << "," << v << ")";
}
}
return os;
}
size_t ReversibleEdgeSet::count() const {
return edgeset.count();
}
void ReversibleEdgeSet::undo() {
auto y{trail.back()};
trail.pop_back();
auto x{trail.back()};
trail.pop_back();
remove(Arc(x,y));
}
// void EdgeSet::remove(const int x, const int y) {
// if (x != y) {
// auto e{x * size() + y};
......@@ -524,6 +573,23 @@ size_t EdgeSet::count() const { return edgeset.count(); }
// }
// }
void ReversibleEdgeSet::resize(const size_t n) {
if(n<size_)
return;
edgeset.resize(n * n, 0);
for(auto u{size_}; u-->0;) {
for(auto v{size_}; v-->0;) {
if(has(u,v)) {
edgeset.set(u * n + v);
edgeset.reset(u * size_ + v);
}
}
}
size_ = n;
}
std::ostream &schedcl::operator<<(std::ostream &os, const schedcl::Graph &x) {
return x.display(os);
}
......
#include "Scheduler.hpp"
......@@ -47,8 +47,6 @@ public:
// for every variable, its triggers
vector<vector<Trigger>> triggers;
// vector<vector<Trigger>> event_triggers;
ConstraintQueue(Scheduler<T> &s);
void resize(const size_t n);
......@@ -75,6 +73,8 @@ public:
size_t numVar() const;
size_t numCons() const;
ostream &display(ostream &os) const;
};
template <typename T, int N>
......@@ -172,6 +172,28 @@ template <typename T, int N> bool ConstraintQueue<T, N>::empty() const {
return true;
}
template <typename T, int N>
ostream &ConstraintQueue<T, N>::display(ostream &os) const {
for (auto x{0}; x < scheduler.numEvent(); ++x) {
for (auto y{0}; y < scheduler.numEvent(); ++y) {
auto varxy{scheduler.getVariable(x, y)};
if (varxy != NoVar) {
os << "watch " << scheduler.label(x) << "->" << scheduler.label(y)
<< ":";
for (auto t : triggers[varxy])
os << " " << *(constraints[t.constraint_id]);
os << endl;
}
}
}
return os;
}
template <typename T, int N>
ostream &operator<<(ostream &os, const ConstraintQueue<T, N> &x) {
return x.display(os);
}
template <class T> ostream &operator<<(ostream &os, const ResourceConstraint<T> &x) {
return x.display(os);
}
......
#ifndef _SCHEDCL_CONSTRAINT_HPP
#define _SCHEDCL_CONSTRAINT_HPP
#include "Graph.hpp"
namespace schedcl {
template <typename T> class ConstraintGraph {
public:
// all constraints
vector<ResourceConstraint<T> *> constraints;
// bipartite graph variables/constraints. successors are triggers, predecessors are scopes
Graph network;
ConstraintGraph();
vector<int>& operator[](const int var_id) const;
// vector<int>& scope(const int cons_id);
// void resize(const size_t n);
// void initialise_triggers();
// add a new constraint to the queue, returns the index of that constraint in
// the queue
void add(ResourceConstraint<T> *cons);
int addVar();
void createTrigger(const var v, const int c);
// void createEventTrigger(const int evt, const int c, const int h);
// notifies that variable 'id' has changed, activate the corresponding
// triggers
void merge(const int x, const int y);
size_t size() const;
size_t numVar() const;
size_t numCon() const;
// ostream &display(ostream &os) const;
};
template <typename T>
ConstraintGraph<T>::ConstraintGraph() {}
template<typename T>
vector<int>& ConstraintGraph<T>::operator[](const int var_id) const {
return network[SUCCESSOR][var_id + numCon()];
}
// template<typename T>
// vector<int>& ConstraintGraph<T>::scope(const int cons_id) {
// return network[PREDECESSOR][cons_id];
// }
template<typename T>
size_t ConstraintGraph<T>::size() const {
return network.size();
}
template<typename T>
size_t ConstraintGraph<T>::numCon() const {
return constraints.size();
}
template<typename T>
size_t ConstraintGraph<T>::numVar() const {
return size() - numCon();
}
// add a new variable
template <typename T>
int ConstraintGraph<T>::addVar() {
network.resize(size()+1);
return static_cast<int>(numVar())-1;
}
// add a new constraint
template <typename T>
void ConstraintGraph<T>::add(ResourceConstraint<T> *cons) {
constraints.push_back(cons);
network.resize(numCon()+1);
}
template <typename T>
void ConstraintGraph<T>::createTrigger(const var v, const int c) {
network.addArc(v + numCon(), c);
}
// template <typename T, int N>
// ostream &ConstraintQueue<T, N>::display(ostream &os) const {
//
// for (auto x{0}; x < size(); ++x) {
// if(constraints[x] == NULL) {
// for (auto y{0}; y < size(); ++y) {
// if(constraints[y] != NULL) {
//
//
// auto varxy{scheduler.getVariable(x, y)};
// if (varxy != NoVar) {
// os << "watch " << scheduler.label(x) << "->" << scheduler.label(y)
// << ":";
// for (auto t : triggers[varxy])
// os << " " << *(constraints[t.constraint_id]);
// os << endl;
// }
// }
// }
// }
// }
// return os;
// }
//
// template <typename T, int N>
// ostream &operator<<(ostream &os, const ConstraintQueue<T, N> &x) {
// return x.display(os);
// }
//
// template <class T> ostream &operator<<(ostream &os, const ResourceConstraint<T> &x) {
// return x.display(os);
// }
} // namespace SCHEDCL
#endif // _SCHEDCL_SCHEDULING_HPP
#ifndef _SCHEDCL_CONSTRAINTQUEUE_HPP
#define _SCHEDCL_CONSTRAINTQUEUE_HPP
#include "Constraint.hpp"
#include "SparseSet.hpp"
namespace schedcl {
template <typename T, int N> class ConstraintQueue {
public:
vector<ResourceConstraint<T>*> *constraints;
// which ones need to be propagated
SparseSet<> active[N]; // alows for N levels of priority
ConstraintQueue(); //vector<ResourceConstraint<T>*> &s);
// void resize(const size_t n);
void initialize(vector<ResourceConstraint<T>*> *c);
// notifies that variable 'id' has changed, activate the corresponding
// triggers
void triggers(const int var_id, const int cons_id);
// returns the active constraint of highest priority that has been activated
// first, return NULL if there are no active constraint
ResourceConstraint<T> *pop_front();
// bool empty() const;
void clear();
bool empty() const;
ostream &display(ostream &os) const;
};
template <typename T, int N>
ConstraintQueue<T, N>::ConstraintQueue() {
// resize(constraints.size());
}
// template <typename T, int N>
// void ConstraintQueue<T, N>::resize(const size_t n) {
// for(auto i{0}; i<N; ++i)
// active[i].reserve(n);
// }
template <typename T, int N>
void ConstraintQueue<T, N>::initialize(vector<ResourceConstraint<T>*> *c) {
constraints = c;
for(auto i{0}; i<N; ++i)
active[i].reserve(constraints->size());
}
// template <typename T, int N>
// void ConstraintQueue<T, N>::resize(const size_t n) {
// for(auto i{0}; i<N; ++i)
// active[i].reserve(n);
// }
// notifies that variable 'id' has changed, activate the corresponding
// triggers
template <typename T, int N>
void ConstraintQueue<T, N>::triggers(const int var_id, const int cons_id) {
auto cons = (*constraints)[cons_id];
cons->notify(var_id);
auto p{cons->priority};
if (not active[p].has(cons_id)) {
active[p].add(cons_id);
#ifdef TRACE
if (scheduler.debug_flag and (TRACE & PROPAGATION)) {
cout << " triggers " << *cons << endl;
}
#endif
}
}
template <typename T, int N>
ResourceConstraint<T> *ConstraintQueue<T, N>::pop_front() {
auto i{N};
ResourceConstraint<T> *cons{NULL};
while (i-- > 0) {
if (not active[i].empty()) {
cons = (*constraints)[active[i].front()];
active[i].pop_front();
break;
}
}
return cons;
}
template <typename T, int N>
void ConstraintQueue<T, N>::clear() {
for (auto i{N}; i-- > 0;)
active[i].clear();
}
template <typename T, int N> bool ConstraintQueue<T, N>::empty() const {
for (auto i{N}; i-- > 0;)
if (not active[i].empty())
return false;
return true;
}
template <typename T, int N>
ostream &ConstraintQueue<T, N>::display(ostream &os) const {
for(auto p{N}; p-->0;) {
os << "p" << p << ":";
for(auto a : active[p])
os << " " << *((*constraints)[a]) ;
os << endl;
}
return os;
}
template <typename T, int N>
ostream &operator<<(ostream &os, const ConstraintQueue<T, N> &x) {
return x.display(os);
}
} // namespace SCHEDCL
#endif // _SCHEDCL_SCHEDULING_HPP
......@@ -129,6 +129,8 @@ public:
// be careful, does not work with merges
T get(const event ei, const event ej) const;
lit getLiteral(const event ei, const event ej) const;
// handles the case where 'from' and/or 'to' are merged events and calls
// 'set()'
// TODO: explanations
......@@ -160,6 +162,7 @@ public:
private:
Graph core;
ReversibleEdgeSet core_edges;
// boost::dynamic_bitset<> core_edges;
// vector<size_t> core_list;
......@@ -316,6 +319,11 @@ T BackwardDistance<T>::get(const event ei, const event ej) const {
return m.get(ej, ei);
}
// template <class T>
// lit DistanceMatrix<T>::getLiteral(const event ei, const event ej) const {
// return distance[ei][ej];
// }
template <class T> DistanceMatrix<T>::DistanceMatrix() : first_edge(0) {
// NoLit
prev_edge.push_back(numLiterals()); // prev_edge is self
......@@ -340,7 +348,12 @@ template <class T> DistanceMatrix<T>::DistanceMatrix() : first_edge(0) {
// ORIGIN is the first event, HORIZON is the last event
current_edge[HORIZON][ORIGIN] = IdLit;
core.addArc(HORIZON, ORIGIN);
// if()
core.addArc(HORIZON, ORIGIN);
auto ver{core_edges.newArc(HORIZON, ORIGIN)};
assert(ver);
// core_edges.newArc(HORIZON, ORIGIN);
first_edge = 2;
// resize(2);
......@@ -367,6 +380,11 @@ template <class T> void DistanceMatrix<T>::resize(const size_t n) {
core.addArc(i, ORIGIN);
core.addArc(HORIZON, i);
auto ver{core_edges.newArc(i, ORIGIN)};
assert(ver);
ver = core_edges.newArc(HORIZON, i);
assert(ver);
}
}
......@@ -402,6 +420,7 @@ template <class T> void DistanceMatrix<T>::reserve(const size_t n) {
merged.reserve(n);
core.resize(n);
core_edges.resize(n);
shortest_path_from_x.resize(n, INFTY);
shortest_path_to_y.resize(n, INFTY);
......@@ -440,6 +459,11 @@ void DistanceMatrix<T>::getLiteralInfo(const lit l, event &x, event &y, T &d) co
d = distance[l];
}
template <class T>
lit DistanceMatrix<T>::getLiteral(const event ei, const event ej) const {
return current_edge[ei][ej];
}
template <class T>
void DistanceMatrix<T>::xplain(const hint h, vector<lit> &Cl) const {
cout << "TODO!\n";
......@@ -635,7 +659,9 @@ void DistanceMatrix<T>::add(const event ei, const event ej, const T d,
// }
// addToCore(rei, rej);
core.addArc(rei, rej);
if(core_edges.newArc(rei, rej))
core.addArc(rei, rej);
// core_edges.newArc(rei, rej);
// cout << "add (" << ei << "->" << ej << "):" << d << endl;
//
......@@ -816,6 +842,15 @@ template <class T> void DistanceMatrix<T>::undo() {
}
undoMerge();
// for(auto x{0}; x<size(); ++x) {
// for(auto y{0}; y<size(); ++y) {
// assert(core.has(x,y) == core_edges.has(x,y));
// cout << "ok\n";
// }
// }
}
template <class T> int DistanceMatrix<T>::getPrintWidth() const {
......@@ -845,7 +880,7 @@ void DistanceMatrix<T>::printRow(ostream &os, const int i,
for (auto j{0}; j < size(); ++j) {
if (core.vertices.has(j) or getRepresentant(j, d) == i)
os << setw(pwidth) << right << pretty((*this)(i, j))
<< (core.has(i, j) ? "*" : " ");
<< (core_edges.has(i, j) ? "*" : " ");
else
os << setw(pwidth + 1) << "";
}
......@@ -856,7 +891,7 @@ void DistanceMatrix<T>::printRow(ostream &os, const int i,
if (j > 0)
os << right << setw((pwidth + 1) * j) << "";
os << setw(pwidth) << right << pretty((*this)(i, j))
<< (core.has(i, j) ? "*" : " ");
<< (core_edges.has(i, j) ? "*" : " ");
// << endl;
}
}
......
......@@ -44,6 +44,27 @@ private:
size_t size_{0};
};
class ReversibleEdgeSet : public ReversibleObject {
public:
void resize(const size_t n);
bool has(const int x, const int y) const;
bool newArc(const int x, const int y);
void remove(const Arc a);
ostream& display(ostream& os) const;
size_t count() const;
void undo() override;
private:
boost::dynamic_bitset<> edgeset;
size_t size_{0};
vector<int> trail;
};
/*
Implementation of a graph
- It supports [adding new Arcs/not really]; reducing Arcs' weights; and
......@@ -85,13 +106,13 @@ public:
// merge vertex v to vertex u
void merge(const int u, const int v);