Commit 8ad8db14 authored by ehebrard's avatar ehebrard
Browse files

cool trivial heuristic

parent 0390c40a
......@@ -27,6 +27,8 @@ using namespace schedcl;
int main(int argc, char *argv[]) {
seed(1234567);
vector<int> duration;
vector<vector<int>> resource;
......
......@@ -7,3 +7,25 @@ double schedcl::cpu_time(void) {
getrusage(RUSAGE_SELF, &ru);
return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000;
}
static unsigned long x = 123456789, y = 362436069, z = 521288629;
void schedcl::seed(const unsigned long s) {
x = s;
y = 362436069;
z = 521288629;
}
unsigned long schedcl::random(void) { // period 2^96-1
unsigned long t;
x ^= x << 16;
x ^= x >> 5;
x ^= x << 1;
t = x;
x = y;
y = z;
z = t ^ x ^ y;
return z;
}
......@@ -93,6 +93,10 @@ public:
double cpu_time(void);
void seed(const unsigned long s);
unsigned long random(void);
} // namespace SCHEDCL
#endif // _SCHEDCL_SCHEDULING_HPP
......@@ -30,22 +30,21 @@ namespace schedcl {
class ReversibleBitset : public boost::dynamic_bitset<>, public ReversibleObject {
public:
void reversible_set(const int n) {
boost::dynamic_bitset<>::set(n);
ReversibleObject::save();
trail.push_back(n);
}
void undo() {
boost::dynamic_bitset<>::reset(trail.back());
trail.pop_back();
}
private:
vector<int> trail;
void reversible_set(const int n) {
boost::dynamic_bitset<>::set(n);
ReversibleObject::save();
trail.push_back(n);
}
void undo() {
boost::dynamic_bitset<>::reset(trail.back());
trail.pop_back();
}
private:
vector<int> trail;
};
class ChoicePoint {
......@@ -203,6 +202,7 @@ public:
const Explanation<T> e);
// void exploreRight(const ChoicePoint &cp);
ChoicePoint selectChoicePoint();
bool selectBranch(const ChoicePoint &cp) const;
void search();
void backtrack();
//@}
......@@ -225,8 +225,8 @@ public:
vector<vector<DistanceVariable<T> *>> matrix;
SparseGraph<T> full_graph;
SparseGraph<T> minimal_graph;
// ReversibleBitset in_graph;
SparseSet<Reversible<size_t>> in_graph;
// ReversibleBitset in_graph;
SparseSet<Reversible<size_t>> in_graph;
ostream &print_reason(ostream &os, const int hint) const override {
os << " tr. " << *variables[hint];
......@@ -333,12 +333,12 @@ template <class T> Schedule<T>::Schedule() : queue(*this) {
// variables.push_back(new DistanceVariable<T>(*this, ORIGIN, HORIZON, 0));
newEvent(); // ORIGIN
newEvent(); // HORIZON
addMaximumLag(ORIGIN, ORIGIN, 0);
addMaximumLag(ORIGIN, ORIGIN, 0);
addMaximumLag(ORIGIN, HORIZON, INFTY);
addMaximumLag(HORIZON, ORIGIN, 0);
// addMaximumLag(ORIGIN, ORIGIN, 0);
// mapsto.push_back(2);
// variables.push_back(variables.back());
// addMaximumLag(ORIGIN, ORIGIN, 0);
// mapsto.push_back(2);
// variables.push_back(variables.back());
}
template <typename T> ChoicePoint Schedule<T>::none = {-1, -1};
......@@ -348,7 +348,7 @@ template <class T> void Schedule<T>::initialise() {
// full_graph.initialise(*this);
// full_graph.initialise(*this, true);
// minimal_graph.initialise(*this, false);
// minimal_graph.initialise(*this, false);
// for(auto v : full_graph.vertices) {
// cout << setw(4) << label(v) << ":";
......@@ -381,7 +381,7 @@ template <class T> void Schedule<T>::initialise() {
shortest_path_from_x.resize(numEvent(), INFTY);
shortest_path_to_y.resize(numEvent(), INFTY);
matrix.resize(this->numEvent());
for (auto &m : matrix)
m.resize(this->numEvent(), NULL);
......@@ -410,7 +410,6 @@ template <class T> void Schedule<T>::initialise() {
assert(variables[i]->from == variables[i + 1]->to);
assert(variables[i]->to == variables[i + 1]->from);
}
}
// assert(x != y);
......@@ -432,9 +431,9 @@ const DistanceVariable<T> *Schedule<T>::getVariable(event x, event y) const {
pair<event, event> key{x, y};
auto v{varmap.find(key)};
if (v == varmap.end()) {
if(representant[x] == representant[y] and representant[x] != 0)
return variables[ZERO];
if (representant[x] == representant[y] and representant[x] != 0)
return variables[ZERO];
key = {representant[x], representant[y]};
v = varmap.find(key);
if (v == varmap.end()) {
......@@ -451,12 +450,12 @@ DistanceVariable<T> *Schedule<T>::getVariable(event x, event y) {
// int k = *v;
if (v == varmap.end()) {
// cout << label(x) << " <> " << label(y) << " (" << label(representant[x]) << " <> " << label(representant[y]) << ")\n";
// cout << label(x) << " <> " << label(y) << " (" << label(representant[x])
// << " <> " << label(representant[y]) << ")\n";
if (representant[x] == representant[y] and representant[x] != 0)
return variables[ZERO];
if(representant[x] == representant[y] and representant[x] != 0)
return variables[ZERO];
key = {representant[x], representant[y]};
v = varmap.find(key);
if (v == varmap.end()) {
......@@ -513,15 +512,16 @@ DistanceVariable<T> *Schedule<T>::addMaximumLag(const event x, const event y,
// cout << "NEW!\n";
idvar = numVar(); // static_cast<int>(variables.size());
DistanceVariable<T> *newvar =
new DistanceVariable<T>(*this, x, y, idvar, INFTY); //lag); //(representant[x] == representant[y] ? lag : INFTY));
DistanceVariable<T> *newvar = new DistanceVariable<T>(
*this, x, y, idvar,
INFTY); // lag); //(representant[x] == representant[y] ? lag : INFTY));
varmap[{x, y}] = idvar;
variables.push_back(newvar);
changes.reserve(idvar + 1);
new_bound.resize(idvar + 1);
explanation.resize(idvar + 1);
mapsto.push_back(idvar);
in_graph.reserve(idvar + 1);
in_graph.reserve(idvar + 1);
// cout << " (new)\n";
......@@ -637,7 +637,7 @@ template <class T> event Schedule<T>::newEvent() {
event e{static_cast<event>(representant.size())};
representant.push_back(e);
offset.push_back(0);
// in_graph.resize(representant.size() * representant.size());
// in_graph.resize(representant.size() * representant.size());
return e;
}
......@@ -704,15 +704,14 @@ 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, Constant<T>::NoReason);
}
template <class T>
void Schedule<T>::addConstraint(DistanceVariable<T> *v, const T d_,
const Explanation<T> e) {
// if (isConstant(v))
// return;
// if (isConstant(v))
// return;
#ifdef TRACE
if (debug_flag and (TRACE & PROPAGATION)) {
......@@ -817,72 +816,55 @@ template <class T> bool Schedule<T>::ground(DistanceVariable<T> *x) const {
return *matrix[i][j] <= 0 or *matrix[j][i] <= -Gap<T>::epsilon();
}
template <class T> ChoicePoint Schedule<T>::selectChoicePoint() {
template <class T> bool Schedule<T>::selectBranch(const ChoicePoint &cp) const {
// return 0;
// return random() % 2;
return (T)(*opposite(variables[cp.x[0]])) > (T)(*opposite(variables[cp.x[1]]));
}
// cout << sequence << endl;
// template <class T> ChoicePoint Schedule<T>::selectChoicePoint() {
// int k{-1};
// while (not sequence.empty()) {
// k = sequence.front();
// if (not ground(choicepoints[k])) {
// sequence.pop_front();
// break;
// }
// sequence.remove_back(k);
// k = -1;
// }
// return (k >= 0 ? choicepoints[k] : Schedule<T>::none);
// }
// ChoicePoint cp{Schedule<T>::none};
template <class T> ChoicePoint Schedule<T>::selectChoicePoint() {
// cout << "epsilon: " << (Gap<T>::epsilon()) << " " << (-Gap<T>::epsilon())
// << endl;
// for (auto k : sequence) {
// auto cp{choicepoints[k]};
// if (not ground(cp)) {
// auto ei{variables[cp.x[0]]->from};
// auto ej{variables[cp.x[0]]->to};
//
// cout << label(ei) << " <> " << label(ej) << endl;
//
// cout << *matrix[ORIGIN][ei] << endl;
// cout << *matrix[HORIZON][ei] << endl;
// cout << *matrix[ei][ORIGIN] << endl;
// cout << *matrix[ei][HORIZON] << endl;
//
// cout << *variables[cp.x[0]] << " or " << *variables[cp.x[1]] << endl;
// }
// }
// cout << sequence << endl;
int k{-1};
while (not sequence.empty()) {
k = sequence.front();
// cp = choicepoints[k];
// if (not ground(choicepoints[sequence.front()]))
// displayChoicePoint(cout, choicepoints[k]);
// cout << (ground(choicepoints[k]) ? "*" : " ok!") << endl;
// // cout << "? " << ground(cp) << "/" << sequence.size() << endl;
if (not ground(choicepoints[k])) {
// cout << "break\n";
sequence.pop_front();
break;
}
sequence.remove_back(k);
k = -1;
// cout << "continue\n";
int tightest{-1};
T min_gap{0};
for(auto p{sequence.rbegin()}; p!=sequence.rend(); ++p) {
k = *p;
if (ground(choicepoints[k]))
sequence.remove_back(k);
else {
auto gap0 = (T)(*opposite(variables[choicepoints[k].x[0]]));
auto gap1 = (T)(*opposite(variables[choicepoints[k].x[1]]));
auto gap = max(gap0, gap1);
if(tightest < 0 or min_gap > gap) {
min_gap = gap;
tightest = k;
}
}
}
// #ifdef TRACE
// if (TRACE & SEARCH) {
// if (k < 0) {
// cout << "no choice point left!\n";
// } else {
// cout << "select choice point " << k << " @LEVEL "
// << ReversibleObject::env->level() << ": ";
// displayChoicePoint(cout, choicepoints[k]);
// cout << endl;
// }
// }
// #endif
// if(k >=0)
// cp = choicepoints[k];
return (k >= 0 ? choicepoints[k] : Schedule<T>::none);
if(tightest >= 0) {
sequence.remove_front(tightest);
return choicepoints[tightest];
}
return Schedule<T>::none;
}
template <class T> ostream &Schedule<T>::displayStats(ostream &os) const {
os << "new bounds = [" << left << setw(5) << setfill('.') << lb
<< setfill(' ');
......@@ -894,9 +876,9 @@ template <class T> ostream &Schedule<T>::displayStats(ostream &os) const {
os << "] fails=" << setw(8) << left << num_fails
// << " updates=" << setw(10) << left << num_updates
<< " literals=" << setw(12) << left << num_literals
<< " prunings=" << setw(8) << left << num_prunings << " graph=" << setw(8)
<< left << minimal_graph.arcCount() << " cpu=" << (cpu_time() - start_time)
<< "\n";
<< " prunings=" << setw(8) << left << num_prunings << " graph=" << setw(5)
<< right << minimal_graph.arcCount() << "/" << left
<< full_graph.arcCount() << " cpu=" << (cpu_time() - start_time) << "\n";
#else
os << endl;
#endif
......@@ -905,7 +887,7 @@ template <class T> ostream &Schedule<T>::displayStats(ostream &os) const {
template <class T> void Schedule<T>::search() {
start_time = cpu_time();
// initialisation
sequence.reserve(choicepoints.size());
sequence.fill();
......@@ -923,7 +905,7 @@ template <class T> void Schedule<T>::search() {
// }
try {
propagate();
assert(queue.empty());
......@@ -941,6 +923,9 @@ template <class T> void Schedule<T>::search() {
}
}
if (num_choicepoints % 10000 == 0)
displayStats(cout);
#ifdef TRACE
if (debug_flag and (TRACE & SEARCH) and !(TRACE & PROPAGATION)) {
cout << "bounds = [" << lb << ".." << ub << "]\n" << *this << endl;
......@@ -984,7 +969,7 @@ template <class T> void Schedule<T>::search() {
#ifdef TRACE
if (debug_flag and (TRACE & SEARCH)) {
cout << "new choice point @LEVEL " << ReversibleObject::env->level()
// << " (" << cp.x[0] << "|" << cp.x[1] << ") : ";
// << " (" << cp.x[0] << "|" << cp.x[1] << ") : ";
#ifndef DEBUGCMP
<< " (" << num_literals << "): ";
#else
......@@ -994,11 +979,10 @@ template <class T> void Schedule<T>::search() {
// cout << " ** " << *variables[300] << " and " << *variables[301];
cout << endl;
}
#endif
explore(cp, 0, Constant<T>::NoReason);
explore(cp, selectBranch(cp), Constant<T>::NoReason);
}
} catch (const Failure &f) {
......@@ -1046,7 +1030,6 @@ template <class T> void Schedule<T>::backtrack() {
assert(not ground(cp));
explore(cp, otherbranch, Constant<T>::NoReason); // TODO: use conflict!!
}
template <class T> void Schedule<T>::propagate() {
......@@ -1080,7 +1063,6 @@ template <class T> void Schedule<T>::propagate() {
++num_propagations;
algorithm->propagate();
}
#ifdef TRACE
......@@ -1105,22 +1087,21 @@ template <class T> void Schedule<T>::updateDistances() {
// assert(not isConstant(variables[i]));
if (not isClone(variables[i])) {
// auto x{variables[i]->from};
// auto y{variables[i]->to};
// for(auto e : minimal_graph.neighbor[SUCCESSOR][x]) {
// assert(e.neighbor() != y);
// }
// cout << "add " << *variables[i] << endl;
// if(not isConstant(variables[i]))
// if(*variables[i] == INFTY)
if(not in_graph.has(i)) {
minimal_graph.addArc(variables[i]);
in_graph.add(i);
}
// auto x{variables[i]->from};
// auto y{variables[i]->to};
// for(auto e : minimal_graph.neighbor[SUCCESSOR][x]) {
// assert(e.neighbor() != y);
// }
// cout << "add " << *variables[i] << endl;
// if(not isConstant(variables[i]))
// if(*variables[i] == INFTY)
if (not in_graph.has(i)) {
minimal_graph.addArc(variables[i]);
in_graph.add(i);
}
set(variables[i], new_bound[i], explanation[i]);
}
}
......@@ -1178,7 +1159,6 @@ void Schedule<T>::set(DistanceVariable<T> *v, const T bound, const Explanation<T
auto x{v->from};
auto y{v->to};
fill(shortest_path_from_x.begin(), shortest_path_from_x.end(), INFTY);
fill(shortest_path_to_y.begin(), shortest_path_to_y.end(), INFTY);
......@@ -1195,7 +1175,6 @@ void Schedule<T>::set(DistanceVariable<T> *v, const T bound, const Explanation<T
algo.initialise(numEvent());
for (auto i{0}; i < numEvent(); ++i) {
if (matrix[x][i] != NULL)
shortest_path_from_x[i] = *matrix[x][i];
......@@ -1429,7 +1408,7 @@ template <class T> void Schedule<T>::verifyAPSP() {
#endif
template <class T> ostream &Schedule<T>::display(ostream &os) const {
//
//
os << "\n ";
for (auto i{0}; i < numEvent(); ++i)
......@@ -1481,41 +1460,41 @@ template <class T> ostream &Schedule<T>::display(ostream &os) const {
//
// #ifdef ONLYIMAL
//
// cout << minimal_graph << endl;
vector<T> dbuffer(numEvent(), -INFTY);
os << "\n ";
for (auto i{0}; i < numEvent(); ++i)
// if (vertices.has(i))
os << right << setw(6) << label(i) << " ";
os << endl;
for (auto i{0}; i < numEvent(); ++i) {
// if (vertices.has(i)) {
os << setw(4) << label(i) << ":";
// dbuffer[i] = 0;
for (auto &e : minimal_graph.neighbor[SUCCESSOR][i])
dbuffer[e.neighbor()] = e.length();
for (auto j{0}; j < numEvent(); ++j) {
if (i == j)
os << " ";
else if (matrix[i][j] == NULL)
os << " ";
else if (*matrix[i][j] == INFTY)
os << " ";
else if (dbuffer[j] == -INFTY)
os << " . ";
else
os << " " << setw(5) << right << (T)(*matrix[i][j]) << " ";
}
for (auto &e : minimal_graph.neighbor[SUCCESSOR][i])
dbuffer[e.neighbor()] = -INFTY;
// dbuffer[i] = -INFTY;
os << endl;
// }
// cout << minimal_graph << endl;
vector<T> dbuffer(numEvent(), -INFTY);
os << "\n ";
for (auto i{0}; i < numEvent(); ++i)
// if (vertices.has(i))
os << right << setw(6) << label(i) << " ";
os << endl;
for (auto i{0}; i < numEvent(); ++i) {
// if (vertices.has(i)) {
os << setw(4) << label(i) << ":";
// dbuffer[i] = 0;
for (auto &e : minimal_graph.neighbor[SUCCESSOR][i])
dbuffer[e.neighbor()] = e.length();
for (auto j{0}; j < numEvent(); ++j) {
if (i == j)
os << " ";
else if (matrix[i][j] == NULL)
os << " ";
else if (*matrix[i][j] == INFTY)
os << " ";
else if (dbuffer[j] == -INFTY)
os << " . ";
else
os << " " << setw(5) << right << (T)(*matrix[i][j]) << " ";
}
for (auto &e : minimal_graph.neighbor[SUCCESSOR][i])
dbuffer[e.neighbor()] = -INFTY;
// dbuffer[i] = -INFTY;
os << endl;
// }
}
//
// #elif defined(DEBUG_UPDATES)
//
......@@ -1600,7 +1579,6 @@ void ConstraintQueue<T, N>::notifyChange(const int id) {
}
#endif
++schedule.num_literals;
for (auto &trigger : triggers[id]) {
auto cons_id{trigger.constraint_id};
......
......@@ -174,6 +174,10 @@ CumulativeTimeTabling<T, C>::CumulativeTimeTabling(Schedule<T> &schedule,
distance[END(i)][START(i)] =
m_schedule.addMaximumLag(END(m_tasks[i]), START(m_tasks[i]), INFTY);
distance[END(i)][END(i)] = m_schedule.variables[ZERO];
distance[START(i)][START(i)] = m_schedule.variables[ZERO];
// distance[START(i)][END(i)] = m_schedule.addMaximumLag(START(m_tasks[i]),
// END(m_tasks[i]), max_processing);
// distance[END(i)][START(i)] = m_schedule.addPrecedence(START(m_tasks[i]),
......@@ -438,7 +442,7 @@ void CumulativeTimeTabling<T, C>::propagate() {
}
#endif
assert(TASK(i) != e);
assert(TASK(e) != i);
cur_explanation.back() = distance[e][START(i)]->current();
m_schedule.addConstraint(distance[e][END(i)], -offset_before_event, {this, static_cast<int>(explanations.size())});
......@@ -476,7 +480,7 @@ void CumulativeTimeTabling<T, C>::propagate() {
}
#endif
assert(TASK(i) != e);
assert(TASK(e) != i);
cur_explanation.back() = distance[END(i)][e]->current();
m_schedule.addConstraint(distance[START(i)][e], -offset_after_event, {this, static_cast<int>(explanations.size())});
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment