#include "coptimizer.h" #include "../instance/cinstance.h" #include "../instance/cinstancereduite.h" #include "cgraphe.h" #include "../tuning.h" #include "../instance/indices.h" #include "../filtreAval/filtreAval.h" #include #include #include #include #include #include #include #include "DA.h" using std::vector; using namespace std; COptimizer::COptimizer() { } COptimizer::~COptimizer() { } struct PredAffichePlanDeProduction { vector * m_plans ; PredAffichePlanDeProduction( vector * plans ) { m_plans = plans; } void operator()(CGraphe * g) { std::cout << *(g->m_plan) << std::endl; } } ; struct PredAjoutColonne { int m_passe ; vector * m_plans ; DualAscent * m_da ; PredAjoutColonne( int passe, vector * plans, DualAscent * da ) { m_passe = passe ; m_plans = plans; m_da=da; } void operator()(CGraphe * g) { #ifdef OPTION_REJETE_COUTS_REDUITS_POSITIFS if (m_passe==1 or g->m_plan->m_cout_reduit - CGraphe::m_u[H()+g->m_i]<=0) { #endif m_plans->push_back(g->m_plan); m_da->ajoutcolonne(g->m_plan); g->accepte_colonne(); #ifdef OPTION_REJETE_COUTS_REDUITS_POSITIFS } #endif } } ; void produit_solution( DualAscent & da, vector & graphes, time_t & maintenant, int passes = -1 ); void COptimizer::start() { time_t maintenant ; #ifdef _RELEASE_ time_t pourcentage_de_temps_1 = 0 ; time_t pourcentage_de_temps_2 = 0 ; #endif #ifndef LIMIT_PASSES time_t duree_cplex = 5 ; time_t duree_filtre_aval = 10 ; #endif time_t heure_debut_passe = 0 ; time_t duree_passe_precedente = 0 ; time_t delta_duree_passe = 0 ; vector graphes; vector plans_de_production ; DualAscent da( CInstanceReduite::getEDEM_min(), I() ); // vecteur des coûts réduits par semaine puis des centrales vector u( H()+I(), 0 ); vector lambda(u); /** * CREATION DES GRAPHES */ #ifdef VERBOSE_TEMPS time_t debut_optimization = time(NULL); #endif /* pour chaque centrale, créer un graphe */ for (powerplants2_t i=(powerplants2_t) 0; i 0) { // calcul fait dans DA.cpp char id[20]; sprintf(id, "passe n°%d", passes); #ifdef VERBOSE_PASSES std::cout << " appel au dual ascent" << std::endl ; #endif da.boucle(u, lambda, rechercheBorneSup, id); #ifdef VERBOSE_TEMPS std::cout << "time(DA) " << "\t" << time(NULL) - CInstance::params().getTimeStart() << "\t" << time(NULL) - maintenant << std::endl; maintenant = time(NULL); #endif } /* passage des variables duales aux graphes */ #ifdef VERBOSE_PASSES std::cout << " préparation viterbi" << std::endl ; #endif CGraphe::prepare_viterbi(&u) ; /* générer les nouvelles colonnes pour chaque centrale */ #ifdef VERBOSE_PASSES std::cout << " génération des colonnes" << std::endl ; #endif std::for_each( graphes.begin(), graphes.end(), CGraphe::creer_colonnes ); #ifdef VERBOSE_TEMPS std::cout << "time(colonnes) " << "\t" << time(NULL) - CInstance::params().getTimeStart() << "\t" << time(NULL) - maintenant << std::endl; maintenant = time(NULL); #endif #ifdef VERBOSE_PLANS PredAffichePlanDeProduction affichePlan(&plans_de_production); std::for_each( graphes.begin(), graphes.end(), affichePlan ); #endif #ifdef VERBOSE_PASSES std::cout << " ajout des nouvelles colonnes" << std::endl ; #endif /* ajout des colonnes à la liste des colonnes */ PredAjoutColonne ajoute(passes, &plans_de_production, &da); std::for_each( graphes.begin(), graphes.end(), ajoute ); #ifdef PRODUIT_SOLUTION_A_CHAQUE_PASSE produit_solution(da, graphes, maintenant, passes); #endif /* gestion du temps */ maintenant = time(NULL); if (passes>1) delta_duree_passe = std::max( maintenant - heure_debut_passe - duree_passe_precedente, delta_duree_passe ); duree_passe_precedente = maintenant - heure_debut_passe ; } produit_solution(da, graphes, maintenant); // destruction des graphes std::for_each(graphes.begin(), graphes.end(), CGraphe::detruit); } /** * * Production d'une solution * */ void produit_solution( DualAscent & da, vector & graphes, time_t & maintenant, int passes ) { /** * APPEL A CPLEX */ Cplex cplex(da); #ifndef NO_CPLEX vector x = cplex.resolution(); #else vector x(I()); for (size_t i=0; i<(unsigned)I(); i++) x[i] = Clique::s_plans.size()-I()+i ; #endif #ifdef VERBOSE_TEMPS std::cout << "time(cplex)" << "\t" << time(NULL) - CInstance::params().getTimeStart() << "\t" << time(NULL) - maintenant << "\tnb.plans\t" << Clique::s_plans.size() << "\tt.steps\t" << T() << "\tcliques\t" << cplex.m_cliques.size() << std::endl; maintenant = time(NULL); #endif /** * appel au filtre aval */ std::ostringstream oss; if (passes!=-1) oss << "_passe_" << printIntSurQuatreChiffres(passes) ; FiltreAval filtreAval(x); ofstream ofs((CInstance::params().getSolutionName()+oss.str()).c_str()); filtreAval.printOutput(ofs, CInstance::params().getTimeStart()); ofs.close(); #ifdef VERBOSE_TEMPS std::cout << "time(f.aval) " << "\t" << time(NULL) - CInstance::params().getTimeStart() << "\t" << time(NULL) - maintenant << std::endl; maintenant = time(NULL); #endif }