Commit 426b3e93 authored by Valentin Antuori's avatar Valentin Antuori
Browse files

warming

parent ba0112b6
......@@ -13,6 +13,8 @@ using namespace std;
int FAIL_LIMIT = 10000;
double ALPHA = 0.90;
bool WARMING = false;
int RESTART = false;
int DFSRollout::component_ect(const int op) const
{
......@@ -182,21 +184,21 @@ void DFSRollout::get_operations() {
actions.push_back(p);
} else if(data.is_pickup(prev_operation[i])) {
if(num_operation[i] != 1 && num_operation[i] != 3){
std::cout << num_operation[i] <<"/" << period[i] << std::endl;
std::cout << "prev = " << prev_operation[i] << std::endl;
std::cout << "compo = " << i << std::endl;
for(auto elt : sequence)
std::cout << elt << std::endl;
// std::cout << num_operation[i] <<"/" << period[i] << std::endl;
// std::cout << "prev = " << prev_operation[i] << std::endl;
// std::cout << "compo = " << i << std::endl;
// for(auto elt : sequence)
// std::cout << elt << std::endl;
}
assert(num_operation[i] == 1 || num_operation[i] == 3);
actions.push_back(data.get_delivery(prev_operation[i]));
} else {
if(num_operation[i] != 2){
std::cout << num_operation[i] <<"/" << period[i] << std::endl;
std::cout << "prev = " << prev_operation[i] << std::endl;
std::cout << "compo = " << i << std::endl;
for(auto elt : sequence)
std::cout << elt << std::endl;
// std::cout << num_operation[i] <<"/" << period[i] << std::endl;
// std::cout << "prev = " << prev_operation[i] << std::endl;
// std::cout << "compo = " << i << std::endl;
// for(auto elt : sequence)
// std::cout << elt << std::endl;
}
assert(num_operation[i] == 2);
if(data.is_full_operation(prev_operation[i])) {
......@@ -298,7 +300,7 @@ void DFSRollout::compute_distance(const int op) {
tardiness[op] = component_ect(op) - data.due_date(op);
// Test was with :
tardiness[op] = start[op] + data.duration(op) - data.due_date(op);
// tardiness[op] = start[op] + data.duration(op) - data.due_date(op);
// auto f{(1.0 - fast_sigmoid(tardiness[op] - get_tardiness()))};
......@@ -461,12 +463,13 @@ void DFSRollout::greedy_stochastic(int upper_bound) {
}
}
void DFSRollout::extend_rollout() {
void DFSRollout::extend_rollout(int ub) {
int timeout;
bool can_stop = false;
restore_state();
// std::cout << "Restored" << std::endl;
if(debug_dfs)
std::cerr << "Restored" << std::endl;
if(get_tardiness() > 0)
{
......@@ -483,7 +486,7 @@ void DFSRollout::extend_rollout() {
if(get_tardiness() == 0)
first_tard_depth = sequence.size();
if(!can_stop && get_tardiness() > 0)
if(get_tardiness() > ub && !can_stop && get_tardiness() > 0)
{
timeout = sequence.size() + 1000;
can_stop = true;
......@@ -677,13 +680,25 @@ void DFSRollout::restart(const int lvl, int& restart_size, int& restart_limit)
restart_limit += restart_size;
if(verbose)
cout << "o restart\n";
if(warming){
temperature += warming_step;
// std::cout << "T = " << temperature << std::endl;
}
if(debug_dfs)
std::cerr << "========= Restart =========" << std::endl;
restore_start(lvl);
}
void DFSRollout::warm_up(int step, int restart_prevision)
{
double a = (warm - cold)/std::max(1, (restart_prevision*restart_prevision - 1));//max in order to prevent 0 denominator
double b = cold;
temperature = a*step*step + b; // basic quadratic function from two points (base and target temperature)
if(verbose)
std::cout << "d temperature=" << temperature <<", a=" << a << ", b=" << b << ", step=" << step << std::endl;
if(debug_dfs){
std::cerr << "Restart prevision=" << restart_prevision << std::endl;
std::cerr << "d temperature=" << temperature <<", a=" << a << ", b=" << b << ", step=" << step << std::endl;
}
}
void DFSRollout::clear() {
sequence.clear();
best_solution.clear();
......@@ -700,7 +715,7 @@ void DFSRollout::clear() {
maximum_tardiness.clear();
maximum_tardiness.push_back(0);
maximum_tardiness.push_back(numeric_limits<int>::min());
maximum_positive_tardiness.clear();
maximum_positive_tardiness.push_back(0);
......@@ -715,11 +730,10 @@ void DFSRollout::clear() {
first_tard_depth = 0;
start_level = 0;
}
///*
int DFSRollout::search(int ub, int ub_depth) {
int DFSRollout::search(int ub, int lb_depth) {
cout.precision(6);
......@@ -738,18 +752,18 @@ int DFSRollout::search(int ub, int ub_depth) {
int iter{0};
int restart_limit{restart_base};
int restart_size{restart_base};
int nb_restart = 0;
int restart_prevision;
bool first_fail = true;
temperature = base_temperature;
if(warming){
temperature = cold;
}
// if(warming){
// temperature = cold;
// }
while(true) {
++iter;
// branch
while(sequence.size() < data.nb_tasks) {
......@@ -767,7 +781,18 @@ int DFSRollout::search(int ub, int ub_depth) {
{
if(verbose)
{
cout << "d depth=" << sequence.size() << " iter=" << iter << endl;
cout << "d depth=" << sequence.size() << "(lmax="<< get_tardiness() << ") iter=" << iter << endl;
if(sequence.size() == 284){
for(auto elt : maximum_positive_tardiness)
std::cout << elt << " ";
std::cout << std::endl << "=====" << std::endl;
for(auto elt : maximum_tardiness)
std::cout << elt << " ";
std::cout << std::endl << "=====" << std::endl;
for(auto elt : sequence)
std::cout << elt << " ";
std::cout << std::endl;
}
}
save_state();
}
......@@ -785,6 +810,7 @@ int DFSRollout::search(int ub, int ub_depth) {
if(proba[*a] > 0)
domain[i].push_back(*a);
}
// std::cout << actions.size() << " / " << domain[i].size() << std::endl;
sum_domain_size += domain[i].size();
nb_dom++;
......@@ -806,15 +832,17 @@ int DFSRollout::search(int ub, int ub_depth) {
// branch left
action[i] = domain[i].begin();
// if(debug_dfs){
// std::cout << "branch left on " << *action[i] << std::endl;
// std::cout << "Domain : " << std::endl;
// for(auto elt : domain[i]){
// std::cout << elt << " ";
// }
// std::cout << "\nIterator at position : " << (action[i] - domain[i].begin()) << std::endl;
// }
if(debug_dfs){
std::cerr << "branch left on " << *action[i] << std::endl;
std::cerr << "Action's size : " << actions.size() << std::endl;
std::cerr << "Domain's size : " << domain[i].size() << std::endl;
std::cerr << "Domain : ";
for(auto elt : domain[i]){
std::cerr << elt << " ";
}
std::cerr << "\nIterator at position : " << (action[i] - domain[i].begin()) << std::endl;
std::cerr << std::endl;
}
commit(*action[i]);
// print_step();
......@@ -822,36 +850,36 @@ int DFSRollout::search(int ub, int ub_depth) {
if(first_fail and auto_limit)
{
max_iter = 1;
first_fail = false;
if(sequence.size() == data.nb_tasks || first_tard_depth > ub_depth)
max_iter = 1;
if(sequence.size() == data.nb_tasks || first_tard_depth > lb_depth) // improvement of lmax lupper bound, or longer sequence without tardiness
{
max_iter = FAIL_LIMIT;
}else if(first_tard_depth > ALPHA * ub_depth)
}else if(first_tard_depth > ALPHA * lb_depth)
{
double term = (1 - (ub_depth - first_tard_depth)/(ub_depth - ALPHA*ub_depth));
double term = (1 - (lb_depth - first_tard_depth)/(lb_depth - ALPHA*lb_depth));
term = (double)first_tard_depth/lb_depth;
max_iter = FAIL_LIMIT * term * term;
}
// verbose = max_iter > 1;
if(verbose){
std::cout << "o max_iter=" << max_iter << std::endl;
}
// warming computation
if(warming && max_iter > 1)
if(restart_base && warming && max_iter > 1)
{
int k = 0;
restart_prevision = 0;
int tmp_limit = restart_base;
int tmp_iter = tmp_limit;
//how many restart ?
while(tmp_iter < max_iter)
{
k++;
restart_prevision++;
tmp_limit *= restart_factor;
tmp_iter += tmp_limit;
}
warming_step = (warm-cold) / k;
// std::cout << "Iter : " << max_iter << std::endl;
// std::cout << "Warming step = " << warming_step << std::endl;
// std::cout << "Nb restart = " << k << std::endl;
}
}
......@@ -875,6 +903,10 @@ int DFSRollout::search(int ub, int ub_depth) {
if(restart_base and iter >= restart_limit) {
restart(start_level, restart_size, restart_limit);
if(warming){
warm_up(nb_restart, restart_prevision);
}
nb_restart++;
continue;
}
......@@ -894,18 +926,21 @@ int DFSRollout::search(int ub, int ub_depth) {
// if there is an action that we haven't tried yet, try it, otherwise backtrack again
if(action[i] != domain[i].end()) {
// if(debug_dfs){
// std::cerr << "right branch : " << *action[i] << std::endl;
// for(auto elt : sequence){
// std::cerr << elt << " ";
// }
// std::cerr << std::endl;
// for(auto elt : domain[i])
// {
// std::cerr << elt << " ";
// }
// std::cerr << std::endl;
// }
if(debug_dfs){
std::cerr << "-- Backtrack --" << std::endl;
std::cerr << "Start lvl = " << start_level << std::endl;
std::cerr << "Sequence's size = " << sequence.size() << std::endl;
std::cerr << "right branch : " << *action[i] << std::endl;
for(auto elt : sequence){
std::cerr << elt << " ";
}
std::cerr << std::endl << "Domain : ";
for(auto elt : domain[i])
{
std::cerr << elt << " ";
}
std::cerr << std::endl;
}
compute_distance(*action[i]);
maximum_tardiness.push_back(std::max(maximum_tardiness.back(), tardiness[*action[i]]));
maximum_positive_tardiness.push_back(std::max(0, maximum_tardiness.back()));
......
......@@ -3,7 +3,7 @@
#define __DFSROLLOUT_H
// #define DEBUG_DFS_ROLLOUT
#define DEBUG_DFS_ROLLOUT
......@@ -23,6 +23,8 @@ using namespace std;
extern bool debug_dfs;
extern double ALPHA;
extern int FAIL_LIMIT;
extern bool WARMING;
extern int RESTART;
class DFSRollout {
......@@ -33,7 +35,7 @@ public:
void greedy_first();
void greedy_best();
void greedy_stochastic(int upper_bound=std::numeric_limits<int>::infinity());
void extend_rollout();
void extend_rollout(int ub);
// return the number of fail before stop
int search(int ub, int ub_depth=0);
......@@ -60,18 +62,18 @@ public:
void verify(const char* msg, const int offset=0);
// params
double base_temperature{0.01};
double temperature{0.01};
double sigmoid_slope{0.0005};
bool verbose{false};
bool verified{true};
bool verified{false};
bool randomized{true};
bool auto_limit{true};
int restart_base{0};
int restart_base{RESTART};
double restart_factor{1.2};
bool warming{false};
double warming_step;
bool warming{WARMING};
double cold{0.00001};
double warm{0.1};
......@@ -103,6 +105,45 @@ public:
return maximum_positive_tardiness[pos+2] - maximum_positive_tardiness[pos+1];
}
void replay(std::vector<int> v)
{
auto i{0};
for(auto elt : v)
{
get_operations();
compute_distances();
std::cout << i <<" : Actions : " << std::endl;
for(auto ac : actions)
{
std::cout << ac << " ";
}
std::cout << "\nTardiness : " << get_tardiness() << std::endl;
std::cout << "Train = " << train_length << std::endl;
std::cout << "->"<< elt << std::endl;
commit(elt);
std::cout << "===============" << std::endl;
++i;
}
get_operations();
compute_distances();
std::cout << i <<" : Actions : " << std::endl;
for(auto elt : actions)
{
std::cout << elt << " ->" << tardiness[elt] << std::endl;
}
std::cout << "Train = " << train_length << std::endl;
std::cout << std::endl << "Tardiness : " << get_tardiness() << std::endl;
}
private:
......@@ -211,6 +252,8 @@ private:
// return .5 * (slope * t / (1 + abs(slope * t))) + .5;
return slope * t / (1 + abs(slope * t));
}
void warm_up(int step, int restart_prevision);
};
......
......@@ -229,6 +229,7 @@ int main(int argc, char **argv){
else */
if(opt.mcts)
{
set_epsilon(opt.epsilon);
set_c_mode(opt.c_mode);
......@@ -236,10 +237,13 @@ int main(int argc, char **argv){
set_aggregation(opt.aggregation);
set_c_decay(opt.c_decay);
set_stop_rollout(!opt.complete_rollout);
lb1 = opt.lb1;
//dfs rollouts parameter
FAIL_LIMIT = opt.fail_limit;
ALPHA = opt.alpha;
WARMING = opt.warming;
RESTART = opt.restart;
Solution sol = solve(data[0], opt.c, opt.time);
......@@ -254,35 +258,11 @@ int main(int argc, char **argv){
build(sol);
std::cout << sol.lmax() << std::endl;
}
else{
else if(opt.dfs_mode){
DFSRollout rollout(data[0]);
rollout.temperature = opt.temperature;
set_default_temperature(opt.temperature);
// double sol_rol = 0;
// double sol_greed = 0;
// double sol_greed2 = 0;
// for(int i = 0; i < 2000; ++i)
// {
// WITHOUT_TARDINESS = false;
// rollout.clear();
// rollout.greedy_stochastic();
// sol_rol = sol_rol + (rollout.get_tardiness() - sol_rol)/(i+1);
// Solution sol(&data[0]);
// build(sol);
// sol_greed = sol_greed + (sol.lmax() - sol_greed)/(i+1);
// WITHOUT_TARDINESS = true;
// Solution sol2(&data[0]);
// build(sol2);
// sol_greed2 = sol_greed2 + (sol2.lmax() - sol_greed2)/(i+1);
// // std::cout << rollout.get_tardiness() << " / " << sol.lmax() << std::endl;
// }
// std::cout << sol_rol << " / " << sol_greed << " / " << sol_greed2 << std::endl;
rollout.auto_limit = false;
......@@ -291,6 +271,43 @@ int main(int argc, char **argv){
rollout.max_iter = std::numeric_limits<int>::max();
rollout.search(1, 0);
}else
{
/*
DFSRollout rollout(data[0]);
rollout.temperature = opt.temperature;
set_default_temperature(opt.temperature);
double sol_rol = 0;
double sol_greed = 0;
double sol_greed2 = 0;
for(int i = 0; i < 2000; ++i)
{
rollout.clear();
rollout.greedy_stochastic();
sol_rol = sol_rol + (rollout.get_tardiness() - sol_rol)/(i+1);
WITHOUT_TARDINESS = true;
Solution sol2(&data[0]);
build(sol2);
sol_greed2 = sol_greed2 + (sol2.lmax() - sol_greed2)/(i+1);
WITHOUT_TARDINESS = false;
Solution sol(&data[0]);
build(sol);
sol_greed = sol_greed + (sol.lmax() - sol_greed)/(i+1);
// std::cout << rollout.get_tardiness() << " / " << sol.lmax() << std::endl;
}
std::cout << sol_rol << " / " << sol_greed << " / " << sol_greed2 << std::endl;
//*/
std::vector<int> v{278,100,438,279,494,495,316,550,439,436,101,338,317,398,399,396,339,437,60,258,259,42,61,376,397,358,377,43,40,378,379,102,103,104,551,548,549,256,41,576,257,416,577,578,579,610,417,418,611,336,419,626,359,356,105,106,337,62,63,22,107,594,23,20,21,296,627,624,357,318,319,110,625,616,111,442,443,554,555,108,595,592,593,440,441,552,553,608,297,298,299,602,109,114,609,260,261,262,263,46,115,112,617,584,47,618,113,380,381,402,403,64,619,26,585,422,423,420,421,586,27,24,587,382,383,400,401,44,603,600,65,118,601,300,25,66,301,302,45,444,67,322,303,340,119,116,445,446,323,360,117,122,341,342,361,362,363,320,123,120,321,558,559,556,557,622,447,614,121,630,631,628,623,620,629,124,343,304,125,126,305,306,307,266,267,324,127,426,427,598,599,30,31,28,325,326,29,264,265,404,405,48,621,386,387,384,49,364,327,448,449,450,451,128,615,424,425,590,385,406,407,68,129,130,69,70,71,562,563,560,131,50,561,612,613,580,581,132,133,134,51,596,365,366,591,588,367,346,347,344,345,606,135,32,607,410,411,308,33,34,589,454,455,452,453,430,431,428,429,270,271,268,269,408,409,390,391,388,389,52,53,54,55,35};
DFSRollout rollout(data[0]);
rollout.replay(v);
}
// std::cout << "Fin" << std::endl;
......
......@@ -14,7 +14,7 @@
#include "heuristic.h"
/*Option de sortie et debug*/
#define DEBUG_MODE false
#define DEBUG_MODE true
#define DISPLAY_ALL false // each iteration
......@@ -44,7 +44,7 @@ double c_decay;
bool stop_rollout;
int c_mode = 0; // 1: xc with decay; 0 :
int aggregation; //0: Lmax, 1: diminishing return
bool lb1 = false;
int iteration = 0;
void set_aggregation(int agg)
......@@ -190,6 +190,7 @@ Solution solve(const Instance& data, double c, int timeout)
DFSRollout rollout(data);
rollout.temperature = default_temperature;
rollout.base_temperature = default_temperature;
// root
add_node(node_vector, node_set, 0, -1, 0, -1);
......@@ -199,7 +200,10 @@ Solution solve(const Instance& data, double c, int timeout)
int iteration = 0;
while(upper_bound > 0 && std::chrono::steady_clock::now() < run_until)
{
if(iteration > 0)
exit(1);
// debug_dfs = true;
rollout.verbose = true;
// if(iteration == 190417){
// debug_dfs = true;
// rollout.verbose = true;
......@@ -215,7 +219,7 @@ Solution solve(const Instance& data, double c, int timeout)
(iteration < 10000 && iteration%1000 == 0) || iteration%10000 == 0);
DEBUG = DEBUG_MODE && display_data;
// DEBUG = iteration >= 6500;
// debug_dfs = iteration >= 7063;
// debug_dfs = iteration >= 88;
/*Solution & state for the current iteration*/
Solution sol(&data);
......@@ -287,7 +291,9 @@ Solution solve(const Instance& data, double c, int timeout)
int rollout_tardiness;
if(dfs_mode)
{
int fail = rollout.search(upper_bound, best_depth);
int ub = lb1 ? 1 : upper_bound;
int fail = rollout.search(ub, best_depth);
// std::cout << fail << std::endl;
if(fail > 1){
count_fail++;
......@@ -295,7 +301,7 @@ Solution solve(const Instance& data, double c, int timeout)
}
// finished by a greedy, using the best solution found
// std::cout << "Extend" << std::endl;
rollout.extend_rollout();
rollout.extend_rollout(upper_bound);
rollout_depth = rollout.first_tard_depth;
rollout_tardiness = rollout.get_tardiness();
......@@ -420,7 +426,7 @@ Solution solve(const Instance& data, double c, int timeout)
while(!node_vector[current_node_idx].is_root()){
node_vector[current_node_idx].update(backup_value, sol, depth_reached, added_node);
node_vector[current_node_idx].update(backup_value, rollout_depth, rollout_tardiness, depth_reached, added_node);
current_node_idx = node_vector[current_node_idx].parent_idx;
// update backup
if(aggregation == 1)
......@@ -428,7 +434,7 @@ Solution solve(const Instance& data, double c, int timeout)
backup_value *= decay;
}
}
node_vector[ROOT_IDX].update(backup_value, sol, depth_reached, added_node);
node_vector[ROOT_IDX].update(backup_value, rollout_depth, rollout_tardiness, depth_reached, added_node);
//displayed statistics
......@@ -512,14 +518,16 @@ int expand(const State& s, std::vector<Node>& node_vector, SparseSet& node_set,
int end_date = start_date + s.data->duration(actions[i]);
if(end_date > s.lst(actions[i])){ // Don't expand if one child is late
added_nodes = 0;
break;
}
// Check precedences between siblings
bool precedence = false;
for(size_t j = 0; j < actions.size(); ++j){
if(end_date + s.data->distance(actions[i], actions[j]) > s.lst(actions[j]))
if(s.data->component(actions[i] != s.data->component(actions[j])) && end_date + s.data->distance(actions[i], actions[j]) > s.lst(actions[j]))
{
std::cout <<"precedence : " << actions[j] << "<<" << actions[i]<< std::endl;
precedence = true;
break;
}
......@@ -745,7 +753,7 @@ void delete_node(std::vector<Node>& node_vector, SparseSet& node_idx_set, int no
do
{
Node& current(node_vector[current_node_idx]);
count_node++;
// if(DEBUG){
// std::cerr << current << std::endl;
// }
......@@ -753,7 +761,7 @@ void delete_node(std::vector<Node>& node_vector, SparseSet& node_idx_set, int no
to_delete.push_back(current_node_idx);
if(!current.is_root() && node_vector[current.parent_idx].children_idxs.size() == 1){ //if the parent has only 1 child, delete it
current_node_idx = current.parent_idx;
current_node_idx = current.parent_idx;
}else{
if(!current.is_root())
{
......@@ -810,27 +818,6 @@ void delete_node(std::vector<Node>& node_vector, SparseSet& node_idx_set, int no
for(auto& node_idx : to_delete)
{
node_idx_set.remove_back(node_idx);
// if(open_nodes){
// if(node_vector[node_idx].iter_open >= 0)
// {