#include #include #include "cconstraint.h" #include "lecture.h" #include "cinstance.h" #include "cinstancereduite.h" #include #include #include "cplexmutable.h" using instanceNs::lire_valeur; using instanceNs::lire_intervalle ; using instanceNs::lire_liste ; /** * CConstraint */ string CConstraint::getNom() { return string("CT") + getType() + "_" + m; } void CConstraint::lire( int index ) { if (lire_valeur("begin")!="constraint") throw string("section constraint manquante"); if (lire_valeur("type")!=getType()) throw string("mauvais type de contrainte"); if ((m=lire_valeur("index"))!=index) throw string("mauvais index de contrainte"); lire_contrainte_typee(); if (lire_valeur("end")!="constraint") throw string("end constraint manquant"); } void CConstraint::enregistrerDuales(CPlexMutable* cplex) { m_duals = cplex->getDuals(getNom()); } /** * 13 */ const week_t CConstraint13::inconnu = (week_t) -2 ; const week_t CConstraint13::indefini = (week_t) -1 ; void CConstraint13::lire_contrainte_typee() { i = (powerplants2_t) lire_valeur("powerplant"); k = (campaign_t) lire_valeur("campaign"); m_TO = (week_t) lire_valeur("earliest_stop_time"); m_TA = (week_t) lire_valeur("latest_stop_time"); type2(i).TO(k) = m_TO ; type2(i).TA(k) = m_TA ; m_hmax = H(); m_blocages = vector >( 1, vector(h_max(), 0) ); constraints(i).push_back(this); } void CConstraint13::interpole( powerplants2_t _i, campaign_t _k, week_t _to, week_t _ta) { i = _i ; k = _k ; m_TO = _to ; m_TA = _ta ; type2(i).TO(k) = m_TO ; type2(i).TA(k) = m_TA ; m_hmax = H() ; m_blocages = vector >( 1, vector(h_max(), 0) ); } void CConstraint13::ajoute_plan(const CPlan * plan) { // for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) if ( k < (signed) plan->m_ha.size() ) { m_blocages[0][plan->ha(k)] += 1 ; } } double CConstraint13::cout_blocage(powerplants2_t i, const CNoeud * noeud) { return (m_blocages[0][noeud->m_date_outage]); // return 0; } void CConstraint13::prepareZoneVerticale(CPlexMutable* cplex) { } void CConstraint13::ajoute_plan(const CPlan* plan, CPlexMutable* cplex) { } void CConstraint13::enregistrerDuales(CPlexMutable* ) { } euros CConstraint13::cout_noeud(powerplants2_t i, const CNoeud* noeud) { euros cout; return cout; } /** * 14 */ void CConstraint14::lire_contrainte_typee() { m_C = lire_liste("set"); m_Se = (wlen_t) lire_valeur("spacing"); m_index.resize( I(), -1); m_hmax = H(); m_blocages = vector >( m_C.size(), vector(h_max(), 0) ); for (size_t it_i=0; it_im_ha.size(); k=(campaign_t)(k+1)) { if ( ha1==plan->ha(k) or (ha1 >= plan->ha(k) and ha1 < plan->ha(k) + DA(plan->m_i,k) + m_Se) ) { return true ; } } return false ; } void CConstraint14::ajoute_plan(const CPlan * plan) { for ( size_t it_i=0; it_im_i) { for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { for (week_t h=plan->ha(k); h < plan->ha(k) + DA(plan->m_i,k) + m_Se and hm_date_outage]); } void CConstraint14::prepareZoneVerticale(CPlexMutable* cplex) { cplex->addLigne( getNom(), h_max() ); cplex->setLigne( getNom() ); for (week_t w; waddToRHS(w, CPlexModel::LowerThan, 1); } m_duals.resize(h_max(), 0); } void CConstraint14::ajoute_plan(const CPlan* plan, CPlexMutable* cplex) { cplex->setLigne(getNom()); for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { for (week_t h=plan->ha(k); h < plan->ha(k) + DA(plan->m_i,k) + m_Se and haddToZ(h, 0, 1); } } } euros CConstraint14::getCoutDual(const CPlan* plan) { /* nécessite l'appel préalable à enregistrerDuales */ euros cout; for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { for (week_t h=plan->ha(k); h < plan->ha(k) + DA(plan->m_i,k) + m_Se and hm_date_outage; h < noeud->m_date_campaign + m_Se and h("start"); m_IF = (week_t) lire_valeur("end"); } double CConstraint15::concerne_self( week_t ha1, const CPlan * plan) { for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { if (ha1==plan->m_ha[k]) { // ha1 est la date d'outage de la campagne k du plan // ha1 est concerné si l'outage coupe l'intervalle [ID,IF] return (m_ID - DA(plan->m_i,k) + 1 <= plan->ha(k) and plan->ha(k) <= m_IF) ; } } // la méthode a été appelée avec une date ne correspondant à aucun outage throw (string("CConstraint15::concerne_self appelée avec la date ") + ha1 + " qui ne correspond à aucun outage."); } double CConstraint15::concerne_other( week_t h, const CPlan * plan) { for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { if ( m_ID - DA(plan->m_i,k) + 1 <= plan->ha(k) and plan->ha(k) <= m_IF ) if ( h == plan->ha(k) or (h >= plan->ha(k) and h < plan->ha(k) + DA(plan->m_i,k) + m_Se) ) { return true ; } } return false ; } void CConstraint15::ajoute_plan(const CPlan * plan) { for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { if ( m_ID - DA(plan->m_i,k) + 1 <= plan->ha(k) and plan->ha(k) <= m_IF ) { for ( size_t it_i=0; it_im_i) { for (week_t h=plan->ha(k); h < plan->ha(k) + DA(plan->m_i,k) + m_Se and hm_date_campaign>m_ID and noeud->m_date_outage<=m_IF) return (m_blocages[m_index[i]][noeud->m_date_outage]); else return 0; } void CConstraint15::ajoute_plan(const CPlan* plan, CPlexMutable* cplex) { cplex->setLigne(getNom()); for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { if (plan->ha(k)<=IF() and plan->ha(k)+DA(plan->m_i,k)>ID()) { for (week_t h=plan->ha(k); h < plan->ha(k) + DA(plan->m_i,k) + m_Se and haddToZ(h, 0, 1); } } } } euros CConstraint15::getCoutDual(const CPlan* plan) { /* nécessite l'appel préalable à enregistrerDuales */ euros cout; for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { if (plan->ha(k)<=IF() and plan->ha(k)+DA(plan->m_i,k)>ID()) { for (week_t h=plan->ha(k); h < plan->ha(k) + DA(plan->m_i,k) + m_Se and hm_date<=IF() and noeud->m_date_campaign>ID()) cout = CConstraint14::cout_noeud(i,noeud); return cout; } /** * 16 */ double CConstraint16::concerne_other( week_t h, const CPlan * plan) { for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { if ( h >= plan->ha(k) and h < plan->ha(k) + m_Se ) { return true ; } } return false ; } void CConstraint16::ajoute_plan(const CPlan * plan) { for ( size_t it_i=0; it_im_i) { for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { for (week_t h=plan->ha(k); h < plan->ha(k) + m_Se and hm_date_outage]); } void CConstraint16::ajoute_plan(const CPlan* plan, CPlexMutable* cplex) { cplex->setLigne(getNom()); for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { for (week_t h=plan->ha(k); h < plan->ha(k) + m_Se and haddToZ(h, 0, 1); } } } euros CConstraint16::getCoutDual(const CPlan* plan) { /* nécessite l'appel préalable à enregistrerDuales */ euros cout; for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { for (week_t h=plan->ha(k); h < plan->ha(k) + m_Se and hm_date_outage; h < noeud->m_date_outage + m_Se and h >( m_C.size(), vector(h_max(), 0) ); } double CConstraint17::concerne_other( week_t h, const CPlan * plan) { for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { if ( h >= plan->ha(k) + DA(plan->m_i, k) and h < plan->ha(k) + DA(plan->m_i, k) + m_Se ) { return true ; } } return false ; } void CConstraint17::ajoute_plan(const CPlan * plan) { for ( size_t it_i=0; it_im_i) { for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { for (week_t h=plan->ha(k) + DA(plan->m_i, k); h < plan->ha(k) + DA(plan->m_i, k) + m_Se and hm_date_campaign]); } void CConstraint17::ajoute_plan(const CPlan* plan, CPlexMutable* cplex) { cplex->setLigne(getNom()); for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { for (week_t h=plan->ha(k) + DA(plan->m_i,k); h < plan->ha(k) + DA(plan->m_i,k) + m_Se and haddToZ(h, 0, 1); } } } euros CConstraint17::getCoutDual(const CPlan* plan) { /* nécessite l'appel préalable à enregistrerDuales */ euros cout; for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { for (week_t h=plan->ha(k) + DA(plan->m_i,k); h < plan->ha(k) + DA(plan->m_i,k) + m_Se and hm_date_campaign; h < noeud->m_date_campaign + m_Se and hm_ha.size(); ++k) { if ( h1==plan->ha(k) or (abs(plan->ha(k) + DA(plan->m_i,k) - h1) < m_Se) ) { return 1 ; } } return 0 ; } void CConstraint18::ajoute_plan(const CPlan * plan) { for ( size_t it_i=0; it_im_i) { for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { for (week_t h = std::max( (week_t)0, (plan->ha(k) + DA(plan->m_i, k) - m_Se + (wlen_t) 1) ); h < plan->ha(k) + DA(plan->m_i, k) + m_Se and hm_date_outage]); } void CConstraint18::prepareZoneVerticale(CPlexMutable* cplex) { cplex->addLigne( getNom(), h_max()*m_C.size()); cplex->setLigne( getNom() ); for (size_t i=0; iaddToRHS(i*h_max()+w, CPlexModel::LowerThan, m_C.size()); m_duals.resize(H()*m_C.size(), 0); } void CConstraint18::ajoute_plan(const CPlan* plan, CPlexMutable* cplex) { cplex->setLigne(getNom()); for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { cplex->addToZ(plan->ha(k) + m_index[plan->m_i]*h_max(), 0, m_C.size()); for (powerplants2_t j: m_C) if (j!=plan->m_i) for (week_t h=std::max(week_t(0), plan->ha(k) + DA(plan->m_i,k) - m_Se + wlen_t(1)); h < plan->ha(k) + DA(plan->m_i,k) + m_Se and haddToZ(h + m_index[j]*h_max(), 0, 1); } } } euros CConstraint18::getCoutDual(const CPlan* plan) { /* nécessite l'appel préalable à enregistrerDuales */ euros cout; for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { cout -= (euros) (m_duals[plan->ha(k) + m_index[plan->m_i]*h_max()] * m_C.size()); for (powerplants2_t j: m_C) if (j!=plan->m_i) for (week_t h=std::max(week_t(0), plan->ha(k) + DA(plan->m_i,k) - m_Se + wlen_t(1)); h < plan->ha(k) + DA(plan->m_i,k) + m_Se and hm_date_outage + m_index[i]*h_max()] * m_C.size()); for (powerplants2_t j: m_C) if (j!=i) for (week_t h=std::max(week_t(0), noeud->m_date_campaign - m_Se + wlen_t(1)); h < noeud->m_date_campaign + m_Se and h("quantity"); m_C = lire_liste("set"); m_index.resize( I(), -1); size_t inv = 0 ; for (powerplants2_t i: m_C) { // enregistrement de cette contrainte dans les centrales concernées constraints(i).push_back(this); m_index[i] = inv++ ; } m_L .resize( m_C.back()+1 ); m_TU.resize( m_C.back()+1 ); for (powerplants2_t i: m_C) { if (lire_valeur("begin")!="period") throw string("section period manquante"); if (lire_valeur("powerplant")!=i) throw string("mauvais index de powerplant dans la section period"); m_L[i] = lire_liste("start" , 0, type2(i).K-1) ; m_TU[i]= lire_liste("duration", 0, type2(i).K-1) ; if (lire_valeur("end")!="period") throw string("end period manquant"); for (size_t l=0; l >( m_C.size(), vector(h_max(), 0) ); } double CConstraint19::concerne_other( week_t h, const CPlan * plan) { for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { if ( h >= plan->ha(k) + m_L[plan->m_i][k] and h < plan->ha(k) + m_L[plan->m_i][k] + m_TU[plan->m_i][k] ) { return 1 ; } } return 0 ; } double CConstraint19::borne( week_t ) { return m_Q ; } void CConstraint19::ajoute_plan(const CPlan * plan) { for ( size_t it_i=0; it_im_i) { for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { for (week_t h=plan->ha(k) + m_L[plan->m_i][k]; h < plan->ha(k) + m_L[plan->m_i][k] + m_TU[plan->m_i][k] and hm_date_outage + m_L[i][noeud->m_campaign]]); } void CConstraint19::prepareZoneVerticale(CPlexMutable* cplex) { cplex->addLigne( getNom(), h_max() ); cplex->setLigne( getNom() ); for (week_t w; waddToRHS(w, CPlexModel::LowerThan, m_Q); } m_duals.resize(h_max(), 0); } void CConstraint19::ajoute_plan(const CPlan* plan, CPlexMutable* cplex) { cplex->setLigne(getNom()); for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { for (week_t h=plan->ha(k) + m_L[plan->m_i][k]; hha(k) + m_L[plan->m_i][k] + m_TU[plan->m_i][k] and haddToZ(h, 0, 1); } } } euros CConstraint19::getCoutDual(const CPlan* plan) { /* nécessite l'appel préalable à enregistrerDuales */ euros cout; for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { for (week_t h=plan->ha(k) + m_L[plan->m_i][k]; hha(k) + m_L[plan->m_i][k] + m_TU[plan->m_i][k] and hm_date_outage + m_L[i][noeud->m_campaign]; hm_date_outage + m_L[i][noeud->m_campaign] + m_TU[i][noeud->m_campaign] and h("week"); // bizarre m_C = lire_liste("set"); m_index.resize( I(), -1); m_N = lire_valeur("max"); m_hmax = m_h + (wlen_t) 1; m_blocages = vector >( m_C.size(), vector(h_max(), 0) ); size_t idx=0; for ( powerplants2_t i: m_C) { // enregistrement de cette contrainte dans les centrales concernées constraints(i).push_back(this); m_index[i]=idx++; } } double CConstraint20::concerne_other( week_t h, const CPlan * plan) { if (h!=m_h) return 0 ; // bizarre for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { if ( h >= plan->ha(k) and h < plan->ha(k) + DA(plan->m_i, k)) { return 1 ; } } return 0 ; } double CConstraint20::borne( week_t h ) { return m_N ; } void CConstraint20::ajoute_plan(const CPlan * plan) { for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { if ( m_h >= plan->ha(k) and m_h < plan->ha(k) + DA(plan->m_i, k)) { for ( size_t it_i=0; it_im_i) { m_blocages[it_i][m_h] += 1/borne(m_h) ; } } } } } double CConstraint20::cout_blocage(powerplants2_t i, const CNoeud * noeud) { if (m_h>=noeud->m_date_outage and m_hm_date_campaign) return floor(m_blocages[m_index[i]][m_h]); else return 0; } void CConstraint20::prepareZoneVerticale(CPlexMutable* cplex) { cplex->addLigne( getNom(), 1 ); cplex->setLigne( getNom() ); cplex->addToRHS(0, CPlexModel::LowerThan, m_N); m_duals.resize(1, 0); } void CConstraint20::ajoute_plan(const CPlan* plan, CPlexMutable* cplex) { cplex->setLigne(getNom()); for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { if (m_h>=plan->ha(k) and m_h < plan->ha(k)+DA(plan->m_i, k)) cplex->addToZ(0, 0, 1); } } euros CConstraint20::getCoutDual(const CPlan* plan) { /* nécessite l'appel préalable à enregistrerDuales */ euros cout; for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { if (m_h>=plan->ha(k) and m_h < plan->ha(k)+DA(plan->m_i, k)) cout -= (euros) m_duals[0]; } return cout; } euros CConstraint20::cout_noeud(powerplants2_t i, const CNoeud* noeud) { euros cout; if (m_h>=noeud->m_date_outage and m_hm_date_campaign) cout -= (euros) m_duals[0]; return cout; } /** * 21 */ void CConstraint21::lire_contrainte_typee() { m_C = lire_liste("set"); m_index.resize( I(), -1); lire_intervalle("startend", m_IT.start, m_IT.end); m_IMAX = lire_valeur("max"); m_hmax = H() ; m_blocages = vector >( m_C.size(), vector(h_max(), 0) ); size_t idx=0; for ( powerplants2_t i: m_C) { // enregistrement de cette contrainte dans les centrales concernées constraints(i).push_back(this); m_index[i]=idx++; } } double CConstraint21::concerne_other( week_t h, const CPlan * plan) { for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { if ( h>=m_IT.start and h<=m_IT.end and h >= plan->ha(k) and h < plan->ha(k) + DA(plan->m_i, k) ) { return PMAX(plan->m_i, h).v ; } } return 0 ; } double CConstraint21::borne( week_t h ) { return m_IMAX.v ; } void CConstraint21::ajoute_plan(const CPlan * plan) { for ( size_t it_i=0; it_im_i) { for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { for (week_t h=std::max(m_IT.start, plan->ha(k)); h < std::min(plan->ha(k) + DA(plan->m_i, k), m_IT.end + (wlen_t)1) and hm_i, h).v / borne(h) ; } } } } } double CConstraint21::cout_blocage(powerplants2_t i, const CNoeud * noeud) { double blocage = 0 ; for (week_t h=std::max(m_IT.start, noeud->m_date_outage); h < std::min(noeud->m_date_campaign, m_IT.end + (wlen_t)1) and haddLigne( getNom(), h_max() ); cplex->setLigne( getNom() ); for (week_t w; waddToRHS(w, CPlexModel::LowerThan, m_IMAX.v); } m_duals.resize(h_max(), 0); } void CConstraint21::ajoute_plan(const CPlan* plan, CPlexMutable* cplex) { cplex->setLigne(getNom()); for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { for (week_t h =std::max(m_IT.start, plan->ha(k)); h<=std::min(m_IT.end , plan->ha(k)+DA(plan->m_i,k)-(wlen_t)1) and haddToZ(h, 0, PMAX(plan->m_i, h).v); } } } euros CConstraint21::getCoutDual(const CPlan* plan) { /* nécessite l'appel préalable à enregistrerDuales */ euros cout; for (campaign_t k=(campaign_t)0; (unsigned)km_ha.size(); k=(campaign_t)(k+1)) { for (week_t h =std::max(m_IT.start, plan->ha(k)); h<=std::min(m_IT.end , plan->ha(k)+DA(plan->m_i,k)-(wlen_t)1) and hm_i, h).v); } } return cout; } euros CConstraint21::cout_noeud(powerplants2_t i, const CNoeud* noeud) { euros cout; for (week_t h =std::max(m_IT.start, noeud->m_date_outage); h<=std::min(m_IT.end , noeud->m_date_campaign-(wlen_t)1) and hm_i)) c->ajoute_plan(plan); } double CConstraint::cout_blocage_contraintes_13_a_21(powerplants2_t i, const CNoeud * noeud) { double _cout = 0 ; for (CConstraint * c: constraints(i)) _cout += c->cout_blocage(i,noeud); return _cout ; } void CConstraint::prepare_contraintes_14_a_21(CPlexMutable* cplex) { for (constraint_t ct = C14; ct<=C21; ++ct) { for (size_t m=0; mprepareZoneVerticale(cplex); } } } void CConstraint::ajoute_plan_contraintes_14_a_21(const CPlan* plan, CPlexMutable* cplex) { for (CConstraint * c: constraints(plan->m_i)) c->ajoute_plan(plan, cplex); } euros CConstraint::cout_noeud_contraintes_14_a_21(powerplants2_t i, const CNoeud* noeud) { euros cout; if (noeud->m_type == TYPE_OUTAGE) for (CConstraint * c: constraints(i)) cout += c->cout_noeud(i,noeud); return cout; } void CConstraint::collecte_duales_14_a_21(CPlexMutable* cplex) { for (constraint_t ct = C14; ct<=C21; ++ct) { for (size_t m=0; menregistrerDuales(cplex); } } } euros CConstraint::getCoutDual_14_a_21(const CPlan* plan) { euros cout; for (CConstraint * c: constraints(plan->m_i)) cout += c->getCoutDual(plan); return cout; }