#include "cdualcplexscenario.h" #include #include #include #include #include using namespace std; int CDualCplexScenario::m_iteration = 0; CDualCplexScenario::CDualCplexScenario(scenario_t s, bool internal_silent, bool silent, bool writeToFile) { m_s = s; m_cplex = new CPlexMutable( "DualCalc", CPlexModel::Minimisation, CPlexModel::Linear, internal_silent, silent, writeToFile, writeToFile ); ajoute_thermiques(); ajoute_contraintes(); } CDualCplexScenario::~CDualCplexScenario() { delete m_cplex; } std::vector< euros_par_kWh > CDualCplexScenario::calculeDuals() const { vector duals( H() + I() ); m_cplex->resolution(); printResults(); vector cplex_duals = m_cplex->getDuals("production=demande"); for (week_t h; hgetDuals( "unicité colonnes nucléaires" ); for (powerplants2_t i; i CDualCplexScenario::resolution_entiers() { m_cplex->set_problem_type(CPlexModel::MixedInteger); for (CPlan * plan: m_plans) { m_cplex->set_variable_type(string("centrale_") +plan->m_i +"_plan_"+plan->m_id, CPlexModel::Binary); } m_cplex->resolution(); vector selection ; for (CPlan * plan: m_plans) { vector vplan = m_cplex->getResult(string("centrale_") +plan->m_i +"_plan_"+plan->m_id); if (vplan[0]>1-EPSILON ) selection.push_back(plan); } return selection; } void CDualCplexScenario::ajoutcolonne(CPlan* cplan) { ostringstream os ; os << "DualCalc_" << (++m_iteration) ; // ajout du plan à la liste des plans m_plans.push_back(cplan); // ajout de la zone horizontale pour la colonne m_cplex->addColonne( string("centrale_") +cplan->m_i +"_plan_"+cplan->m_id, 1); // fonction objectif : coût du plan m_cplex->setColonne( string("centrale_") +cplan->m_i +"_plan_"+cplan->m_id ); // m_cplex->addToObj( 0, 0, 1, CPlexModel::Continuous, cplan->m_cout.v ); m_cplex->addToObj( 0, 0, INFINI, CPlexModel::Continuous, cplan->m_cout.v ); // Z : partie production m_cplex->setLigne("production=demande"); for (week_t h=(week_t)0; haddToZ( h, 0, cplan->m_colonne[h].v ); // Z : partie sélection de colonne m_cplex->setLigne( "unicité colonnes nucléaires" ); m_cplex->addToZ( cplan->m_i, 0, 1 ); // ajout des contraintes de type 14 à 21 CConstraint::ajoute_plan_contraintes_14_a_21(cplan, m_cplex); // ajout des coefficients (abarre-a) les contraintes des variables de recours ?" delta+ m_cplex->setLigne (string("delta_date_plus_i_")+cplan->m_i+"_k"); for (campaign_t k; kK()) { //if (m_dates_ref[cplan->m_i][k] - cplan->ha(k) < 0) m_cplex->addToZ(k, 0, - cplan->ha(k)); } else { //if (m_dates_ref[cplan->m_i][k] - H() < 0) m_cplex->addToZ(k, 0, - H()); } // } // ajout des coefficients sur les variables "de recours ?" delta- m_cplex->setLigne (string("delta_date_moins_i_")+cplan->m_i+"_k"); for (campaign_t k; kK()) { //if (cplan->ha(k) - m_dates_ref[cplan->m_i][k] < 0) m_cplex->addToZ(k, 0, cplan->ha(k)); } else { //if (H() - m_dates_ref[cplan->m_i][k] < 0) m_cplex->addToZ(k, 0, H() ); } } // affichage cout << "scenario " << m_s << " centrale " << cplan->m_i << ", arrêts : "; for (campaign_t k; kK()) cout << cplan->ha(k); else cout << "aucun" ; } cout << endl; #warning idem pour les recharges // ajout des coefficients (rbarre-r) les contraintes des variables de recours ?" delta+ m_cplex->setLigne (string("delta_recharge_plus_i_")+cplan->m_i+"_k"); for (campaign_t k; kK()) { //if ( m_recharges_ref[cplan->m_i][k].v - cplan->recharge(k).v < 0) m_cplex->addToZ(k, 0, - cplan->recharge(k).v); } else { //if (m_recharges_ref[cplan->m_i][k].v - 0 < 0) m_cplex->addToZ(k, 0, 0); } } // ajout des coefficients sur les variables "de recours ?" delta- m_cplex->setLigne (string("delta_recharge_moins_i_")+cplan->m_i+"_k"); for (campaign_t k; kK()) { //if (cplan->recharge(k).v - m_recharges_ref[cplan->m_i][k].v < 0) m_cplex->addToZ(k, 0, cplan->recharge(k).v); } else { //if (0 - m_recharges_ref[cplan->m_i][k].v < 0) m_cplex->addToZ(k, 0, 0 ); } } // affichage cout << "scenario " << m_s << " centrale " << cplan->m_i << ", recharges : "; for (campaign_t k; kK()) cout << cplan->recharge(k) << ",ref=" << m_recharges_ref[cplan->m_i][k]; else cout << 0 << ",ref=" << m_recharges_ref[cplan->m_i][k] ; } cout << endl; } pair,vector> CDualCplexScenario::getDualsDates(powerplants2_t i) { pair,vector> duals; duals = make_pair(m_cplex->getDuals(string("delta_date_plus_i_")+i+"_k"), m_cplex->getDuals(string("delta_date_moins_i_")+i+"_k")); return duals; } pair, vector> CDualCplexScenario::getDualsRecharges(powerplants2_t i) { pair,vector> duals; duals = make_pair(m_cplex->getDuals(string("delta_recharge_plus_i_")+i+"_k"), m_cplex->getDuals(string("delta_recharge_moins_i_")+i+"_k")); return duals; } ///Calculer la moyenne x(i)*cplan->ha(k) vector> CDualCplexScenario::getMoyenneDates() { vector> dates(I(),vector(K(),0.0)); vector probas = getResults(); for (size_t p=0; p m_i][k] += probas[p]*(kK()?plan->ha(k):H()); ///Affichage //cout << "centrale " << plan->m_i << " id plan " << plan->m_id << " x " << probas[p] << " dates " << dates[plan->m_i][k] << endl; /// end Affichage } // //cout << "scenario " << m_s << " centrale " << plan->m_i << ", x : " << probas[p] << ", arrêts : "; // for (campaign_t k; kK()) cout << plan->ha(k); // else cout << H() ; // } // cout << endl; } return dates; } vector< vector< double > > CDualCplexScenario::getMoyenneRecharges() { vector> recharges(I(),vector(K(),0.0)); vector probas = getResults(); for (size_t p=0; p m_i][k] += probas[p]*( (k < plan->K()) ? plan->recharge(k) : (kWh)0).v; ///Affichage //cout << "centrale " << plan->m_i << " id plan " << plan->m_id << " x " << probas[p] << " dates " << dates[plan->m_i][k] << endl; /// end Affichage } // //cout << "scenario " << m_s << " centrale " << plan->m_i << ", x : " << probas[p] << ", arrêts : "; // for (campaign_t k; kK()) cout << plan->ha(k); // else cout << H() ; // } // cout << endl; } return recharges; } /// retrait d'un plan de production nucléaire void CDualCplexScenario::retraitColonne(const CPlan* plan) { size_t indice = std::find(m_plans.begin(), m_plans.end(), plan) - m_plans.begin() ; m_cplex->removeZoneHorizontale( string("centrale_") +plan->m_i +"_plan_"+plan->m_id ); m_plans.erase( m_plans.begin()+indice ); } vector CDualCplexScenario::getReducedCosts() const { vector cr( m_plans.size() ); for (size_t p=0; pgetReducedCosts(string("centrale_") +m_plans[p]->m_i +"_plan_"+m_plans[p]->m_id)[0]; } return cr; } vector CDualCplexScenario::getResults() const { vector vars( m_plans.size() ); for (size_t p=0; pgetResult(string("centrale_") +m_plans[p]->m_i +"_plan_" +m_plans[p]->m_id)[0]; } return vars; } void CDualCplexScenario::printResults() const { vector r = getResults(); cout << "Objectif : " << m_cplex->getObjectiveValue() ; cout << " Results : "; for (auto p: r) { cout << p << " "; } cout << endl; } double CDualCplexScenario::getObjectiveValue() const { return m_cplex->getObjectiveValue() ; } void CDualCplexScenario::collecte_duales_14_a_21() const { CConstraint::collecte_duales_14_a_21(m_cplex); } void CDualCplexScenario::ajoute_thermiques() { // définition des zones m_cplex->addLigne( "production=demande", H()); for (powerplants1_t j=(powerplants1_t)0; jaddColonne( string("production thermique centrale ")+j, H()); m_cplex->addLigne( "unicité colonnes nucléaires", I()); // fonction objectif // coeff: coût de la production thermique unitaire par semaine // variables associées : énergie produite, continue (entre pmin et pmax) for (powerplants1_t j=(powerplants1_t)0; jsetColonne( string("production thermique centrale ")+j ); for ( week_t h=(week_t) 0; haddToObj( h, EMIN(j,m_s,h).v, EMAX(j,m_s,h).v, CPlexModel::Continuous, C(j,m_s,h).v ); } // remplissage de Z // satisfaction de la demande m_cplex->setLigne( "production=demande"); // partie droite : demande, opérateur = for (week_t h=(week_t) 0; haddToRHS( h, CPlexModel::Equals, EDEM(m_s,h).v ); // production des centrales thermiques par semaine (matrices identité) for (powerplants1_t j=(powerplants1_t)0; jsetColonne( string("production thermique centrale ")+j ); for (week_t h=(week_t)0; haddToZ( h, h, 1 ); } // unicité des colonnes nucléaires m_cplex->setLigne( "unicité colonnes nucléaires" ); for (powerplants2_t i; iaddToRHS( i, CPlexModel::LowerThan, 1 ); } } void CDualCplexScenario::ajoute_contraintes() { CConstraint::prepare_contraintes_14_a_21(m_cplex); } void CDualCplexScenario::ajoute_deltas() { // ajout d'un delta_date+ et d'un delta_date- pour chaque centrale nucléaire et chaque campagne vector zones({string("delta_date_plus_i_" ),string("delta_date_moins_i_")}); for (string zone: zones) { for (powerplants2_t i; iaddColonne(zone+i+"_k", K()); // fonction objectif : coûts et bornes m_cplex->setColonne(zone+i+"_k"); for (campaign_t k; kaddToObj(k, 0, H().v, CPlexModel::Continuous, zone=="delta_date_plus_i_" ? Cpost(i,k).v : Cpre(i,k).v); // cout << "delta_date_plus_i_" << i << "_k_" << k << " = " << type2(i).Cpost(k).v << endl; } // ajout des contraintes : une pour chaque delta_date m_cplex->addLigne(zone+i+"_k", K()); m_cplex->setLigne(zone+i+"_k"); for (campaign_t k; kaddToZ(k, k, 1); m_cplex->addToRHS(k, CPlexModel::GreaterThan, (zone=="delta_date_plus_i_" ? -1 : 1) * m_dates_ref[i][k]); } } } // ajout d'un delta_recharge+ et d'un delta_recharge- pour chaque centrale nucléaire et chaque campagne vector zonesrecharge({string("delta_recharge_plus_i_" ),string("delta_recharge_moins_i_")}); for (string zone: zonesrecharge) { for (powerplants2_t i; iaddColonne(zone+i+"_k", K()); // fonction objectif : coûts et bornes m_cplex->setColonne(zone+i+"_k"); for (campaign_t k; kaddToObj(k, 0, RMAX(i,k).v, CPlexModel::Continuous, zone=="delta_recharge_plus_i_" ? Cplus(i,k).v : Cmoins(i,k).v); // cout << "delta_recharge_plus_i_" << i << "_k_" << k << " = " << type2(i).Cpost(k).v << endl; } // ajout des contraintes : une pour chaque delta_recharge m_cplex->addLigne(zone+i+"_k", K()); m_cplex->setLigne(zone+i+"_k"); for (campaign_t k; kaddToZ(k, k, 1); m_cplex->addToRHS(k, CPlexModel::GreaterThan, (zone=="delta_recharge_plus_i_" ? -1 : 1) * m_recharges_ref[i][k].v); } } } }