Commit 9f3c3480 authored by ehebrard's avatar ehebrard
Browse files

merge

parents f13f15c4 91ed89ba
......@@ -17,6 +17,7 @@ set(SRCS
src/mcts.cpp
src/heuristic.cpp
src/SparseSet.cpp
src/DFSRollout.cpp
)
......@@ -26,12 +27,14 @@ AUX_SOURCE_DIRECTORY(src/tclap TCLAP)
set(HEADERS
#src/policy-gradient.h
src/test.h
src/instance.h
src/solution.h
src/options.h
src/mcts.h
src/heuristic.h
src/SparseSet.hpp
src/DFSRollout.h
${TCLAP}
)
......
This diff is collapsed.
......@@ -3,8 +3,8 @@
#define __DFSROLLOUT_H
// #define DEBUG
// #define STATS
// #define DEBUG_DFS_ROLLOUT
#include <random>
......@@ -19,16 +19,23 @@ using namespace std;
#define THETA_3 0.148330024098084
#define THETA_4 0.023875557385973
extern bool debug_dfs;
extern double ALPHA;
extern int FAIL_LIMIT;
class DFSRollout {
public:
DFSRollout(Instance& data);
DFSRollout(const Instance& data);
void random_walk();
void greedy_first();
void greedy_best();
void greedy_stochastic();
void search(const int ub);
void greedy_stochastic(int upper_bound=std::numeric_limits<int>::infinity());
void extend_rollout();
// return the number of fail before stop
int search(int ub, int ub_depth=0);
void do_op(const int op);
void undo();
......@@ -43,18 +50,22 @@ public:
// the total tour_length of the
int train_length{0};
vector<int> best_sequence;
vector<int> best_solution;
int best_tardiness{numeric_limits<int>::max()};
int tardi_depth;
int best_depth() { return best_sequence.size(); }
void verify(const char* msg, const int offset=0);
// params
double temperature{0.0005};
double sigmoid_slope{0.001};
bool verbose{true};
bool verified{true};
double temperature{0.01};
double sigmoid_slope{0.0005};
bool verbose{false};
bool verified{false};
bool randomized{true};
bool auto_limit{true};
int restart_base{0};
......@@ -79,7 +90,8 @@ public:
private:
Instance& data;
const Instance& data;
int start_tour_length{0};
int start_train_length{0};
......@@ -98,6 +110,7 @@ private:
// the current period, for every component
vector<int> period;
vector<int> start_period;
// the latest operation, for every component
......@@ -107,8 +120,18 @@ private:
// the number of operations in the period, for every component
vector<int> num_operation;
vector<int> start_num_operation;
vector<int> best_sequence;
// Copy in order to save a state
vector<int> _num_operation;
vector<int> _prev_operation;
vector<int> _period;
vector<int> _start;
int _tour_length;
int _train_length;
int _tardi_depth;
vector<int> best_seq_max_tardiness;
// for every operation, its start time if scheduled, or a lower bound on it if it is a possible actions choice
vector<int> start;
......@@ -133,9 +156,6 @@ private:
std::mt19937 random_generator;
int get_tardiness() const {
assert(maximum_positive_tardiness.size() > 0);
return maximum_positive_tardiness.back();
}
......@@ -170,8 +190,10 @@ private:
int get_previous_operations(const int op) const;
void verify(const char* msg, const int offset=0);
// void verify(const char* msg, const int offset=0);
void save_state();
void restore_state();
};
......
......@@ -244,6 +244,8 @@ vector<double> get_distribution(const State& s, const std::vector<int>& actions,
return proba; // compiler should optimize this
}
bool WITHOUT_TARDINESS = false;
double fitness_func(const State& s, int action)
{
// distance return 0 if last_task < 0
......@@ -253,11 +255,15 @@ double fitness_func(const State& s, int action)
{
dist = 0;
}
double lambda1 = (double)(s.lst(action) - max(s.data->release_date(action), s.date - s.tardiness + dist)) / s.data->max_slack;
double lambda2 = (double)(max(s.data->release_date(action) - (s.date - s.tardiness), dist)) / s.data->max_dist;
double lambda3 = 1 - (double)s.data->trolley_length(action) / s.data->T_max;
double lambda4 = s.data->is_pickup(action) ? 1 : 0;
double lambda3 = 1 - (double)s.data->trolley_length(action) / s.data->T_max;
double lambda4 = s.data->is_pickup(action) ? 1 : 0;
if(WITHOUT_TARDINESS){
lambda1 = (double)(s.lst(action) - max(s.data->release_date(action), s.date + dist)) / s.data->max_slack;
lambda2 = (double)(max(s.data->release_date(action) - (s.date), dist)) / s.data->max_dist;
}
......
......@@ -13,6 +13,7 @@
extern double default_temperature;
extern bool DEBUG_H;
extern bool WITHOUT_TARDINESS;
void set_default_temperature(double temperature);
/**
......
......@@ -20,7 +20,7 @@
#include "options.h"
#include "mcts.h"
#include "heuristic.h"
#include "dfs.h"
#include "DFSRollout.h"
#include "test.h"
......@@ -237,11 +237,16 @@ int main(int argc, char **argv){
set_c_decay(opt.c_decay);
set_stop_rollout(!opt.complete_rollout);
//dfs rollouts parameter
FAIL_LIMIT = opt.fail_limit;
ALPHA = opt.alpha;
Solution sol = solve(data[0], opt.c, opt.time);
if(!sol.is_valid())
{
std::cout << "Solution is not valid" << std::endl;
}
// if(!sol.is_valid())
// {
// std::cout << "Solution is not valid" << std::endl;
// }
}
else if(opt.heuristic)
{
......@@ -250,20 +255,36 @@ int main(int argc, char **argv){
std::cout << sol.lmax() << std::endl;
}
else{
set_default_temperature(0.01);
Solution sol(&data[0]);
State s(&data[0]);
std::vector<int> hint{};
for(auto t : hint){
sol.append(t);
s.update(t);
}
dfs(sol, s);
// test_sample(data[0], opt.stat);
// solve_by_sample(data[0], opt.stat);
// range_children(data[0], opt.stat);
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;
}
// std::cout << "Fin" << std::endl;
......
......@@ -12,7 +12,7 @@
#include "mcts.h"
#include "heuristic.h"
#include "dfs.h"
#include "DFSRollout.h"
/*Option de sortie et debug*/
#define DEBUG_MODE false
......@@ -30,6 +30,8 @@
#define ROOT_IDX 0
// int ROOT_IDX = 0;
bool DEBUG = DEBUG_MODE;
std::vector<int> node_per_depth; // used to print the width of the tree
......@@ -79,8 +81,50 @@ int count_iter_sim = 0; //number of iterations between two displays
double mean_lmax_sol_iter = 0.0;
double mean_depth_sol_iter = 0.0;
double mean_backup_iter = 0.0; // mean backup at root nodes
double mean_fail_iter = 0.0; // mean fail when dfs rollout
int count_fail = 0;
void commit(std::vector<Node>& node_vector, SparseSet& node_set)
{
// Commit !
Node* current = &node_vector[ROOT_IDX];
while(current->children_idxs.size() == 1)
{
current = &node_vector[current->children_idxs[0]];
}
std::cerr << "-- COMMIT --" << current->depth << std::endl;
std::cout << "-- COMMIT --" << current->depth << std::endl;
// Get the best child
int better_child_idx = 0;
double better_Q = std::numeric_limits<float>::infinity();
for(auto child_idx : current->children_idxs)
{
if(better_Q > node_vector[child_idx].get_Q())
{
better_Q = node_vector[child_idx].get_Q();
better_child_idx = child_idx;
}
}
// Copy the children for deleting ?
std::vector<int> children_idxs_copy(current->children_idxs);
for(auto child_idx : children_idxs_copy)
{
if(child_idx != better_child_idx)
{
delete_node(node_vector, node_set, child_idx);
}
}
// ROOT_IDX = better_child_idx;
// std::cerr << "Root is " << node_vector[ROOT_IDX] << std::endl;
}
int n_balance = 0;
double balance = 0;
/**
Main function, run the algorithm on the instance in data
@param data : the instance to solve
......@@ -95,11 +139,12 @@ Solution solve(const Instance& data, double c, int timeout)
auto run_until = begin_time + std::chrono::seconds(timeout);
double t = (double)(timeout)*2/(data.nb_tasks);
double cumul = t;
auto step_timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds((int)(t*1000));
// Overall stats
int best_iter_lmax = 0; //for lmax
int best_depth = std::numeric_limits<std::int32_t>::min();
int best_iter_depth = 0;
......@@ -107,6 +152,7 @@ Solution solve(const Instance& data, double c, int timeout)
Solution best_sol(&data);
build(best_sol, /*STOP=*/false);
int upper_bound = best_sol.lmax();
int best_depth = best_sol.first_tardiness();
double decay;
/* Compute the decay for the diminishing return */
......@@ -120,7 +166,7 @@ Solution solve(const Instance& data, double c, int timeout)
}
std::cout << "decay:\t\t" << decay << std::endl;
std::cout << "Upper bound : " << upper_bound << std::endl;
std::cout << "Upper bound : " << upper_bound << " / " << best_depth<< std::endl;
//////////////////
std::cout <<
......@@ -143,14 +189,18 @@ Solution solve(const Instance& data, double c, int timeout)
SparseSet node_set(MAX_NODE);
node_vector.reserve(MAX_NODE);
DFSRollout rollout(data);
rollout.temperature = default_temperature;
// root
add_node(node_vector, node_set, 0, -1, 0, -1);
int& tree_depth = node_vector[ROOT_IDX].max_depth_subtree; // ref on the tree depth
int iteration = 0;
while(best_sol.lmax() > 0 && std::chrono::steady_clock::now() < run_until)
while(upper_bound > 0 && std::chrono::steady_clock::now() < run_until)
{
rollout.clear();
iteration++;
iter_count_display++;
......@@ -158,6 +208,8 @@ Solution solve(const Instance& data, double c, int timeout)
(iteration < 10 || (iteration < 100 && iteration%10 == 0) || (iteration < 1000 && iteration%100 == 0) ||
(iteration < 10000 && iteration%1000 == 0) || iteration%10000 == 0);
DEBUG = DEBUG_MODE && display_data;
// DEBUG = iteration >= 6500;
// debug_dfs = iteration >= 7063;
/*Solution & state for the current iteration*/
Solution sol(&data);
......@@ -177,7 +229,7 @@ Solution solve(const Instance& data, double c, int timeout)
///////////////////////////////////////
////////////// Selection //////////////
///////////////////////////////////////
int current_node_idx = select(node_vector, sol, s, c, tree_depth);
int current_node_idx = select(rollout, node_vector, sol, s, c, tree_depth);
if( DEBUG)
......@@ -218,91 +270,150 @@ Solution solve(const Instance& data, double c, int timeout)
node_vector[current_node_idx].max_depth_subtree += 1; //successed expand
int depth_reached = node_vector[current_node_idx].max_depth_subtree;
int _upper = upper_bound;
if( DEBUG)
std::cerr << "-- Simulation --" << std::endl;
///////////////////////////////
////////// SIMULATION /////////
///////////////////////////////
count_iter_sim++;
int rollout_depth;
int rollout_tardiness;
if(dfs_mode)
{
int fail = rollout.search(upper_bound, best_depth);
// std::cout << fail << std::endl;
if(fail > 1){
count_fail++;
mean_fail_iter = mean_fail_iter + (fail - mean_fail_iter)/count_fail;
}
// finished by a greedy, using the best solution found
rollout.extend_rollout();
rollout_depth = rollout.tardi_depth;
rollout_tardiness = rollout.get_tardiness();
if(stop_rollout){
// build(sol, s, upper_bound);
build(sol, s, true);
}else{
build(sol, s, /*stop=*/false);
// if(stop_rollout){
// // build(sol, s, upper_bound);
// build(sol, s, true);
// }else{
// build(sol, s, /*stop=*/false);
// }
// rollout_depth = sol.first_tardiness();
// rollout_tardiness = sol.lmax();
rollout.greedy_stochastic(upper_bound);
rollout_depth = rollout.tardi_depth;
rollout_tardiness = rollout.get_tardiness();
}
// compute backup value
double backup_value = 0;
if(aggregation == 0)
if(rollout_depth > best_depth)
{
backup_value = sol.lmax();
best_depth = rollout_depth;
best_iter_depth = iteration;
// best_sol.copy(sol);
}
}else if(aggregation == 1){
// start from the last task, to current nodes
for(int i = sol.size()-1; i >= 0 && sol.sequence[i] != node_vector[current_node_idx].action; --i)
{
int marginal_incr = sol.max_tardiness(i) - sol.max_tardiness(i-1);
backup_value = marginal_incr + decay*backup_value;
if(rollout_tardiness < upper_bound)
{
upper_bound = rollout_tardiness;
best_iter_lmax = iteration;
if(upper_bound == 0){
rollout.verify("Solution");
}
}
}
// std::cout << sol.lmax() <<"/" << sol.first_tardiness() <<std::endl;
// std::cout << rollout.get_tardiness() <<"/" << rollout.tardi_depth << std::endl;
bool new_nodes = false;
bool intensification = false;
if(sol.first_tardiness() > best_depth)
// compute backup value
double backup_value = 0;
if(aggregation == 0)
{
best_depth = sol.first_tardiness();
best_iter_depth = iteration;
best_sol.copy(sol);
}
backup_value = rollout_tardiness;
if(sol.lmax() < upper_bound)
{
upper_bound = sol.lmax();
best_iter_lmax = iteration;
// best_sol.copy(sol);
}
if(intensification && sol.lmax() > 0){
}else if(aggregation == 1){
// start from the last task, to current nodes
// if(dfs_mode)
// {
// // Quand lancer un dfs ?
// if(true)
// if(DEBUG){
// std::cout << rollout_tardiness <<", "<< rollout.best_sequence.size() << std::endl;
// for(auto v : rollout.best_seq_max_tardiness)
// std::cout << " " << v << std::endl;
// }
double gamma = 1;
for(int i = node_vector[current_node_idx].depth; i < rollout.sequence.size() && i+2 < rollout.maximum_tardiness.size(); ++i){
int marginal_incr = rollout.maximum_tardiness[i+2] - rollout.maximum_tardiness[i+1];
// std::cout << marginal_incr << " ";
backup_value += gamma * marginal_incr;
gamma *= decay;
}
// std::cout << std::endl;
// for(auto elt : rollout.maximum_tardiness)
// {
// std::cout << elt << " ";
// }
// std::cout << std::endl;
// }else{
// for(int i = sol.size()-1; i >= 0 && sol.sequence[i] != node_vector[current_node_idx].action; --i)
// {
// Solution sol_bis(sol);
// State s_bis(s);
// if(sol_bis.lmax() > 0)
// {
// while(sol_bis.lmax() > 0)
// {
// sol_bis.pop_back();
// s_bis.rewind(sol_bis);
// }
// }
// dfs(sol_bis, s_bis);
// // std::cout << " / " << sol.first_tardiness() <<std::endl;
// }
// int marginal_incr = sol.max_tardiness(i) - sol.max_tardiness(i-1);
// backup_value = marginal_incr + decay*backup_value;
// }
// }
}
// if(iteration == 1)
// exit(1);
// tricks for displaying the mean tardiness for each node
// bool start = false;
// for(auto elt : rollout.sequence){
// if(start){
// sol.append(elt);
// }
// if(elt == node_vector[current_node_idx].action){
// start = true;
// }
// }
// // for(int i = 0; i < rollout.sequence.size(); ++i)
// // {
// // std::cout << rollout.sequence[i] << "/" << sol.sequence[i] << std::endl;
// // }
// rollout.clear();
// for(int i = 0; i < sol.size(); ++i)
// {
// rollout.do_op(sol.sequence[i]);
// if(sol.sequence[i] == node_vector[current_node_idx].action){
// break;
// }
// }
// rollout.greedy_stochastic(_upper);
// std::cerr << "greed=" << rollout.get_tardiness() <<", depth=" << rollout.tardi_depth << std::endl;
// balance = balance + ((rollout_tardiness - rollout.get_tardiness()) - balance)/(++n_balance);
////////////////////////////
///////// BACKUP /////////
////////////////////////////
if(DEBUG)
{
std::cerr << " -> lmax = " << sol.lmax() << ", depth = " << sol.first_tardiness() << std::endl;
std::cerr << " -> lmax = " << rollout_tardiness << ", depth = " << rollout_depth << std::endl;
std::cerr << " => val = " << backup_value << std::endl;
std::cerr << "from nodes : " << node_vector[current_node_idx] << std::endl;
std::cerr << "-- Backup phase --" << std::endl;
}
while(!node_vector[current_node_idx].is_root()){
node_vector[current_node_idx].update(backup_value, sol, depth_reached, added_node);
current_node_idx = node_vector[current_node_idx].parent_idx;
// update backup
if(aggregation == 0)
if(aggregation == 1)
{
backup_value *= decay;
}
......@@ -311,8 +422,8 @@ Solution solve(const Instance& data, double c, int timeout)
//displayed statistics
mean_lmax_sol_iter = mean_lmax_sol_iter + (sol.lmax() - mean_lmax_sol_iter)/count_iter_sim;
mean_depth_sol_iter = mean_depth_sol_iter + (sol.first_tardiness() - mean_depth_sol_iter)/count_iter_sim;
mean_lmax_sol_iter = mean_lmax_sol_iter + (rollout_tardiness - mean_lmax_sol_iter)/count_iter_sim;
mean_depth_sol_iter = mean_depth_sol_iter + (rollout_depth - mean_depth_sol_iter)/count_iter_sim;
mean_backup_iter = mean_backup_iter + (backup_value -mean_backup_iter )/count_iter_sim;// backup value from the root
}
......@@ -324,7 +435,7 @@ Solution solve(const Instance& data, double c, int timeout)
std::cout <<
std::setw(8) << std::left << resolutionTime.count()
<< std::setw(12) << std::left << iteration
<< std::setw(15) << std::left << best_sol.lmax()
<< std::setw(15) << std::left << upper_bound
<< std::setw(12) << std::left << best_depth
<< std::setw(18) << std::left << mean_depth_iter
<< std::setw(12) << std::left << mean_lmax_sol_iter
......@@ -334,7 +445,9 @@ Solution solve(const Instance& data, double c, int timeout)
<< std::setw(15) << std::left << nb_node_deleted
<< std::setw(12) << std::left << node_vector[ROOT_IDX].max_depth_subtree
<< std::setw(12) << std::left << max_tree_depth_reached
<< std::endl;
<< mean_fail_iter <<"/" << count_fail
</