Commit 29b02a65 authored by ehebrard's avatar ehebrard
Browse files

gr

parent be39536e
/*************************************************************************
minicsp
Copyright 2010--2011 George Katsirelos
Minicsp is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
Minicsp is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with minicsp. If not, see <http://www.gnu.org/licenses/>.
*************************************************************************/
// #include "DistanceVariable.hpp"
#include "BellmanFord.hpp"
#include "DistanceGraph.hpp"
#include "SparseDistanceGraph.hpp"
#include "TimeTabling.hpp"
#include "osp.hpp"
using namespace std;
using namespace schedcl;
int main(int argc, char *argv[]) {
vector<int> duration;
vector<vector<int>> resource;
osp::read_instance("j3-per0-1.txt", duration, resource);
cout << duration.size() << " tasks:";
for (auto d : duration) {
cout << " " << d;
}
cout << endl;
cout << resource.size() << " resources:";
for (auto R : resource) {
cout << " (";
for (auto x : R) {
cout << " " << x;
}
cout << ")";
}
cout << endl;
Schedule<int> S;
for (auto d : duration) {
S.addTask("t" + to_string(S.numTask()), d, d);
}
vector<CumulativeTimeTabling<int, int> *> cons;
for (auto &R : resource) {
vector<int> demand(R.size(), 1);
cons.push_back(new CumulativeTimeTabling<int, int>(
S, R.begin(), R.end(), demand.begin(), demand.end(), 1));
// for (auto x : R) {
// for (auto y : R)
// if (x != y) {
// S.addEdge(START(x), START(y));
// S.addEdge(START(x), END(y));
// S.addEdge(END(x), START(y));
// S.addEdge(END(x), END(y));
// S2.addEdge(START(x), START(y));
// S2.addEdge(START(x), END(y));
// S2.addEdge(END(x), START(y));
// S2.addEdge(END(x), END(y));
// }
// }
cons.back()->debug_flag = true;
}
auto ub{osp::getUb(duration, resource)};
S.setUpperBound(ub);
// vector<task> scope;
// vector<int> demand;
// for (auto &job : resource) {
// demand.resize(job.size(), 1);
// for (auto j : job)
// scope.push_back(j);
// SparseDistanceGraph<int> SG(S);
// cout << SG << endl;
// DistanceGraph<int> G(S2);
// cout << G << endl;
// G.FloydWarshall();
// cout << G << endl;
// BellmanFord<int> BF(SG.size());
// vector<int> shortest_path(S.numEvent(), numeric_limits<int>::max());
//
// BF.allShortestPaths(ORIGIN, SG.successor, shortest_path);
// for(auto v{0}; v<S.numEvent(); ++v)
// cout << S.label(v) << ": " << shortest_path[v] << endl;
S.initialise();
cout << S << endl;
S.updateDistances();
cout << S << endl;
auto u{S.getVariable(START(1), END(0))};
S.addConstraint(u, 0);
S.updateDistances();
cout << S << endl;
cout << "save\n";
ReversibleObject::env->save();
cout << S.graph << endl;
// cout << "merge\n";
for (auto i{0}; i < S.numTask(); ++i)
S.graph.merge(START(i), END(i), duration[i]);
cout << S.graph << endl;
cout << "restore to level " << ReversibleObject::env->level() << "\n";
ReversibleObject::env->restore(ReversibleObject::env->level());
cout << S << endl;
cout << "OK!\n";
for (auto c : cons) {
c->propagate();
}
}
......@@ -73,6 +73,7 @@ int main(int argc, char *argv[]) {
S1.addEdge(START(x), END(y));
S1.addEdge(END(x), START(y));
S1.addEdge(END(x), END(y));
S2.addEdge(START(x), START(y));
S2.addEdge(START(x), END(y));
S2.addEdge(END(x), START(y));
......@@ -159,7 +160,7 @@ int main(int argc, char *argv[]) {
// cout << "merge\n";
for (auto i{0}; i < S1.numTask(); ++i)
S1.graph.merge(START(i), END(i));
S1.graph.merge(START(i), END(i), duration[i]);
cout << S1.graph << endl;
......@@ -174,14 +175,18 @@ int main(int argc, char *argv[]) {
// 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;
// auto v{S.getVariable(START(1), END(0))};
// S.set(v, 0);
//
// cout << S << endl;
//
//
//
//
//
// //
//
// DistanceGraph<int> G(S,
// events.begin(), events.end());
// G.initialise();
......
#include "TimeTabling.hpp"
......@@ -71,13 +71,13 @@ void BellmanFord<T>::allShortestPaths(const int s, const G& neighbors, vector<T>
auto u{changed.front()};
changed.pop_front();
cout << u << ":";
// cout << u << ":";
for (auto e : neighbors[u]) {
auto v{e.next(u)};
auto v{e.neighbor()};
auto w{e.length()};
cout << " (" << v << "|" << w << ")";
// cout << " (" << v << "|" << w << ")";
if (w != INFTY and shortest_path[u] + w < shortest_path[v]) {
......@@ -88,7 +88,7 @@ void BellmanFord<T>::allShortestPaths(const int s, const G& neighbors, vector<T>
shortest_path[v] = shortest_path[u] + w;
cout << " (" << shortest_path[v] << ")";
// cout << " (" << shortest_path[v] << ")";
if (not changed.has(v))
changed.add(v);
......@@ -97,7 +97,7 @@ void BellmanFord<T>::allShortestPaths(const int s, const G& neighbors, vector<T>
}
}
cout << endl;
// cout << endl;
}
}
......@@ -115,7 +115,7 @@ 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.next(u)};
auto v{e.neighbor()};
auto w{e.length()};
if (w != INFTY and shortest_path[u] + w < shortest_path[v]) {
......
......@@ -13,15 +13,14 @@ using event = int;
using namespace std;
//
// template <class T>
// template <typename T>
// class DistanceVariable ;
template <typename T> class Schedule;
template <class T> class Schedule;
template <typename T> class DistanceVariable;
template <class T> class DistanceVariable;
template <class T> class DistanceLiteral {
template <typename T> class DistanceLiteral {
public:
// DistanceLiteral() {
......@@ -31,6 +30,13 @@ public:
DistanceVariable<T> *var{NULL};
int lit{-1};
ostream &display(ostream &os) const {
os << var->sched.label(var->to) << " - " << var->sched.label(var->from)
<< " <= " << var->get(lit).value;
// os << "e" << to << " - e" << from << " <= " << get();
return os;
}
};
// class DistanceLiteral {
......@@ -53,26 +59,26 @@ DistanceGraph are also explainers, for the transitivity
The static object "NoReason" is the empty reason
*/
template <class T> class Explainer {
template <typename T> class Explainer {
public:
virtual void xplain(const int hint, vector<DistanceLiteral<T>> &Cl) const {};
// virtual void xplain(const int hint, vector<DistanceLiteral>& Cl)
// const {};
};
template <class T> class Constant {
template <typename T> class Constant {
public:
static Explainer<T> *NoReason;
static DistanceLiteral<T> NoLiteral;
};
template <class T> Explainer<T> *Constant<T>::NoReason = new Explainer<T>();
template <typename T> Explainer<T> *Constant<T>::NoReason = new Explainer<T>();
template <class T>
template <typename T>
DistanceLiteral<T> Constant<T>::NoLiteral = {
static_cast<DistanceVariable<T> *>(NULL), -1};
template <class T> struct Bound {
template <typename T> struct Bound {
T value;
const Explainer<T> *reason;
......@@ -82,7 +88,7 @@ template <class T> struct Bound {
// literals x - y <= k (with x,y pointing to vars and k a constant)
template <class T> class DistanceVariable : public ReversibleObject {
template <typename T> class DistanceVariable : public ReversibleObject {
public:
Schedule<T> &sched;
......@@ -111,6 +117,10 @@ public:
// reason.push_back(Constant<T>::NoReason);
}
DistanceLiteral<T> current() {
return {this, static_cast<int>(literals.size()) - 1};
}
// get the current distance
T get() const { return literals.back().value; }
......@@ -223,11 +233,16 @@ protected:
// vector<const int> hint;
};
template <class T>
template <typename T>
ostream &operator<<(ostream &os, const DistanceVariable<T> &x) {
return x.display(os);
}
template <typename T>
ostream &operator<<(ostream &os, const DistanceLiteral<T> &x) {
return x.display(os);
}
} // namespace schedcl
#endif
......@@ -16,11 +16,79 @@ namespace schedcl {
#define HORIZON 1
#define CMAX 0
#define LOWERBOUND 1
#define SUCCESSOR 0
#define PREDECESSOR 1
task TASK(event x);
event START(task x);
event END(task x);
template <class T> class Gap {
public:
static constexpr T epsilon() noexcept { return T(); }
};
template <> class Gap<short> {
public:
static constexpr short epsilon() noexcept { return 1; }
};
template <> class Gap<int> {
public:
static constexpr int epsilon() noexcept { return 1; }
};
template <> class Gap<long> {
public:
static constexpr long int epsilon() noexcept { return 1; }
};
template <> class Gap<long long> {
public:
static constexpr long long int epsilon() noexcept { return 1; }
};
template <> class Gap<unsigned short> {
public:
static constexpr short epsilon() noexcept { return 1; }
};
template <> class Gap<unsigned int> {
public:
static constexpr int epsilon() noexcept { return 1; }
};
template <> class Gap<unsigned long> {
public:
static constexpr long int epsilon() noexcept { return 1; }
};
template <> class Gap<unsigned long long> {
public:
static constexpr long long int epsilon() noexcept { return 1; }
};
template <> class Gap<float> {
public:
static constexpr float epsilon() noexcept {
return 10e-6; // std::numeric_limits<float>::epsilon();
}
};
template <> class Gap<double> {
public:
static constexpr double epsilon() noexcept {
return 10e-9; // std::numeric_limits<double>::epsilon();
}
};
template <> class Gap<long double> {
public:
static constexpr double epsilon() noexcept {
return 10e-12; // std::numeric_limits<long double>::epsilon();
}
};
} // namespace SCHEDCL
#endif // _SCHEDCL_SCHEDULING_HPP
......@@ -7,15 +7,16 @@
// #include <boost/dynamic_bitset.hpp>
#include "Global.hpp"
#include "BellmanFord.hpp"
#include "SparseDistanceGraph.hpp"
#include "Global.hpp"
#include "SparseGraph.hpp"
// #include "SparseDistanceGraph.hpp"
namespace schedcl {
template <class T> class DistanceVariable;
template <class T> class DistanceGraph;
// template <class T> class DistanceGraph;
// class ConstraintQueue {
//
......@@ -61,8 +62,10 @@ public:
//@{
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);
DistanceVariable<T> *addMaximumLag(const event x, const event y,
const T lag = 0);
DistanceVariable<T> *addPrecedence(const event x, const event y,
const T delay = 0);
void addEdge(const event x, const event y);
void setUpperBound(const T b);
//@}
......@@ -73,6 +76,8 @@ public:
void updateDistances();
void fail(Explainer<T> *expl, const int hint);
// set the distance var v to 'bound' and update all shortest paths
void set(DistanceVariable<T> *v, const T bound);
//@}
......@@ -83,7 +88,9 @@ public:
//@}
// the graph of distances
SparseDistanceGraph<T> graph;
// SparseDistanceGraph<T> graph;
SparseGraph<T> graph;
private:
/*!@name Private Parameters*/
......@@ -101,6 +108,15 @@ private:
// the value corresponding to the requests above
vector<T> new_bound;
// tail[i] == last variable mapped to i
vector<int> tail;
// next[i] == next variable mapped to the same variable as i (i, if there is
// none)
vector<int> next;
// prev[i] == prev variable mapped to the same variable as i (i, if there is
// none)
vector<int> prev;
// the Bellman-Ford algorithm and structures required to handle the changes
BellmanFord<T> algo;
......@@ -122,6 +138,8 @@ template <class T> Schedule<T>::Schedule() {
}
template <class T> void Schedule<T>::initialise() {
// graph.initialise(*this);
graph.initialise(*this);
shortest_path_from_x.resize(numEvent(), INFTY);
......@@ -251,16 +269,18 @@ DistanceVariable<T> *Schedule<T>::getVariable(event x, event y) {
//
template <class T>
void Schedule<T>::addPrecedence(const event x, const event y, const T delay) {
DistanceVariable<T> *Schedule<T>::addPrecedence(const event x, const event y,
const T delay) {
// variables.push_back(new DistanceVariable<T>(*this, y, x,
// numVar(), -delay));
addMaximumLag(y, x, -delay);
return addMaximumLag(y, x, -delay);
}
template <class T>
void Schedule<T>::addMaximumLag(const event x, const event y, const T lag) {
DistanceVariable<T> *Schedule<T>::addMaximumLag(const event x, const event y,
const T lag) {
pair<event, event> key{x, y};
auto v{varmap.find(key)};
......@@ -298,6 +318,8 @@ void Schedule<T>::addMaximumLag(const event x, const event y, const T lag) {
if(lag != INFTY) {
addConstraint(variables[idvar], lag);
}
return variables[idvar];
}
template <class T>
......@@ -343,6 +365,10 @@ void Schedule<T>::addConstraint(DistanceVariable<T> *v, const T d) {
}
}
template <class T> void Schedule<T>::fail(Explainer<T> *expl, const int hint) {
cout << "FAIL!!\n"; // TODO
}
template <class T> void Schedule<T>::updateDistances() {
// int k{3};
......@@ -392,8 +418,11 @@ void Schedule<T>::set(DistanceVariable<T> *v, const T bound) {
algo.initialise(numEvent());
// backwardAlgo.initialise(numEvent());
algo.allShortestPaths(x, graph.successor, shortest_path_from_x);
algo.allShortestPaths(y, graph.predecessor, shortest_path_to_y);
// algo.allShortestPaths(x, graph.successor, shortest_path_from_x);
// algo.allShortestPaths(y, graph.predecessor, shortest_path_to_y);
algo.allShortestPaths(x, graph.neighbor[SUCCESSOR], shortest_path_from_x);
algo.allShortestPaths(y, graph.neighbor[PREDECESSOR], shortest_path_to_y);
for (auto i{0}; i < numEvent(); ++i) {
cout << setw(4) << label(i) << ": " << shortest_path_from_x[i] << " / "
......@@ -402,11 +431,17 @@ void Schedule<T>::set(DistanceVariable<T> *v, const T bound) {
v->set(bound);
algo.allShorterPaths(x, y, bound, graph.successor, shortest_path_from_x,
fCandidates);
// algo.allShorterPaths(x, y, bound, graph.successor, shortest_path_from_x,
// fCandidates);
//
// algo.allShorterPaths(y, x, bound, graph.predecessor, shortest_path_to_y,
// bCandidates);
algo.allShorterPaths(y, x, bound, graph.predecessor, shortest_path_to_y,
bCandidates);
algo.allShorterPaths(x, y, bound, graph.neighbor[SUCCESSOR],
shortest_path_from_x, fCandidates);
algo.allShorterPaths(y, x, bound, graph.neighbor[PREDECESSOR],
shortest_path_to_y, bCandidates);
cout << "f cand:\n";
for (auto i{0}; i < numEvent(); ++i)
......@@ -424,8 +459,8 @@ void Schedule<T>::set(DistanceVariable<T> *v, const T bound) {
// vertices whose distance from x has been reduced
for (auto b : fCandidates) {
for (auto e : graph.predecessor[b]) {
auto a{e.from()};
for (auto e : graph.neighbor[PREDECESSOR][b]) {
auto a{e.neighbor()};
if (shortest_path_to_y[a] != INFTY and shortest_path_from_x[b] != INFTY) {
auto nd{shortest_path_to_y[a] - bound + shortest_path_from_x[b]};
if (nd < e.length()) {
......@@ -438,8 +473,8 @@ void Schedule<T>::set(DistanceVariable<T> *v, const T bound) {
}
for (auto a : bCandidates) {
for (auto e : graph.successor[a]) {
auto b{e.to()};
for (auto e : graph.neighbor[SUCCESSOR][a]) {
auto b{e.neighbor()};
if (shortest_path_to_y[a] != INFTY and shortest_path_from_x[b] != INFTY) {
auto nd{shortest_path_to_y[a] - bound + shortest_path_from_x[b]};
if (nd < e.length()) {
......@@ -776,7 +811,39 @@ template <class T> ostream &Schedule<T>::display(ostream &os) const
{
vector<T> dbuffer(numEvent(), -INFTY);
os << " ";
// os << " ";
// for (auto i{0}; i < numEvent(); ++i)
// // if (vertices.has(i))
// os << " " << setw(4) << label(i);
// os << endl;
// for (auto i{0}; i < numEvent(); ++i) {
// // if (vertices.has(i)) {
//
// os << setw(4) << label(i) << ":";
// for (auto &e : graph.successor[i])
// dbuffer[e.to()] = e.length();
// for (auto j{0}; j < numEvent(); ++j)
// if (dbuffer[j] != -INFTY) {
// if (dbuffer[j] == INFTY) {
// os << " oo";
// } else {
// os << " " << setw(4) << dbuffer[j];
// }
// } else {
// os << " ";
// }
// for (auto &e : graph.successor[i])
// dbuffer[e.to()] = -INFTY;
// os << endl;
// // }
// }
// return os;