Commit 125e25a2 authored by ehebrard's avatar ehebrard
Browse files

ok update

parent f66e157a
......@@ -104,11 +104,11 @@ int main(int argc, char *argv[]) {
DistanceGraph<int> G(S2);
cout << G << endl;
// cout << G << endl;
G.FloydWarshall();
// G.FloydWarshall();
// cout << G << endl;
// cout << G << endl;
// BellmanFord<int> BF(SG.size());
......@@ -120,29 +120,58 @@ int main(int argc, char *argv[]) {
// for(auto v{0}; v<S.numEvent(); ++v)
// cout << S.label(v) << ": " << shortest_path[v] << endl;
S1.initialise();
S2.initialise();
cout << S1 << endl;
cout << S2 << endl;
S1.initialise();
S2.initialise();
// cout << S1 << endl;
// cout << S2 << endl;
//
// // S1.update(0,1)
//
// auto v2{S2.getVariable(START(1), END(0))};
// v2->set(0);
//
// // S2.addPrecedence(END(0), START(1), 0);
//
// G.FloydWarshall();
//
// cout << S2 << endl;
// S2.addPrecedence(END(0), START(1));
//
// G.FloydWarshall();
//
// cout << S2 << endl;
S1.updateDistances();
S2.updateDistances();
G.FloydWarshall();
cout << S1 << endl;
cout << S2 << endl;
for (auto v : S1.variables) {
auto x{v->from};
auto y{v->to};
auto w{v->get()};
//
auto u{S2.getVariable(x, y)};
if(w != u->get()) {
cout << "d[" << S1.label(x) << "][" << S1.label(y) << "]=" << w << "/" << u->get() << endl;
}
}
auto u{S1.getVariable(START(1), END(0))};
S1.addConstraint(u, 0);
S1.updateDistances();
cout << S1 << endl;
// auto v2{S2.getVariable(START(1), END(0))};
// v2->set(0);
// G.FloydWarshall();
// auto v1{S1.getVariable(START(1), END(0))};
// S1.set(v1, 0);
//
// cout << S1 << endl;
//
//
// DistanceGraph<int> G(S, events.begin(), events.end());
// G.initialise();
......
......@@ -70,28 +70,38 @@ void BellmanFord<T>::allShortestPaths(const int s, const G& neighbors, vector<T>
// reached.add(s);
while(not changed.empty()) {
auto u{changed.front()};
auto u{changed.front()};
changed.pop_front();
for(auto e : neighbors[u]) {
auto v{e.to()};
auto w{e.length()};
if(w != INFTY and shortest_path[u] + w < shortest_path[v]) {
if(v == s) {
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);
}
cout << u << ":";
for(auto e : neighbors[u]) {
auto v{e.next(u)};
auto w{e.length()};
cout << " (" << v << "|" << w << ")";
if (w != INFTY and shortest_path[u] + w < shortest_path[v]) {
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>
......@@ -108,21 +118,21 @@ void BellmanFord<T>::allShorterPaths(const int x, const int y, const T wxy, cons
changed.pop_front();
for(auto e : neighbors[u]) {
auto v{e.to()};
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);
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);
}
}
}
......
......@@ -199,7 +199,8 @@ public:
}
ostream &display(ostream &os) const {
os << "e" << to << " - e" << from << " <= " << get();
os << sched.label(to) << " - " << sched.label(from) << " <= " << get();
// os << "e" << to << " - e" << from << " <= " << get();
return os;
}
......
......@@ -15,6 +15,7 @@ namespace schedcl {
#define ORIGIN 0
#define HORIZON 1
#define CMAX 0
#define LOWERBOUND 1
task TASK(event x);
event START(task x);
......
......@@ -5,29 +5,14 @@
#include <string>
#include <vector>
// #define NoHint -1
// #define INFTY numeric_limits<T>::max()
//
// #define ORIGIN 0
// #define HORIZON 1
// #define CMAX 0
#include <boost/dynamic_bitset.hpp>
#include "Global.hpp"
#include "BellmanFord.hpp"
#include "SparseDistanceGraph.hpp"
// #include "DistanceVariable.hpp"
// using namespace std;
// using event = int;
// using task = int;
namespace schedcl {
// task TASK(event x);
// event START(task x);
// event END(task x);
template <class T> class DistanceVariable;
template <class T> class DistanceGraph;
......@@ -52,149 +37,103 @@ template <class T> class Schedule {
// using edge = DistanceConstraint<T>;
public:
/*!@name Constructors*/
//@{
Schedule();
void initialise();
~Schedule() {}
//@}
/*!@name Accessors*/
//@{
DistanceVariable<T> *getVariable(event x, event y);
// vector<DistanceVariable<T> *>& getVariables();
int getUB() const;
int numVar() const;
int numTask() const;
int numEvent() const;
string label(const int event) const;
//@}
/*!@name Modelling*/
//@{
void addTask(const std::string &label, const T min_processing,
const T max_processing);
void addMaximumLag(const event x, const event y, const T lag = 0);
void addPrecedence(const event x, const event y, const T delay = 0);
void addEdge(const event x, const event y);
void setUpperBound(const T b);
//@}
string label(const int event) const;
/*!@name Pruning and Solving*/
//@{
void addConstraint(DistanceVariable<T> *v, const T d);
void updateDistances();
void update(const event x, const event y, const T w);
// set the distance var v to 'bound' and update all shortest paths
void set(DistanceVariable<T> *v, const T bound);
//@}
/*!@name Public Parameters*/
//@{
vector<DistanceVariable<T> *> variables;
//@}
private:
/*!@name Private Parameters*/
//@{
// // whether the distance variable has already been added to the graph
// boost::dynamic_bitset<> declared;
SparseDistanceGraph<T> graph;
// the graph of distances
SparseDistanceGraph<T> graph;
// map of variables indexed by pairs of events, used only when creating the
// variables to avoid duplicates
map<const pair<event, event>, int> varmap;
// nice labels for tasks
vector<string> task_label;
BellmanFord<T> forwardAlgo;
BellmanFord<T> backwardAlgo;
// int num_task{0};
// int num_event{2}; // there are always at least to events 0=BEG and 1=END
// /*** propagation stuff ***/
// ConstraintQueue queue;
// vector<vector<vector<int>>> constraint_graph;
// // vector<vector<vector<int>>> rule_graph;
// edge_idx last_literal;
//
// // /*** trail stuff for rules ***/
// // vector<int> cons_trail;
// // vector<event> ev_trail;
// // vector<size_t> tr_size;
// // void pop(int &rule, const int from, const int to);
//
// public:
// bool learn_clause{false};
// size_t numPropagation{0};
/* void setLearning(const bool l) {
learn_clause = l;
getGraph()->use_learning = l;
}*/
// size_t numTask();
// size_t numEvent();
//
// task addTask(const std::string &label, const T min_processing,
// const T max_processing);
// void addOverlap(const task i, const task j);
// void addPrecedence(const task i, const task j);
// void setUpperBound(const T max_processing);
// void setLowerBound(const T min_processing);
// T getUpperBound() const;
// T getLowerBound() const;
//
// void propagate();
//
// string label(const task i);
//
// DifferenceSystem<T> *getGraph();
//
// T getMinProcessing(const task x);
// T getMaxProcessing(const task x);
//
// T getEarliestStart(const task x);
// T getLatestStart(const task x);
// T getEarliestCompletion(const task x);
// T getLatestCompletion(const task x);
//
// // C_TYPE getConsumption(const task x);
// bool overlap(const task x, const task y);
// bool precede(const task x, const task y);
//
// void save() {
// ds->save();
// // tr_size.push_back(cons_trail.size());
// }
// the list of "change" requests that are not yet taken into account
SparseSet changes;
// the value corresponding to the requests above
vector<T> new_bound;
// void restore() {
// ds->restore();
// last_literal = getGraph()->numEdge();
//
// // auto ps{tr_size.back()};
// // tr_size.pop_back();
// // while (cons_trail.size() > ps) {
// // auto cons{cons_trail.back()};
// // cons_trail.pop_back();
// // auto event2{ev_trail.back()};
// // ev_trail.pop_back();
// // auto event1{ev_trail.back()};
// // ev_trail.pop_back();
// // trigger_me_on_edge(event1, event2, cons);
// // }
// //
// // assert(2 * cons_trail.size() == ev_trail.size());
// }
// the Bellman-Ford algorithm and structures required to handle the changes
BellmanFord<T> algo;
vector<int> shortest_path_from_x;
vector<int> shortest_path_to_y;
SparseSet fCandidates;
SparseSet bCandidates;
//@}
// template <class RandomIt>
// void wake_me_on(RandomIt f, RandomIt l, const int idx);
// void wake_me_on_edge(const event e1, const event e2, const int idx);
// // void trigger_me_on_edge(const event e1, const event e2, const int idx);
// void post(ScheduleConstraint *c);
//
// void search();
//
public:
ostream& display(ostream &os) const;
//
// ostream &printTask(ostream &os, const task x);
};
template <class T> Schedule<T>::Schedule() : graph(*this) {
variables.push_back(new DistanceVariable<T>(*this, ORIGIN, HORIZON, 0));
// variables.push_back(new DistanceVariable<T>(*this, ORIGIN, HORIZON, 0));
addMaximumLag(ORIGIN, HORIZON, INFTY);
addMaximumLag(HORIZON, ORIGIN, 0);
}
template <class T> void Schedule<T>::initialise() {
graph.initialise();
shortest_path_from_x.resize(numEvent(), INFTY);
shortest_path_to_y.resize(numEvent(), INFTY);
fCandidates.reserve(numEvent());
bCandidates.reserve(numEvent());
// declared.resize(numVar(), 0);
// declared.clear();
}
// assert(x != y);
......@@ -328,22 +267,40 @@ void Schedule<T>::addMaximumLag(const event x, const event y, const T lag) {
pair<event, event> key{x, y};
auto v{varmap.find(key)};
// cout << "ADD LAG " << x << " " << y << " " << delay << endl;
int idvar;
// cout << "ADD LAG " << x << " " << y << " " << delay << endl;
if (v == varmap.end()) {
int idvar = numVar(); // static_cast<int>(variables.size());
idvar = numVar(); // static_cast<int>(variables.size());
DistanceVariable<T> *newvar =
new DistanceVariable<T>(*this, x, y, idvar, lag);
new DistanceVariable<T>(*this, x, y, idvar, INFTY);
varmap[key] = idvar;
variables.push_back(newvar);
changes.reserve(idvar + 1);
new_bound.resize(idvar + 1);
} else {
// cout << " x[" << v->second << "] = (" << variables[v->second]->from << " -> " << variables[v->second]->to << ") = " << variables[v->second]->get() << endl;
variables[v->second]->set(lag);
// cout << " x[" << v->second << "] = (" << variables[v->second]->from << "
// -> " << variables[v->second]->to << ") = " << variables[v->second]->get()
// << end;
idvar = v->second;
// if (variables[idvar]->get() < lag)
// return;
//
// variables[idvar]->set(lag);
}
// set(variables[v->second], lag);
// if (not changes.has(idvar) and lag != INFTY) {
// changes.add(idvar);
// new_bound[idvar] = lag;
// }
if(lag != INFTY) {
addConstraint(variables[idvar], lag);
}
}
template <class T>
......@@ -351,6 +308,7 @@ void Schedule<T>::addTask(const std::string &label, const T min_processing,
const T max_processing) {
auto i{numTask()};
addMaximumLag(START(i), END(i), max_processing);
addPrecedence(START(i), END(i), min_processing);
addPrecedence(ORIGIN, START(i));
......@@ -367,28 +325,137 @@ template <class T> void Schedule<T>::addEdge(const event x, const event y) {
template <class T> void Schedule<T>::setUpperBound(const T b) {
addConstraint(variables[CMAX], b);
// addMaximumLag(ORIGIN, HORIZON, b);
variables[CMAX]->set(b);
// variables[CMAX]->set(b);
// set(variables[CMAX], b);
}
template <class T>
void Schedule<T>::update(const event x, const event y, const T w) {
vector<int> shortest_path_from_x(numEvent(), INFTY);
vector<int> shortest_path_to_y(numEvent(), INFTY);
forwardAlgo.initialise(numEvent());
backwardAlgo.initialise(numEvent());
forwardAlgo.allShortestPaths(x, graph.successor, shortest_path_from_x);
forwardAlgo.allShortestPaths(y, graph.predecessor, shortest_path_to_y);
void Schedule<T>::addConstraint(DistanceVariable<T> *v, const T d) {
auto vid{v->id};
if (changes.has(vid)) {
if (new_bound[vid] > d) {
new_bound[vid] = d;
}
} else {
if (v->get() > d) {
changes.add(vid);
new_bound[vid] = d;
}
}
}
template <class T> void Schedule<T>::updateDistances() {
// int k{3};
while (not changes.empty()) {
auto i{changes.front()};
changes.pop_front();
// for(auto i : changes) {
cout << "change on " << *variables[i] << ": " << new_bound[i] << endl;
set(variables[i], new_bound[i]);
// cout << k << endl << *this << endl;
// if(--k <= 0)
// exit(1);
}
}
template <class T>
void Schedule<T>::set(DistanceVariable<T> *v, const T bound) {
if (bound >= v->get())
return;
auto x{v->from};
auto y{v->to};
// if(not declared[v->id]) {
// graph.addEdge(v);
// declared.set(v->id);
// }
cout << "add " << label(x) << " -" << bound << "-> " << label(y) << endl;
fill(shortest_path_from_x.begin(), shortest_path_from_x.end(), INFTY);
fill(shortest_path_to_y.begin(), shortest_path_to_y.end(), INFTY);
vector<int> shortest_path_from_x(numEvent(), INFTY);
vector<int> shortest_path_to_y(numEvent(), INFTY);
fCandidates.clear();
bCandidates.clear();
// vector<int> shortest_path_from_x(numEvent(), INFTY);
// vector<int> shortest_path_to_y(numEvent(), INFTY);
algo.initialise(numEvent());
// backwardAlgo.initialise(numEvent());
algo.allShortestPaths(x, graph.successor, shortest_path_from_x);
algo.allShortestPaths(y, graph.predecessor, shortest_path_to_y);
for (auto i{0}; i < numEvent(); ++i) {
cout << setw(4) << label(i) << ": " << shortest_path_from_x[i] << " / "
<< shortest_path_to_y[i] << endl;
}
v->set(bound);
algo.allShorterPaths(x, y, bound, graph.successor, shortest_path_from_x,
fCandidates);
algo.allShorterPaths(y, x, bound, graph.predecessor, shortest_path_to_y,
bCandidates);
cout << "f cand:\n";
for (auto i{0}; i < numEvent(); ++i)
if (fCandidates.has(i)) {
// for(auto i : fCandidates) {
cout << setw(4) << label(i) << ": " << shortest_path_from_x[i] << endl;
}
cout << "b cand:\n";
for (auto i{0}; i < numEvent(); ++i)
if (bCandidates.has(i)) {
// for(auto i : bCandidates) {
cout << setw(4) << label(i) << ": " << shortest_path_to_y[i] << endl;
}
// vertices whose distance from x has been reduced
for (auto b : fCandidates) {
for (auto e : graph.predecessor[b]) {
auto a{e.from()};