#include "coptimizer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cdualcplexscenario.h" #include "cbendercplex.h" using std::vector; using namespace std; COptimizer::COptimizer( bool multithreading ) { multithread = multithreading ; pourcentage_de_temps_1 = 0 ; pourcentage_de_temps_2 = 0 ; duree_cplex = 5 ; heure_debut_passe = 0 ; duree_passe_precedente = 0 ; delta_duree_passe = 0 ; coeff_recharges = 206613465.3984422 ; coeff_scenarios = 26000 ; if (multithreading) { coeff_selecteur = 540 ; } else { coeff_selecteur = 298 ; } prev_selecteur = (double) I() * T() / coeff_selecteur * 1000000.0 / (double) CLOCKS_PER_SEC ; prev_recharges = (double) I() * T() * S() * S() / coeff_recharges * 1000000.0 / (double) CLOCKS_PER_SEC ; prev_scenarios = (double) (I() + J()) * T() * S() / coeff_scenarios * 1000000.0 / (double) CLOCKS_PER_SEC ; duree_filtre_aval = std::min(3 * (double)CInstance::params().getTimeLimit() / 4, prev_selecteur + prev_recharges + prev_scenarios) ; _nbTotalIter = 0; nb_colonnes_cout_non_positif = 0 ; nb_rejets_couts_positifs = 0 ; nb_rejets_existants = 0 ; m_cout_solution = (euros) INFINI ; m_prochaine_suppression = 2 * (H() + I()) ; #ifdef VERBOSE_CPLEX_INTERNAL m_cplex_internal_silent = false ; #else m_cplex_internal_silent = true ; #endif #ifdef VERBOSE_SOLUTION_STATUS m_duals_silent = false ; #else m_duals_silent = true ; #endif #ifdef WRITE_CPLEX_FILE m_cplex_writeToFile = true ; #else m_cplex_writeToFile = false ; #endif } COptimizer::~COptimizer() { if (m_bender!=nullptr) delete m_bender; } void verbose_rejet_plan_existant( CGraphe * g); void verbose_rejet_cout_positif( CGraphe * g); /** * calcul des nouvelles colonnes réparti sur plusieurs threads * ( 1 thread par cpu disponible ) */ // structure partagée par les différents threads struct CIterThreadGraph { vector graphes ; // liste des graphes à traiter vector::iterator it ; // itérateur sur le prochain graphe à traiter pthread_mutex_t lock_it ; // mutex pour bloquer l'itérateur quand un thread "se sert" CIterThreadGraph( vector & _graphes ) : graphes(_graphes) { it = graphes.begin(); pthread_mutex_init(&lock_it, NULL); } }; // fonction "start" d'un thread void * threaded_creer_colonnes( void * /* (CIterThreadGraph *) */ iter_graphes ) { CIterThreadGraph * itg = (CIterThreadGraph *) iter_graphes ; // itérateur sur les graphes à traiter while (true) { CGraphe * graphe = NULL ; // recherche du prochain graphe à traiter pthread_mutex_lock( & itg->lock_it ); if ( itg->it != itg->graphes.end() ) { graphe = * itg->it ; itg->it ++ ; } pthread_mutex_unlock( & itg->lock_it ); // fin du thread s'il n'y a plus de graphes à traiter if (graphe==NULL) break ; // création de colonne s'il y a un graphe à traiter CGraphe::creer_colonnes( graphe ); } return NULL ; } // création de colonnes sur plusieurs threads void COptimizer::creer_colonnes_multithread() { // nombre de cpus int ncpus = sysconf(_SC_NPROCESSORS_CONF); // autant de threads que de cpus vector threads(ncpus); // lancement des différents threads CIterThreadGraph threaded_graphes(graphes) ; for (vector::iterator th=threads.begin(); th!=threads.end(); th++) { pthread_create( &(*th), NULL, threaded_creer_colonnes, (void *) &threaded_graphes ); } // attente de la fin des threads lancés for (vector::iterator th=threads.begin(); th!=threads.end(); th++) { pthread_join( *th, NULL ); } } /** * Algorithme principal de l'optimisation */ void COptimizer::start() { _LBvalue = INFINI ; #ifdef VERBOSE_TEMPS std::cout << "\t" << "Magnitude_I " << I() << std::endl << "\t" << "Magnitude_J " << J() << std::endl << "\t" << "Magnitude_K " << K() << std::endl << "\t" << "Magnitude_T " << T() << std::endl << "\t" << "Magnitude_H " << H() << std::endl << "\t" << "Magnitude_S " << S() << std::endl << std::endl ; std::cout << "Temps pour selecteur + filtre aval :\t" << duree_filtre_aval << std::endl << "Temps pour le sélecteur :\t" << prev_selecteur << std::endl << "Temps pour les recharges :\t" << prev_recharges << std::endl << "Temps pour les scénarios :\t" << prev_scenarios << std::endl << std::endl ; #endif u = u_initial(); /** * CREATION DES GRAPHES */ debut_optimization = time(NULL); /* pour chaque centrale, créer un graphe */ temps1 = clock() ; for (powerplants2_t i; i > dates_ref; vector > recharges_ref; for (powerplants2_t i; i(0)); recharges_ref.push_back(std::vector(0)); for (campaign_t k; k> dates_moy(I(), vector(K(), 0.0)); vector> recharges_moy(I(), vector(K(), 0.0)); /** * un dantzig-wolfe par scénario */ for (scenario_t s; s.vinit(); // calcul des Duales cout << "******************** Génération colonne passe " << m_passe_benders << " scénario " << s << endl; CDualCplexScenario * dw_cplex = generation_colonnes(s, dates_ref, recharges_ref); // ajout d'une coupe au maître cout << "******************** Ajout coupe passe " << m_passe_benders << " scénario " << s << endl; m_bender->ajouteCoupe(s, dw_cplex); // affichages afficher_dates_moyennes_par_scenario_dw(s, dw_cplex); mettre_a_jour_dates_moyennes_globales_dw(dates_moy, dw_cplex); afficher_recharges_moyennes_par_scenario_dw(s, dw_cplex); mettre_a_jour_recharges_moyennes_globales_dw(recharges_moy, dw_cplex); _nbTotalIter++ ; // libération de mémoire CPlan::libere_plans(); delete dw_cplex; } /** * résolution du maître */ m_bender->set_name("bender_" + to_string(m_passe_benders)); double obj = m_bender->resolution(); static int passe = 0; passe ++; changement = false; std::vector> dr = m_bender->get_dates_ref(); std::vector> rr = m_bender->get_recharges_ref(); for (powerplants2_t i; i > dates_ref, vector< vector< kWh > > recharges_ref) { for (scenario_t s; s.v plans = dw_cplex->resolution_entiers(); } } /** * génération de colonnes */ CDualCplexScenario * COptimizer::generation_colonnes(scenario_t s, vector > dates_ref, vector > recharges_ref) { CGraphe::set_recharges_ref(recharges_ref); CGraphe::set_dates_ref(dates_ref); CDualCplexScenario * dualCalc = new CDualCplexScenario(s, m_cplex_internal_silent, m_duals_silent, m_cplex_writeToFile); dualCalc->set_name("b_" + to_string(m_passe_benders) + "_dw_s_" + to_string(s)); dualCalc->set_dates_ref(dates_ref); dualCalc->set_recharges_ref(recharges_ref); dualCalc->ajoute_deltas(); bool premiere_fois = true; strategie_stop = false; m_dw_passes = 0; while (prepare_strategie()) { ++m_dw_passes; /* tant qu'il reste du temps */ verbose_debut_passe(); if (not premiere_fois) { verbose_avant_dual_ascent(); vector new_u = dualCalc->calculeDuals(); // voir DualCalc.cpp double temp = dualCalc->getObjectiveValue() ; // std::cout << "dualCalc->getObjectiveValue() : " << temp << std::endl ; if (_LBvalue >= temp+0.1) // pour le log { _LBvalue = temp; } m_cr = dualCalc->getReducedCosts(); vector vars = dualCalc->getResults(); // std::cout << "coûts réduits donnés par cplex : "; // for (unsigned int i=0; im_id <<",i:" << CPlan::getPlan(i)->m_i << ",x:" << vars[i] << ",cr:" << m_cr[i]; std::cout << std::endl; dualCalc->collecte_duales_14_a_21(); verbose_apres_dual_ascent(new_u); u = new_u; for (CGraphe * g: graphes) { g->collecte_duales_dates(dualCalc); g->collecte_duales_recharges(dualCalc); } //suppression_colonnes(graphes, maintenant); } /* passage des variables duales aux graphes */ verbose_avant_viterbi(); CGraphe::prepare_viterbi(&u, strategie_dual_ascent, strategie_utilise_contraintes_de_cliques) ; /* générer les nouvelles colonnes pour chaque centrale */ verbose_avant_creer_colonnes(); if (multithread) creer_colonnes_multithread() ; else { for (auto g: graphes) CGraphe::creer_colonnes(g); } verbose_apres_creer_colonnes(); // for (unsigned int i=0; istr_couts_arcs(graphes[CPlan::getPlan(i)->m_i]) << std::endl; /* ajout des colonnes à la liste des colonnes */ size_t nbPlansAvantAjouts = CPlan::getNbPlans() ; for (auto g: graphes) ajoute_colonne(g, dualCalc); for (size_t p=nbPlansAvantAjouts; p solution; // produit_solution(graphes, maintenant, solution, true, _nbTotalIter); // /* gestion du temps */ calcule_temps_fin_passe(); premiere_fois = false; } return dualCalc; } void COptimizer::afficher_dates_moyennes_par_scenario_dw(scenario_t s, CDualCplexScenario * dw_cplex) { ///Affichage des dates moyennes suite à DW vector> dates = dw_cplex->getMoyenneDates(); for (powerplants2_t i; i < I(); ++i) { cout << "scenario " << s << " centrale " << i << " dates moyennes : "; for (campaign_t k; k < K(); ++k) { cout << k << ":" << fixed << setw(5) << setprecision(1) << dates[i][k] << " "; } cout << endl; } } void COptimizer::mettre_a_jour_dates_moyennes_globales_dw(vector> & dates_moy, CDualCplexScenario * dw_cplex) { vector> dates = dw_cplex->getMoyenneDates(); for (powerplants2_t i; i < I(); ++i) { for (campaign_t k; k < K(); ++k) { dates_moy[i][k] += dates[i][k] / S(); } } } void COptimizer::afficher_dates_moyennes_et_ref_bender(vector> dates_moy, vector> dr) { cout << "-----------------------------------------------------" << endl; for (powerplants2_t i; i> recharges = dw_cplex->getMoyenneRecharges(); for (powerplants2_t i; i < I(); ++i) { cout << "scenario " << s << " centrale " << i << " recharges moyennes : "; for (campaign_t k; k < K(); ++k) { cout << k << ":" << fixed << setw(5) << setprecision(1) << recharges[i][k] << " "; } cout << endl; } } void COptimizer::mettre_a_jour_recharges_moyennes_globales_dw(vector> & recharges_moy, CDualCplexScenario * dw_cplex) { vector> recharges = dw_cplex->getMoyenneRecharges(); for (powerplants2_t i; i < I(); ++i) { for (campaign_t k; k < K(); ++k) { recharges_moy[i][k] += recharges[i][k] / S(); } } } void COptimizer::afficher_recharges_moyennes_et_ref_bender(vector> recharges_moy, vector> dr) { cout << "-----------------------------------------------------" << endl; for (powerplants2_t i; i solution; // // produit_solution(graphes, maintenant, solution, true); // _FinalValue = produit_meilleure_solution(graphes, maintenant, solution, true).v; } /** * suppression de colonnes à coût réduit positif */ void COptimizer::suppression_colonnes(vector & graphes, time_t & maintenant, CDualCplexScenario * dw_cplex) { /* suppression des colonnes à coût réduit positif */ /*vector cr = m_dualCalc->getReducedCosts(); * for (int p=CPlan::getNbPlans()-1; p>=0; p--) * { * // euros & _cout_reduit = CPlan::getPlan((size_t)p)->m_cout_reduit ; * euros _cout_reduit = CPlan::getPlan((size_t)p)->m_cout_reduit ; * cr[p] = CPlan::getPlan((size_t)p)->recalcule_cout_reduit(); * if ( (euros) -1 < _cout_reduit and cr[p] <= (euros) -1 and _cout_reduit.v != cr[p].v) * cout << "le coût réduit de la colonne du plan " << CPlan::getPlan((size_t)p)->m_id * << " est devenu négatif : (" << cr[p] << " < " << _cout_reduit << ")" << endl; * * if (_cout_reduit <= (euros) 0 and (euros)1 <= cr[p] and _cout_reduit.v != cr[p].v) * cout << "coût réduit devenu positif sur la colonne du plan " << CPlan::getPlan((size_t)p)->m_id << * " (" << cr[p] << " > " << _cout_reduit << ")" << endl; * * _cout_reduit = cr[p] ; } */ if (CPlan::getNbPlans() < m_prochaine_suppression) return ; m_prochaine_suppression = CPlan::getNbPlans() * 5 ; //+ H() + I() ; cout << "Suppression de colonnes. Avant : " << CPlan::getNbPlans() << endl; // calcul d'une solution vector plans; euros ancien_cout_solution = m_cout_solution; produit_solution(graphes, maintenant, plans, false) ; cout << "Suppression de colonnes. Coût solution = " << m_cout_solution << " (ancien cout = "<< ancien_cout_solution << ")" << endl; if (ancien_cout_solution <= m_cout_solution or m_cout_solution<=(euros)0) { return ; } // calcul et enregistrement des nouveaux coûts réduits vector cr = dw_cplex->getReducedCosts(); for (size_t p=0; p < CPlan::getNbPlans() ; p++) CPlan::getPlan(p)->m_cout_reduit = cr[p] ; // suppression de colonnes à coût réduit positif ne faisant pas partie de la solution for (size_t p=CPlan::getNbPlans()-1; (signed) p >= 0 /*and CPlan::getNbPlans()>=(unsigned)H()+I()*/; p--) { if (m_plans_solution.find(CPlan::getPlan(p))!=m_plans_solution.end()) continue ; // if (CPlan::getPlan(p)->recalcule_cout_reduit()>(euros)0) if (CPlan::getPlan(p)->m_cout_reduit>(euros)0) { dw_cplex->retraitColonne(CPlan::getPlan(p)); CPlan::libere_plan(p); } } cout << "Suppression de colonnes. Après : " << CPlan::getNbPlans() << endl; size_t nb_cr_neg = 0 ; for (size_t p=0; p < CPlan::getNbPlans() ; p++) nb_cr_neg += CPlan::getPlan(p)->m_cout_reduit <= (euros)0 ? 1 : 0 ; cout << "Suppression de colonnes. Nb de colonnes à c.r.<=0 : " << nb_cr_neg << endl; m_prochaine_suppression = CPlan::getNbPlans() * 5 ; //+ H() + I() ; } /** * * ajout d'une colonne, sous conditions * */ void COptimizer::ajoute_colonne(CGraphe * g, CDualCplexScenario * dw_cplex) { // // comptage du nombre de colonnes à coup réduit positif // std::cout << " plan centrale " << g->m_i << ",\tc.r.=" << g->m_plan->m_cout_reduit << std::endl; // std::cout << " cout: " << g->m_plan->m_cout // << " V: " << CGraphe::V(g->m_i) // << " somme_ui_prod: " << g->m_plan->m_ui_prod // << " CT14-21: " << CConstraint::getCoutDual_14_a_21(g->m_plan) // << std::endl; // test sur le coût du plan à ajouter if (strategie_rejete_couts_reduits_positifs and strategie_dual_ascent and g->m_plan and g->m_plan->m_cout_reduit > (euros)10 ) { // rejet nb_rejets_couts_positifs ++ ; verbose_rejet_cout_positif(g); return ; } // test sur l'existence du même plan dans la base if (CPlan::retiens_plan(g->m_plan, strategie_accepte_plan_existant)) { if (g->m_plan->m_cout_reduit < (euros) 10) nb_colonnes_cout_non_positif ++ ; dw_cplex->ajoutcolonne(g->m_plan); g->accepte_colonne(); } else { // rejet nb_rejets_existants ++ ; verbose_rejet_plan_existant( g ); g->rejette_colonne(); } } /** * * calcul des u_i initiaux * */ vector & COptimizer::u_initial() const { static vector s_u( H()+I(), (euros_par_kWh) 0 ); #ifndef U_INITIAL_ZERO euros_par_kWh cout_max(0); for (powerplants2_t i=(powerplants2_t) 0; i & graphes, time_t & maintenant, vector & plans, bool sur_disque, int passes ) { #ifndef PRODUIT_SOLUTION_A_CHAQUE_PASSE if (passes!=-1) return (euros) -1; #endif euros cout_solution(-1); /** * APPEL A CPLEX */ temps1 = clock() ; Selecteur * selecteur = NULL ; switch (CInstance::params().getSelecteur()) { case sel_ct : selecteur = new Selecteur_Thermiques; break; } selecteur->setOption( multithread ? CPlexModel::Opportunistic : CPlexModel::None ) ; // selecteur->setOption( CPlexModel::Time, prev_selecteur ) ; vector x ; #ifndef NO_CPLEX try { x = selecteur->resolution(); temps2 = clock() ; _MIPvalue = selecteur->m_cplex.getObjectiveValue() ; // pour le log _nbContraintesClique = selecteur->getNbContraintesDeClique() ; // pour le log #ifdef VERBOSE_TEMPS std::cout << "time(selecteur)" << "\t" << time(NULL) - CInstance::params().getTimeStart() << "\t" << time(NULL) - maintenant << "\tnb.plans\t" << CPlan::getNbPlans() << "\tt.steps\t" << T() << "\tcliques\t" << selecteur->m_cliques.size() << std::endl; std::cout << "clock(selecteur)" << "\t" << (temps2 - temps1) / (double) CLOCKS_PER_SEC << std::endl ; maintenant = time(NULL); #endif delete selecteur; selecteur = NULL ; } catch (CPlexFailed e) { if (selecteur) delete selecteur ; if (passes!=-1) return (euros)-1; else throw (string("Erreur dans l'appel à CPlex : ") + e); } #else x = vector(I()); for (size_t p=0; pm_i ] = p ; #endif /** * libération de mémoire pour le filtre aval */ // for_each(graphes.begin(), graphes.end(), Delete()); /** * appel au filtre aval */ { temps1 = clock() ; std::ostringstream oss; if (passes!=-1) oss << "_passe_" << printIntSurQuatreChiffres(passes) ; FiltreAval * filtreAval = NULL; // try { switch (CInstance::params().getFiltreAval()) { case fa_manuel : filtreAval = new FiltreAval(); break; case fa_cplex : filtreAval = new FiltreAvalCplex(); break; case fa_cplex_reste_libre : filtreAval = new FiltreAvalCplexResteLibre(); break; case fa_cplex_ultime : filtreAval = new FiltreAvalCplexUltime(); break; case fa_cplex_ultime_1passe : filtreAval = new FiltreAvalCplexUltime1Passe(); break; } cout_solution = filtreAval->calcule_solution(x, multithread, prev_recharges); if (CInstance::params().getFiltreAval()==fa_cplex_ultime) _MinFiltreAvalPhase1Value = ((FiltreAvalCplexUltime *)filtreAval)->minPhase1Value() ; // pour le log for (size_t p=0; p::iterator ptp=plans.begin(); ptp!=plans.end(); ptp++) { m_plans_solution.insert(*ptp); } } else if (sur_disque) { x = vector(I()); for (set::iterator itp=m_plans_solution.begin(); itp!=m_plans_solution.end(); itp++) x[ (*itp)->m_i ] = CPlan::findIndex(*itp) ; cout_solution = filtreAval->calcule_solution(x); } if (sur_disque) { ofstream ofs((CInstance::params().getSolutionName()+oss.str()).c_str()); filtreAval->printOutput(ofs, CInstance::params().getTimeStart()); ofs.close(); } #ifdef EXPORTE_PLANS_PAR_SCENARIO if (passes==-1) // dernière passe filtreAval->exportePlans(); #endif /* } catch (...) { if (filtreAval!=NULL) delete filtreAval ; filtreAval = NULL ; throw; }*/ if (filtreAval!=NULL) delete filtreAval; filtreAval = NULL ; temps2 = clock() ; #ifdef VERBOSE_TEMPS std::cout << "time(f.aval) " << "\t" << time(NULL) - CInstance::params().getTimeStart() << "\t" << time(NULL) - maintenant << std::endl; maintenant = time(NULL); std::cout << "clock(f.aval)" << "\t" << (temps2 - temps1) / (double) CLOCKS_PER_SEC << std::endl ; #endif } return cout_solution; } /** * * Production d'une solution avec plusieurs essais sur la partie 1 du filtre aval ultime * */ euros COptimizer::produit_meilleure_solution( vector & graphes, time_t & maintenant, vector & plans, bool sur_disque ) { euros cout_solution(-1); /** * APPEL A CPLEX */ temps1 = clock() ; Selecteur * selecteur = NULL ; switch (CInstance::params().getSelecteur()) { case sel_ct : selecteur = new Selecteur_Thermiques; break; } selecteur->setOption( multithread ? CPlexModel::Opportunistic : CPlexModel::None ) ; selecteur->setOption( CPlexModel::Time, prev_selecteur ) ; vector< vector > x ; try { x = selecteur->populate(); temps2 = clock() ; _MIPvalue = selecteur->m_cplex.getObjectiveValue() ; // pour le log _nbContraintesClique = selecteur->getNbContraintesDeClique() ; // pour le log #ifdef VERBOSE_TEMPS std::cout << "time(selecteur)" << "\t" << time(NULL) - CInstance::params().getTimeStart() << "\t" << time(NULL) - maintenant << "\tnb.plans\t" << CPlan::getNbPlans() << "\tt.steps\t" << T() << "\tcliques\t" << selecteur->m_cliques.size() << std::endl; std::cout << "clock(selecteur)" << "\t" << (temps2 - temps1) / (double) CLOCKS_PER_SEC << std::endl ; maintenant = time(NULL); #endif delete selecteur; selecteur = NULL ; } catch (CPlexFailed e) { if (selecteur) delete selecteur ; throw (string("Erreur dans l'appel à CPlex : ") + e); } /** * libération de mémoire pour le filtre aval */ // for_each(graphes.begin(), graphes.end(), Delete()); /** * appel au filtre aval */ try { temps1 = clock() ; FiltreAvalCplexUltime * filtreAval = new FiltreAvalCplexUltime(); // calcul de la durée autorisée pour la première phase du filtre aval time_t duree_phase_1 = 0 ; if (CInstance::params().getLimitType()==CParams::TIME_LIMIT) duree_phase_1 = CInstance::params().getDeadline() - time(NULL) - prev_scenarios * 2 ; else duree_phase_1 = 3600; duree_phase_1 = std::max( duree_phase_1, (time_t) 1 ) ; cout_solution = filtreAval->calcule_solution(x, duree_phase_1, multithread); _MinFiltreAvalPhase1Value = filtreAval->minPhase1Value() ; // pour le log _FinalValue = (double) cout_solution.v ; // pour le log if (sur_disque) { ofstream ofs(CInstance::params().getSolutionName().c_str()); filtreAval->printOutput(ofs, CInstance::params().getTimeStart()); ofs.close(); } if (filtreAval!=NULL) delete filtreAval; filtreAval = NULL ; temps2 = clock() ; #ifdef VERBOSE_TEMPS std::cout << "time(f.aval) " << "\t" << time(NULL) - CInstance::params().getTimeStart() << "\t" << time(NULL) - maintenant << std::endl; maintenant = time(NULL); std::cout << "clock(f.aval)" << "\t" << (temps2 - temps1) / (double) CLOCKS_PER_SEC << std::endl ; #endif return cout_solution; } catch (CPlexFailed e) { throw string( "Erreur dans le filtre aval, appel à CPlex : ") + e ; } } /** * * CALCULS DES TEMPS et VERBOSITE * */ void COptimizer::calcule_temps_fin_passe() { maintenant = time(NULL); delta_duree_passe = std::max( maintenant - heure_debut_passe - duree_passe_precedente, delta_duree_passe ); duree_passe_precedente = maintenant - heure_debut_passe ; } void verbose_rejet_plan_existant( CGraphe * g) { #ifdef VERBOSE_PLANS_REJETES cout << "rejet du plan " << g->m_plan->m_id << ", centrale " << g->m_i << " - plan existant n°" << CPlan::plan_existant() << ", id:" << CPlan::getPlan(CPlan::plan_existant())->m_id << endl; #endif } void verbose_rejet_cout_positif( CGraphe * g) { #ifdef VERBOSE_PLANS_REJETES cout << "rejet du plan " << g->m_plan->m_id << ", centrale " << g->m_i << " - cout_reduit(" << g->m_plan->m_cout_reduit << ") > 0" << endl; #endif } void COptimizer::verbose_temps_graphes() { fin_creation_graphe = time(NULL); #ifdef VERBOSE_TEMPS std::cout << "time(graphes) " << "\t" << fin_creation_graphe - CInstance::params().getTimeStart() << "\t" << fin_creation_graphe - debut_optimization << std::endl; maintenant = time(NULL); std::cout << "clock(graphes)" << "\t" << (temps2 - temps1) / (double) CLOCKS_PER_SEC << std::endl ; #endif } void COptimizer::verbose_debut_passe() { maintenant = time(NULL); heure_debut_passe = maintenant ; /* calcul des variables duales */ #ifdef VERBOSE_PASSES std::cout << std::endl << "passe n°" << m_dw_passes << (strategie_utilise_contraintes_de_cliques ? " - cliques" : "") << (strategie_dual_ascent ? " - duales" : "") << (strategie_accepte_plan_existant ? " - accepte plans existants" : "") << (strategie_rejete_couts_reduits_positifs ? " - rejette coûts réduits positifs" : " - accepte coûts réduits positifs") << "#############" << std::endl ; #endif #ifdef _RELEASE_ pourcentage_de_temps_2 = ((heure_debut_passe - CInstance::params().getTimeStart()) * 100) / CInstance::params().getTimeLimit() ; if (pourcentage_de_temps_2 != pourcentage_de_temps_1) std::cout << "elapsed time : " << pourcentage_de_temps_2 << "%" << std::endl; pourcentage_de_temps_1 = pourcentage_de_temps_2; #endif } void COptimizer::verbose_avant_dual_ascent() { #ifdef VERBOSE_PASSES std::cout << " calcul des variables duales" << std::endl ; #endif temps1 = clock(); } void COptimizer::verbose_apres_dual_ascent(vector new_u) { #ifdef VERBOSE_TEMPS temps2 = clock(); std::cout << "time(DA) " << "\t" << time(NULL) - CInstance::params().getTimeStart() << "\t" << time(NULL) - maintenant << std::endl; maintenant = time(NULL); std::cout << "clock(DA)" << "\t" << (temps2 - temps1) / (double) CLOCKS_PER_SEC << std::endl ; #endif #ifdef VERBOSE_DUALS cout << "duals : " ; for (size_t t = 0; tm_plan) << std::endl; } } ; void COptimizer::verbose_apres_creer_colonnes() { temps2 = clock() ; #ifdef VERBOSE_TEMPS std::cout << "time(colonnes) " << "\t" << time(NULL) - CInstance::params().getTimeStart() << "\t" << time(NULL) - maintenant << std::endl; std::cout << "clock(colonnes)" << "\t" << (temps2 - temps1) / (double) CLOCKS_PER_SEC << std::endl ; #endif maintenant = time(NULL); #ifdef VERBOSE_PLANS PredAffichePlanDeProduction affichePlan; std::for_each( graphes.begin(), graphes.end(), affichePlan ); #endif #ifdef VERBOSE_PASSES std::cout << " ajout des nouvelles colonnes" << std::endl ; #endif } /* écriture du fichier daniel.txt : résumé des infos à mettre dans le tableau */ void COptimizer::log_daniel_txt() { std::ofstream daniel("daniel.txt") ; daniel << "data\tRelaxedMPLB\tIterToLB\tTotalIter\tnbPlans\tnbContraintes\tMPsol\tF.A.Phase1\tFinalSol\tMaxTime\tElapsedTime" << std::endl << CInstance::params().getInstanceName() << "\t" << _LBvalue << "\t" // << _nbIterToLB << "\t" << _nbTotalIter << "\t" << _nbPlans << "\t" << _nbContraintesClique << "\t" << _MIPvalue << "\t" << _MinFiltreAvalPhase1Value << "\t" << _FinalValue << "\t" << CInstance::params().getTimeLimit() << "\t" << time(NULL) - CInstance::params().getTimeStart() << std::endl ; daniel.close(); } /** * STRATEGIES */ bool COptimizer::prepare_strategie() { static bool premiere_fois = true ; static bool option_rejete_couts_reduits_positifs = false ; static bool option_accepte_plan_existant = true ; if (premiere_fois) { option_rejete_couts_reduits_positifs = CInstance::params().getRejetCoutsReduitsPositifs() ; option_accepte_plan_existant = not CInstance::params().getRejetPlansExistants() ; premiere_fois = false ; strategie_stop = false ; } strategie_rejete_couts_reduits_positifs = option_rejete_couts_reduits_positifs ; strategie_accepte_plan_existant = option_accepte_plan_existant ; strategie_dual_ascent = true ; strategie_utilise_contraintes_de_cliques = false ; if (nb_rejets_couts_positifs+nb_rejets_existants==(unsigned)I()) strategie_stop = true ; nb_rejets_couts_positifs = 0 ; nb_rejets_existants = 0 ; #ifdef VERBOSE_PASSES std::cout << "planification de passes : strategie_stop=" << (strategie_stop?"true":"false") << std::endl; #endif return (not strategie_stop); }