#include "cplan.h" #include "cgraphe.h" #include #include #include #include #include #include using namespace std ; int CPlan::id = 0 ; /// liste des plans retenus std::vector CPlan::s_plans; /// plans_centrale[i] = ensemble des idx des colonnes relatives à la centrale i vector > CPlan::s_plans_centrale; /// plan déjà existant trouvé dans retiens_plan size_t CPlan::s_plan_existant = (size_t) -1; /** * ENREGISTRE UN PLAN */ bool CPlan::retiens_plan(CPlan * nouveau_plan, bool meme_si_deja_present) { if (s_plans_centrale.size()==0) s_plans_centrale.resize(I(), vector(0)); vector & plans_centrale = s_plans_centrale[nouveau_plan->m_i]; if (not meme_si_deja_present) { for (size_t ip=0; ip::iterator itp = std::find(s_plans.begin(), s_plans.end(), plan); size_t index = itp - s_plans.begin(); s_plans.erase(itp); // recherche et suppression de l'index trouvé dans les plans associés à la centrale plan->m_i vector & idx_plans = s_plans_centrale[plan->m_i]; vector::iterator it = std::find(idx_plans.begin(), idx_plans.end(), index); idx_plans.erase(it); // décrémentation des index supérieurs for (powerplants2_t i; iindex) (*it)--; } } // libération du plan delete plan; } /** * libération */ void CPlan::libere_plans() { for (std::vector::iterator it=s_plans.begin(); it!=s_plans.end(); it++) if (*it) delete *it; s_plans.clear(); } size_t CPlan::findIndex(const CPlan * plan) { return std::find(s_plans.begin(), s_plans.end(), plan) - s_plans.begin(); } /** * égalité de deux plans */ bool CPlan::operator==(const CPlan & o) const { return m_i == o.m_i and m_colonne == o.m_colonne and m_fuel == o.m_fuel and m_fuel_tp1 == o.m_fuel_tp1 and m_arcs == o.m_arcs and m_reste == o.m_reste; } bool CPlan::CArc::operator==(const CPlan::CArc & o) const { return m_type == o.m_type and m_k == o.m_k and m_recharge == o.m_recharge and m_depart == o.m_depart and m_fin == o.m_fin; } CPlan::CArc::CArc(const CNoeud & depart, const CNoeud & fin, kWh _recharge, kWh _reste, euros ui_prod, euros _cout) : m_depart(&depart), m_fin(&fin) { m_type = depart.m_type ; m_k = depart.m_campaign ; m_date = depart.m_date ; m_date_fin = fin .m_date ; m_recharge = _recharge ; m_cout = _cout ; m_ui_prod = ui_prod ; m_reste = _reste ; } CPlan::CPlan( powerplants2_t i, size_t taille_prod, powerplants2_t nb_centrales) { m_colonne = std::vector( taille_prod + nb_centrales, (kWh)0 ); m_colonne[ taille_prod + i ] = (kWh)1 ; m_fuel = vector( taille_prod, (kWh)0 ) ; m_fuel_tp1 = vector( taille_prod, (kWh)0 ) ; m_i = i ; for (week_t h=(week_t)0; h<(week_t)taille_prod; ++h) m_colonne[h] = EMAX(m_i, h); m_cout_reduit = (euros)0 ; m_cout = (euros)0 ; m_reste = (kWh)0 ; m_id = id++ ; } void CPlan::set_prod( size_t index, kWh prod ) { m_colonne[index] = prod ; } euros CPlan::recalcule_cout_reduit() const { euros _ui_prod = CGraphe::V(m_i) * (kWh)1; for (week_t h; h!=H(); ++h) _ui_prod += CGraphe::u(h) * m_colonne[h]; m_cout_reduit = m_cout - _ui_prod ; return m_cout_reduit ; } void CPlan::push_back( const CNoeud & dep, const CNoeud & fin, kWh _recharge, kWh _reste, euros _ui_prod, euros _cout ) { m_arcs.push_back(CArc(dep, fin, _recharge, _reste, _ui_prod, _cout )); m_ui_prod += _ui_prod ; m_cout += _cout ; // cout << "plan " << m_id << " : cout + " << _cout << endl ; m_reste = _reste ; if (fin.m_type==TYPE_DERNIER) { m_cout -= (CiTp1(m_i)*_reste); // cout << "plan " << m_id << " : cout - " << (CiTp1(m_i)*_reste) << endl ; // on fait comme si les V correspondaient à une production d'un kWh sur la semaine H+i m_cout_reduit = m_cout - m_ui_prod - CGraphe::V(m_i) * (kWh)1; // calcul des ha m_ha.resize(0); for (size_t a=0; a & prod, vector & stock, vector & demande_restante) { for (size_t arc_idx=0; arc_idxm_type==TYPE_BO) { kWh fuel = arc.m_depart->m_fuel ; for (timestep_t t=week2timestep(arc.m_date); tm_date); ++t) { stock[t] = fuel ; prod[t] = type2(m_i).PB(arc.m_depart->m_campaign, t, fuel); fuel -= prod[t] ; demande_restante[t] -= prod[t] ; } } } } void CPlan::remplis_BO_en_visant_bien(vector & prod, vector & stock, vector & demande_restante) const { for (size_t arc_idx=0; arc_idx ideal ; timestep_t tdeb=week2timestep(depart.m_date); timestep_t tfin=week2timestep(fin.m_date); #ifdef _DEBUG_BO_ cout << "\nPowerplant " << m_i.v << " k:" << depart.m_campaign.v << " h:" << depart.m_date.v << endl ; #endif if (fin.m_type!=TYPE_DERNIER) { // pour bien viser, on encadre le stock sur chaque t list liste_limits ; liste_limits.push_back( CIntervallesBO((kWh)-1,depart.m_fuel,depart.m_fuel) ); for (timestep_t t=tdeb; t & min, std::vector & max) const { // remplissage des outages (prod=0) min = vector(T(), (kWh)0); // remplissage des BO (max=min) vector stock(T()), reste(T()); remplis_BO_en_visant_bien(min, stock, reste); max = min ; // remplissage hors BO et outages (min=0, max=EMAX) for (size_t arc_idx=0; arc_idxm_type != TYPE_BO) for (timestep_t t=week2timestep(arc.m_depart->m_date_campaign); tm_date); ++t) { max[t] = EMAX(m_i,t); } } } vector CPlan::arcs_non_BO() const { vector retour ; for (size_t arc_idx=0; arc_idxm_type != TYPE_BO) retour.push_back(&arc); } return retour; } void CPlan::remplis_campagnes_non_BO( vector & prod, vector & stock, vector & demande_restante) const { for (size_t arc_idx=0; arc_idxm_type==TYPE_OUTAGE) { timestep_t t = week2timestep(arc.m_date) ; stock[t] = arc.m_depart->m_fuel ; prod [t] = (kWh) 0 ; for (++t; tm_date_campaign) and tm_date); ++t) { stock[t] = arc.m_depart->m_fuel_avant_refuel + arc.m_recharge ; prod[t] = (kWh) 0 ; } } // remplissage des campagnes de production non BO if (arc.m_depart->m_type != TYPE_BO) { kWh fuel = arc.m_depart->m_fuel_avant_refuel + arc.m_recharge ; // parcours des semaines for (week_t h = arc.m_depart->m_date_campaign; hm_date; ++h) { for (timestep_t t=week2timestep(h); tm_campaign)) ; prod [t] = m_colonne[h] * (EMAX(m_i,t)==(kWh)0 ? (coeff_t)1 : EMAX(m_i,t) / EMAX(m_i,h)); fuel -= prod[t] ; demande_restante[t] -= prod[t] ; } } } } } /** * perte de fuel lors d'un refuel * @param i index de la centrale * @param kmoins1 campagne en cours avant l'outage * @param k campagne de l'outage * @param x niveau de fuel avant l'outage * @return */ inline kWh perte_refuel( powerplants2_t i, campaign_t k, kWh x ) { return BO(i,(campaign_t)(k-1)) * ((Q(i,k)-(coeff_t)1)/Q(i,k)) - BO(i,k) + x / Q(i,k) ; } vector CPlan::remplis_stock( const vector & prod, const vector & recharges ) const { vector stock(T()+(tlen_t)1); // stock de départ stock[0] = m_arcs[0].m_depart->m_fuel; // parcours des arcs for (size_t arc_idx=0; arc_idxm_date)+(tlen_t)1 ; if (arc.m_depart->m_type==TYPE_OUTAGE) { stock[t] = stock[t-(tlen_t)1] - perte_refuel(m_i, arc.m_depart->m_campaign, stock[t-(tlen_t)1]) + recharges[arc.m_depart->m_campaign] ; } else { stock[t] = stock[t-(tlen_t)1] - prod[t-(tlen_t)1]; } for (; tm_date); ++t) { stock[t+(tlen_t)1] = stock[t] - prod[t]; //cout << "(" << m_i << "," << t << " : " << stock[t] << "," << prod[t] << "->" << stock[t+(tlen_t)1] << " "; } //cout << endl; } return stock; } void CPlan::remplis_dates_outages( std::vector & dates ) const { for (size_t arc_idx=0; arc_idxm_type==TYPE_OUTAGE) dates[arc.m_depart->m_campaign] = arc.m_depart->m_date ; } } void CPlan::remplis_recharges( std::vector & recharges ) const { for (size_t arc_idx=0; arc_idxm_type==TYPE_OUTAGE) recharges[arc.m_depart->m_campaign] = arc.m_recharge ; } } ostream & operator <<(ostream & out, CPlan & plan) { #ifdef FICHIER_PLAN ofstream fichier ; char nom[100]; sprintf(nom, "centrale_%02d", (int)plan.m_i); fichier.open(nom, ios_base::app); fichier.seekp( 0, ios_base::end ); for (size_t h=0; h<(unsigned)H(); h++) { fichier << fixed << setprecision(10) << plan.m_colonne[h]; if (h==(unsigned) (H()-1)) fichier << endl ; else fichier << '\t'; } fichier.close(); #endif out << "***** Plan de production de la centrale " << (int) plan.m_i << " *****" << endl ; for (size_t i = 0; iat(h) ; out << endl ; } out << " revente : " << plan.m_reste << "\tprix : " << CiTp1(plan.m_i)*plan.m_reste << endl; out << " coût total du plan : " << plan.m_cout << endl ; out << " coût réduit de la colonne : " << plan.m_cout_reduit << endl ; return out ; }