Recuit simulé ajout de remove et insert dépendant de la progression du recuit + autoriser le remove à couter quedalle au début puis un max et de même pour les violation d'intervales (pour l'instant une seule violation autorisée et compatibilisée à la detection)

This commit is contained in:
tom
2026-06-04 21:59:36 +02:00
parent 4fc8a7be89
commit 3c94d56120
10 changed files with 515 additions and 356 deletions
@@ -1,5 +1,7 @@
#include "SolutionPoolManager.hpp"
#include <iterator>
#include <unordered_map>
#include <vector>
namespace solverlib {
std::vector<TrackPlan> SolutionPoolManager::getTrackPlansFromSolution(SASolution& sol, bool withTrash)
@@ -10,14 +12,17 @@ namespace solverlib {
//id plan = id voie
std::vector<TrackPlan> plans;
plans.resize(STFMockInstance::tracks.size());
std::unordered_map<unsigned int, std::vector<std::pair<unsigned short, Decision>>> decisionsOnMachines;
std::vector<std::set<unsigned int>> machineIdsFromTrackId(STFMockInstance::tracks.size());
for(auto& dec : sol.decisions)
{
if(!dec.second.excluded)
{
plans[dec.second.voie].source = sol.source;
plans[dec.second.voie].isTrash = false;
plans[dec.second.voie].track = dec.second.voie;
plans[dec.second.voie].schedule[dec.first] = dec.second;
decisionsOnMachines[dec.second.empV].push_back({dec.first, dec.second});
machineIdsFromTrackId[dec.second.voie].insert(dec.second.empV);
}
else if(withTrash) {
TrackPlan trashTrack;
@@ -37,10 +42,28 @@ namespace solverlib {
{
if(!plan.schedule.empty())
{
plan.mock = sol.mock;
plan.source = sol.source;
plan.evaluate();
trackPlans.push_back(plan);
bool feasible = true;
if(!sol.penalty.isFeasible())
{
for(auto& machine : machineIdsFromTrackId[plan.track])
{
std::sort(decisionsOnMachines[machine].begin(), decisionsOnMachines[machine].end(), [&](auto& el, auto& el2){
return el.second.lastCreneau.first < el2.second.lastCreneau.first;
});
feasible = checkSequence(decisionsOnMachines[machine], plan.track);
if(!feasible)
break;
}
}
if(feasible)
{
plan.mock = sol.mock;
plan.source = sol.source;
plan.evaluate();
trackPlans.push_back(plan);
}
}
}
@@ -56,11 +79,13 @@ namespace solverlib {
trackPlans.reserve(STFMockInstance::tracks.size() * pool.size() + 1);
while(!pool.empty())
{
auto& sol = pool.back();
auto sol = pool.back();
//id plan = id voie
std::vector<TrackPlan> plans;
plans.resize(STFMockInstance::tracks.size());
std::unordered_map<unsigned int, std::vector<std::pair<unsigned short, Decision>>> decisionsOnMachines;
std::vector<std::set<unsigned int>> machineIdsFromTrackId(STFMockInstance::tracks.size());
for(auto& dec : sol.decisions)
{
if(!dec.second.excluded)
@@ -68,22 +93,46 @@ namespace solverlib {
plans[dec.second.voie].isTrash = false;
plans[dec.second.voie].track = dec.second.voie;
plans[dec.second.voie].schedule[dec.first] = dec.second;
decisionsOnMachines[dec.second.empV].push_back({dec.first, dec.second});
machineIdsFromTrackId[dec.second.voie].insert(dec.second.empV);
}
}
for(auto& plan : plans)
{
if(!plan.schedule.empty())
{
plan.mock = sol.mock;
plan.source = sol.source;
plan.evaluate();
auto inserted = uniqueSchedules.insert(plan);
if(!inserted.second)
bool feasible = true;
if(!sol.penalty.isFeasible())
{
for(auto& machine : machineIdsFromTrackId[plan.track])
{
std::sort(decisionsOnMachines[machine].begin(), decisionsOnMachines[machine].end(), [&](auto& el, auto& el2){
return el.second.lastCreneau.first < el2.second.lastCreneau.first;
});
feasible = checkSequence(decisionsOnMachines[machine], plan.track);
if(!feasible)
break;
}
}
if(feasible)
{
plan.mock = sol.mock;
plan.source = sol.source;
plan.evaluate();
auto inserted = uniqueSchedules.insert(plan);
if(!inserted.second)
{
countD++;
}
}
else {
countD++;
}
}
}
pool.pop_back();
}
std::move(uniqueSchedules.begin(), uniqueSchedules.end(), std::back_inserter(trackPlans));
@@ -104,12 +153,31 @@ namespace solverlib {
auto nbplan = trackPlans.size();
loggerlib::Logger::systemNotify(loggerlib::LOGGER_PROGRESS, "Removed " + std::to_string(countD) + " non-unique track schedules");
loggerlib::Logger::systemNotify(loggerlib::LOGGER_PROGRESS, "Removed " + std::to_string(countD) + " non-unique or non-feasible track schedules");
loggerlib::Logger::systemNotify(loggerlib::LOGGER_PROGRESS, "Total track plans " + std::to_string(nbplan));
return trackPlans;
}
bool SolutionPoolManager::checkSequence(const std::vector<std::pair<unsigned short, Decision>>& jobsDec, unsigned int machine)
{
auto machineDisp = STFMockInstance::machines[machine]->getDispo();
unsigned short minBegin = machineDisp.getDebut().getRelativeDate();
std::vector<std::pair<unsigned short, Decision>> res;
for(auto& jobDec : jobsDec)
{
auto matchWithMachine = CreneauHoraire::checkSlotsCompatibility(jobDec.second.timeslotGraphSplited, machineDisp).second;
minBegin = std::max(minBegin, matchWithMachine.first);
auto newJobDec = jobDec;
unsigned int duration = !jobDec.second.rejected ? STFMockInstance::jobs[jobDec.first]->getDuree() : STFMockInstance::jobs[jobDec.first]->getDureeDiag();
newJobDec.second.lastCreneau = {minBegin, minBegin + duration};
if(minBegin + duration > matchWithMachine.first + matchWithMachine.second)
return false;
minBegin = minBegin + duration;
}
return true;
}
void SolutionPoolManager::provide(std::vector<SASolution>&& solutions)
{
std::move(solutions.begin(), solutions.end(), std::back_inserter(pool));