#ifndef CGRAPHE_H #define CGRAPHE_H #include "../instance/indices.h" #include #include #include #include #include "cplan.h" #include /** @author Antoine Rozenknop */ struct ExceptionRefuelImpossible : public std::string { ExceptionRefuelImpossible(powerplants2_t i, campaign_t k, double s, double smin, double smax, double rmin, double rmax, double ssmax); }; struct ExceptionCroisementSminSmax {}; struct CNoeud { noeud_t m_type; double m_fuel; // niveau de fuel à l'arrivée sur le noeud double m_fuel_avant_refuel;// niveau de fuel après perte dûe au refueling (mais avant le refueling) campaign_t m_campaign; // numéro de la campagne week_t m_date_outage; // date de l'outage précédant la production // (pour les noeuds de type modulation) week_t m_date_campaign; // date de début de production (pour tous les noeuds) week_t m_date; // date associée au noeud }; struct OrdreCNoeud { bool operator()(const CNoeud * i, const CNoeud * j) { return i->m_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 ; } }; 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; } }; struct Ui { Ui() {} Ui(double _u, week_t _i) {u=_u; i=_i;} double u ; week_t i ; }; class CIntervallesBO ; 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); ~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, double smin_d, double smax_d ); void faisceau_suite_BO( const CNoeud & depart, week_t h, CIntervallesBO limits ) ; void noeuds_eventuels_outage( const CNoeud & depart, week_t h, double smin, double smax ) ; void noeuds_eventuels_BO( const CNoeud & depart, week_t h, double smin, double smax ); void creer_noeuds_intervalle( week_t h, noeud_t type, campaign_t k, double min, double max, bool force_min, bool force_max); void creer_noeud( week_t h, noeud_t type, campaign_t k, double fuel ); double pavage( week_t h ) ; public: void creerArcs(); void dump(); static void prepare_viterbi(const std::vector * u); static void creer_colonnes( CGraphe * graphe ) ; static void detruit( CGraphe * graphe ) { delete graphe ; } void creer_colonne() ; void accepte_colonne() { m_plan = NULL ; } /** * calcule_couts_des_arcs */ void calcule_couts_des_arcs(); /** * calcule_cout_arc */ template double 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 ; // vecteurs précalculés std::vector m_somme_EMAX ; // somme des EMAXi sur la période [0,h[ pour h allant de 0 à H() std::vector m_somme_ui_EMAX ; // somme des ui*EMAXi sur la période [0,h[ #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_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 double 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 double 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 ; double 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 double & V(powerplants2_t i) ; }; #endif