#include "DA.h" #include #include #ifndef EPSILON #define EPSILON 0.001 #endif #include static double s_infini = std::numeric_limits::infinity() ; using namespace std; void DualAscent::boucle(vector& u, vector & lambda, bool& BorneSup, const char*x) const { // lambda = vector(lambda.size(),0); int nbCol = cost.size(); int nbLig = b.size(); vector q = calculePoids(); vector L(nbCol, 0); double pas = 1; double meilleurZd = - s_infini; vector meilleursU(u); vector meilleursLambda(lambda); cout << "Cout des colonnes : "; for (int c = 0; c < cost.size(); c++) { cout << cost[c] << "\t" ;}cout << endl; // Recherche d'un borne sup BorneSup = testUB(); double UB; if (BorneSup) { UB = recherche_UB(); } int nbItMax = 50; for ( int nbIt=0 ; nbIt < nbItMax ; nbIt++ ) { u = DAcalc(lambda, L, q); vector x(nbCol, 0); vector s = sousgrad(x, u, lambda, L, q); //Calcul de Zd double zd = 0; double normeS = 0; for ( int i=0 ; i < nbLig ; i++ ) { #ifdef _DEBUG_LAMBDA if (nbIt ==0) { cout <<"lambda["< DualAscent::calculePoids() const { vector q(cost.size(), 0); for ( int j=0 ; j < cost.size() ; j++ ) { for ( int i=0 ; i < b.size() ; i++ ) { q[j] += a(j, i); } } return q; } vector DualAscent::DAcalc(const vector &lambda, vector &L,const vector &q ) const { vector u(b.size(), 0); //Calcul des L[j] for ( int j=0 ; j < L.size() ; j++ ) { L[j] = 0; for ( int i=0 ; i < b.size() ; i++ ) { L[j] += a(j, i) * lambda[i]; } } //Calcul des Ui for ( int i=0 ; i < b.size() ; i++ ) { double wmin = s_infini; for ( int j=0 ; j < L.size() ; j++ ) { if ( a(j, i) > 0 ) { double w = (cost[j]-L[j])/q[j]; wmin = (wmin < w) ? wmin : w; } } u[i] = wmin + lambda[i]; } return u; } vector DualAscent::sousgrad(vector &x, const vector &u, const vector &lambda, const vector &L, const vector &q) const { //Calcul de l'indexMin vector indexMin(b.size(), -1); for ( int i=0 ; i < b.size() ; i++ ) { double mini = s_infini; for ( int j=0 ; j < cost.size() ; j++ ) { if ( a(j, i) > 0 ) { double w = (cost[j]-L[j])/q[j]; if ( mini > w ) { mini = w; indexMin[i] = j; } } } } //Calcul de x //initialisation for ( int j=0 ; j < cost.size() ; j++ ) { x[j] = 0; } //Remplissage for ( int i=0 ; i < indexMin.size() ; i++) { x[indexMin[i]] += b[i]; } //Division for ( int j=0 ; j < cost.size() ; j++ ) { x[j] /= q[j]; } //Calcul de s vector s(b.size(), 0); for ( int i=0 ; i < s.size() ; i++ ) { for ( int j=0 ; j < cost.size() ; j++ ) { s[i] += x[j]*a(j, i); } s[i] -= b[i]; } return s; } void DualAscent::vireColonneThermique() { A.erase(A.begin()); recharge.erase(recharge.begin()); cost.erase(cost.begin()); reste.erase(reste.begin()); } // Test Borne Sup bool DualAscent::testUB () const { bool out = false; bool STOP = false; int compteur = 0; double SumProd; while (!STOP) { SumProd = 0; for (int l =1 ; l < cost.size() ; l++) { SumProd+=a(l,compteur); } out = (SumProd>=b[compteur]); STOP = (!out); compteur++; if (compteur==b.size()) { STOP = true; } } if (!(out)) { cout << "Sumprod : "<< SumProd<< " et b["<<(compteur-1)<<"] = "< choix (n,false); choix[0] = true ; // la première colonne est la colonne thermique vector SumProd (m,0); for (int k = b.size()-1;k>=0;k--) { if (SumProd[k]>=b[k]) {;} else { bool STOP = false; int compteur = 0 , index_min=-1; double cost_min = s_infini; while (!STOP) { if (!choix[compteur]) { // Colonne non déjà sélectionnée if (a(compteur,k) > 0) { // Colonne à production positive if (cost[compteur] < cost_min) { index_min=compteur; cost_min=cost[compteur]; } } } compteur++; if (compteur==n) { if (index_min>=0) { choix[index_min]=true; UB += cost_min; for (int aa=0;aa=b[k]); } } } } cout << "Calcul de borne Sup : "<