#ifndef CGRAPHE_H #define CGRAPHE_H #include "../instance/indices.h" #include #include #include #include #include "cplan.h" #include /** @author Antoine Rozenknop */ /** * type cout_t : contient le nombre de contraintes violées et le prix */ /*struct cout_t { cout_t() {contraintes=0; prix=(euros)0;} cout_t(double , euros _prix) {contraintes=0; prix=_prix;} double contraintes ; euros prix ; cout_t operator+(const cout_t & o) const { return cout_t(contraintes+o.contraintes, prix+o.prix); } bool operator<(const cout_t & o) const { return (contraintesm_datem_date ? true : i->m_date>j->m_date ? false : i->m_typem_type ? true : i->m_type>j->m_type ? false : i->m_fuel < j->m_fuel ; } }; /** * type CArc */ struct CArc { CArc(CNoeud * de, size_t id, CNoeud * vers, size_t iv) : m_de(de), m_vers(vers), ide(id), ivers(iv) {} const CNoeud * m_de ; const CNoeud * m_vers ; size_t ide; size_t ivers; static size_t de(CArc & arc) { return arc.ide; } static size_t vers(CArc & arc) { return arc.ivers; } }; struct OrdreArc { bool operator()(const CArc & i, const CArc & j) { return i.ide < j.ide ? true : i.ide > j.ide ? false : i.ivers < j.ivers ? true : i.ivers > j.ivers ? false : i.m_de->m_type < j.m_de->m_type ? true : i.m_de->m_type > j.m_de->m_type ? false : i.m_de->m_fuel < j.m_de->m_fuel; } }; /** * type Ui pour ordonner les index des ui par ui croissant */ struct Ui { Ui() {} Ui(euros_par_kWh _u, week_t _i) {u=_u; i=_i;} euros_par_kWh u ; week_t i ; }; /** * classe CGraphe */ class CIntervallesBO ; class CDualCplexScenario; class CGraphe{ public: /** * constructeur d'un graphe pour une centrale * @param i : numéro de la centrale * @param nb_levels : nombre max de niveaux de remplissage de la centrale */ CGraphe(powerplants2_t i); void init(); ~CGraphe(); /* méthodes */ /** * prépare la création du graphe */ void prepareCreation(); /** * creerNoeuds : création des listes associées aux noeuds du graphe * @param nbNiveaux : nombre de niveaux de remplissage à considérer */ void creerNoeuds(); private: void faisceau( const CNoeud & depart ); void faisceau_suite_modul( const CNoeud & depart, week_t h, kWh smin_d, kWh smax_d ); void faisceau_suite_BO( const CNoeud & depart, week_t h, CIntervallesBO limits ) ; void noeuds_eventuels_outage( const CNoeud & depart, week_t h, kWh smin, kWh smax ) ; void noeuds_eventuels_BO( const CNoeud & depart, week_t h, kWh smin, kWh smax ); void creer_noeuds_intervalle( week_t h, noeud_t type, campaign_t k, kWh min, kWh max, bool force_min, bool force_max); void creer_noeud( week_t h, noeud_t type, campaign_t k, kWh fuel ); kWh pavage( week_t h ) ; public: void creerArcs(); void dump(); static void prepare_viterbi(const std::vector * u, bool nouvelles_duales, bool contraintes_cliques); static void creer_colonnes( CGraphe * graphe ) ; static void detruit( CGraphe * graphe ) { delete graphe ; } void creer_colonne() ; void accepte_colonne() { m_plan = nullptr ; } void rejette_colonne() { delete m_plan; m_plan = nullptr; } /** * calcule_couts_des_arcs */ void calcule_couts_des_arcs(); /** * calcul du coût des contraintes de clique */ void calcule_cout_contraintes( CNoeud * noeud ); /** * indique si les contraintes de cliques ont augmenté * depuis la dernière passe pour le dernier plan trouvé */ bool is_contraintes_dernier_plan_augmentees() const; /** * calcule_cout_arc */ template cout_t calcule_cout_arc(size_t arc_idx) ; /** * viterbise */ void viterbise(); /** * plan_de_production_apres_viterbi */ void plan_de_production_apres_viterbi(); /* organisation des noeuds en semaine/niveau */ typedef std::map niveaux_t ; typedef std::map type_levels_t ; typedef std::map campaign_levels_t ; typedef std::map semaines_t ; /* attributs */ powerplants2_t m_i ; std::pair,std::vector> m_dual_dates; void collecte_duales_dates(CDualCplexScenario * cplex); std::pair,std::vector> m_dual_recharges; void collecte_duales_recharges(CDualCplexScenario * cplex); // vecteurs précalculés std::vector m_somme_EMAX ; // somme des EMAXi sur la période [0,h[ pour h allant de 0 à H(), pour chaque campagne std::vector< std::vector > m_somme_ui_EMAX ; // somme des ui*EMAXi sur la période [0,h[, pour chaque campagne kWh m_pavage ; #ifdef _MODUL_REPARTIE_ std::vector< std::vector > m_somme_ui_EMAX_cout_positif ; std::vector< std::vector > m_somme_EMAX_cout_positif ; inline const std::vector & somme_ui_EMAX(campaign_t k) { return k==K_Tp1 ? m_somme_ui_EMAX.back() : m_somme_ui_EMAX[k+1]; } inline const std::vector & somme_ui_EMAX_cout_positif(campaign_t k) { return k==K_Tp1 ? m_somme_ui_EMAX_cout_positif.back() : m_somme_ui_EMAX_cout_positif[k+1]; } inline const std::vector & somme_EMAX_cout_positif(campaign_t k) { return k==K_Tp1 ? m_somme_EMAX_cout_positif.back() : m_somme_EMAX_cout_positif[k+1]; } inline const euros somme_ui_EMAX(campaign_t k, week_t h1, week_t h2) { return somme_ui_EMAX(k)[h2] - somme_ui_EMAX(k)[h1]; } inline const euros somme_ui_EMAX_cout_positif(campaign_t k, week_t h1, week_t h2) { return somme_ui_EMAX_cout_positif(k)[h2] - somme_ui_EMAX_cout_positif(k)[h1];} inline const kWh somme_EMAX_cout_positif(campaign_t k, week_t h1, week_t h2) { return somme_EMAX_cout_positif(k)[h2] - somme_EMAX_cout_positif(k)[h1];} #endif // liste des campagnes ayant un outage une semaine donnée std::vector > m_campaigns ; // taille : nb_semaines semaines_t m_map_noeuds ; // taille totale : nb_noeuds std::vector m_noeuds ; // taille : nb_noeuds std::vector m_premier_arc ; // taille : nb_noeuds std::vector m_arcs ; std::vector m_noeud_debut ; // taille : nb_arcs std::vector m_noeud_fin ; // taille : nb_arcs std::vector m_cout ; // taille : nb_arcs CPlan * m_plan ; // plan de production // on récupère de Viterbi std::list m_meilleur_chemin ; cout_t m_cout_minimal ; /* attributs statiques pour le calcul des coûts : variables duales U, v */ static const std::vector * m_u ; static std::vector U ; static const euros_par_kWh u(const week_t & h) { return (*m_u)[h]; } static const euros_par_kWh V(powerplants2_t i) ; static bool s_contraintes_cliques ; static bool s_nouvelles_duales ; static std::vector> s_dates_ref; static void set_dates_ref(const std::vector> & dr) { s_dates_ref = dr; } static week_t get_date_ref(powerplants2_t i, campaign_t k) {return s_dates_ref[i][k];} static std::vector> s_recharges_ref; static void set_recharges_ref(const std::vector> & dr) { s_recharges_ref = dr; } static kWh get_recharge_ref(powerplants2_t i, campaign_t k) {return s_recharges_ref[i][k];} }; #endif