Opt.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2006-2008 by Antonello Lobianco                         *
00003  *   http://regmas.org                                                     *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 3 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 #include "Opt.h"
00021 #include <stdlib.h>
00022 
00023 #include <glpk.h>
00024 
00025 //#include <typeinfo>
00026 
00027 #include "Agent_base.h"
00028 #include "Agent_space.h"
00029 #include "RegData.h"
00030 #include "Pixel.h"
00031 #include "ModelObject.h"
00032 #include "ThreadManager.h"
00033 #include "Scheduler.h"
00034 
00035 using namespace std;
00036 
00037 Opt::Opt(ThreadManager* MTHREAD_h, Agent_base* AGENT_h){
00038     MTHREAD=MTHREAD_h;
00039     AGENT=AGENT_h;
00040     z=0;
00041     stat=0;
00042 }
00043 
00044 Opt::~Opt(){
00045 
00046 }
00047 
00051 void
00052 Opt::update(){
00053     updateActivities();
00054     updateResourceNames();
00055     updateResourceValues();
00056     //updateGlpkProblem();
00057     refreshGUI();
00058 }
00059 
00097 void
00098 Opt::updateActivities(){
00099     int nPlots;
00100     Agent_space* currentAgent;
00101 
00102     vector <Pixel* > plots;
00103     currentAgent = dynamic_cast<Agent_space*> (AGENT);
00104     //cout << typeid(AGENT).name()<<endl;
00105     if (currentAgent){
00106         plots = currentAgent->getPlots(PLOTS_ALL);
00107         nPlots = plots.size();
00108     }
00109     else{
00110         nPlots=0;
00111     }
00112     
00113     //int debugID = currentAgent->getAgentUniqueID();
00114 
00115     vector<RegActivities*> actMoulds = MTHREAD->RD->getRegActivities();
00116     vector<ModelObject*> objects     = MTHREAD->RD->getObjectsDefinitionVector();
00117 
00118     ACTS.clear(); //remove all elements
00119 
00120     // ACTIVITIES....
00121     for (uint i=0;i<actMoulds.size();i++){
00122         if(actMoulds.at(i)->getSpatiallyExplicit()){
00123             vector <int> requiredLandUseCodes = actMoulds.at(i)->getRequiredLandUseCodes();         // required any of them...
00124             string requiredObjectOnPlot = actMoulds.at(i)->getRequiredObjectOnPlot();
00125             string landUseCodesToken;
00126             //string requiredObjectsToken;
00127             for (uint j=0;j<requiredLandUseCodes.size();j++){
00128                 landUseCodesToken = landUseCodesToken + " " + i2s(requiredLandUseCodes.at(j));
00129             }
00130             // setting activities with spatial requirement...
00131             for (uint j=0;j<plots.size();j++){
00132                 unsigned int z;
00133                 //double debugID = plots[j]->getID();
00134                 string lusecode = d2s(plots.at(j)->getDoubleValue("landUse"));
00135                 bool fulfilledObjectRequirement = false;
00136                 z = landUseCodesToken.find(lusecode); //search the current pixel land use code if it is whitin the ones required by the current activity
00137                 // we already know this activity mould is spacial explicit and so requiredLandUseCodes.size() is > 0
00138                 if (z!=string::npos){ // z in not at the end of the string, means land use code founded!
00139                     // this pixel is one of those supporting this activity. Now we see if the pixel has all the required objects...
00140                     if (requiredObjectOnPlot != ""){ // -> this activity HAS object requirements...
00141                         vector <string> pixelsObjects = plots.at(j)->getIncludedObjectNames();
00142                         for (uint y=0;y<pixelsObjects.size();y++){
00143                             if ( pixelsObjects.at(y) == requiredObjectOnPlot) {
00144                                 fulfilledObjectRequirement = true;
00145                                 break;
00146                             }
00147                         }
00148                     }
00149                     else {
00150                         fulfilledObjectRequirement = true;
00151                     }
00152                     if (fulfilledObjectRequirement){
00153                         // OK, we add the activity mould on this plot !!
00154                         matrixActivities ACT;
00155                         ACT.name=actMoulds.at(i)->getName();
00156                         double plotID=plots.at(j)->getID();
00157                         string plotIDs = d2s(plotID);
00158                         ACT.fullName=actMoulds.at(i)->getName()+"_on_"+plotIDs;
00159                         //ACT.isSpatial=true;
00160                         ACT.isInvest = false;
00161                         ACT.q = 0;
00162                         ACT.objValue = actMoulds.at(i)->getMatrixGrossMargin();
00163                         vector <double> matrixCoefficients = actMoulds.at(i)->getMatrixCoefficients();
00164                         ACT.values = matrixCoefficients;
00165                         for (uint y=0;y<plots.size();y++){
00166                             ACT.values.push_back(0);
00167                         }
00168                         ACT.values.at(matrixCoefficients.size()+j)=1;
00169                         ACT.plotHost=plots.at(j);
00170                         ACT.actMould = actMoulds.at(i);
00171                         ACT.objMould = 0;
00172                         bool test=AGENT->filterActivity(&ACT); //filter the activity eg. inserting trasnport costs in the gm
00173                         if(test) ACTS.push_back(ACT);
00174                     }
00175                 }
00176             }
00177         }
00178         else {
00179             // setting activities without space requirements..
00180             matrixActivities ACT;
00181             ACT.name=actMoulds.at(i)->getName();
00182             ACT.fullName=actMoulds.at(i)->getName();
00183             ACT.isInvest = false;
00184             ACT.q = 0;
00185             ACT.objValue = actMoulds.at(i)->getMatrixGrossMargin();
00186             vector <double> matrixCoefficients = actMoulds.at(i)->getMatrixCoefficients();
00187             ACT.values = matrixCoefficients;
00188             for (uint y=0;y<plots.size();y++){
00189                 ACT.values.push_back(0);
00190             }
00191             ACT.plotHost=0;
00192             ACT.actMould = actMoulds.at(i);
00193             ACT.objMould = 0;
00194             bool test=AGENT->filterActivity(&ACT);//filter the activity eg. inserting trasnport costs in the gm
00195             if(test) ACTS.push_back(ACT);
00196         }
00197     }
00198 
00199     // NEW OBJECTS....
00200     for (uint i=0;i<objects.size();i++){
00201         if(objects.at(i)->getSpatiallyExplicit()){
00202             vector <int> requiredLandUseCodes = objects.at(i)->getRequiredLandUseCodes();          // required any of them...
00203             string landUseCodesToken;
00204             //string requiredObjectsToken;
00205             for (uint j=0;j<requiredLandUseCodes.size();j++){
00206                 landUseCodesToken = landUseCodesToken + " " + i2s(requiredLandUseCodes.at(j));
00207             }
00208             // setting activities with spatial requirement...
00209             for (uint j=0;j<plots.size();j++){
00210                 //double debugID = plots[j]->getID();
00211                 unsigned int z;
00212                 string lusecode = d2s(plots.at(j)->getDoubleValue("landUse"));
00213                 z = landUseCodesToken.find(lusecode); //search the current pixel land use code if it is whitin the ones required by the current activity
00214                 // we already know this activity mould is spacial explicit and so requiredLandUseCodes.size() is > 0
00215                 if (z!=string::npos){ // z in not at the end of the string, means land use code founded!
00216                     // we check that the plot doesn't already have the investment object we want offer:
00217                     vector <string> pixelsObjects = plots.at(j)->getIncludedObjectNames();
00218                     bool fulfilledObjectRequirement = true;
00219                     for (uint y=0;y<pixelsObjects.size();y++){
00220                         if ( pixelsObjects.at(y) == objects.at(i)->getName()) {
00221                             fulfilledObjectRequirement = false;
00222                             break;
00223                         }
00224                     }
00225                     if (fulfilledObjectRequirement){
00226                         // OK, we add the activity mould on this plot !!
00227                         matrixActivities ACT;
00228                         ACT.name=objects.at(i)->getName();
00229                         ACT.fullName=objects.at(i)->getName()+"_on_"+d2s(plots.at(j)->getID());
00230                         ACT.isInvest = true;
00231                         ACT.q = 0;
00232                         ACT.objValue = objects.at(i)->getMatrixGrossMargin();
00233                         vector <double> matrixCoefficients = objects.at(i)->getMatrixCoefficients();
00234                         ACT.values = matrixCoefficients;
00235                         for (uint y=0;y<plots.size();y++){
00236                             ACT.values.push_back(0);
00237                         }
00238                         ACT.values.at(matrixCoefficients.size()+j)=1;
00239                         ACT.plotHost=plots.at(j);
00240                         ACT.actMould = 0;
00241                         ACT.objMould = objects.at(i);
00242                         bool test=AGENT->filterActivity(&ACT);//filter the activity eg. inserting trasnport costs in the gm
00243                         if(test) ACTS.push_back(ACT);
00244                     }
00245                 }
00246             }
00247         }
00248         else {
00249             // setting activities without space requirements..
00250             matrixActivities ACT;
00251             ACT.name=objects.at(i)->getName();
00252             ACT.fullName=objects.at(i)->getName();
00253             ACT.isInvest = true;
00254             ACT.q = 0;
00255             ACT.objValue = objects.at(i)->getMatrixGrossMargin();
00256             vector <double> matrixCoefficients = objects.at(i)->getMatrixCoefficients();
00257             ACT.values = matrixCoefficients;
00258             for (uint y=0;y<plots.size();y++){
00259                 ACT.values.push_back(0);
00260             }
00261             ACT.plotHost=0;
00262             ACT.actMould = 0;
00263             ACT.objMould = objects.at(i);
00264             bool test=AGENT->filterActivity(&ACT);//filter the activity eg. inserting trasnport costs in the gm
00265             if(test) ACTS.push_back(ACT);
00266         }
00267     }
00268 };
00269 
00274 void
00275 Opt::updateResourceNames(){
00276 
00277     resourceNames.clear();
00278     resourceNames= MTHREAD->RD->getResourceNames();
00279     
00280     int nPlots;
00281     Agent_space* currentAgent;
00282     vector <Pixel* > plots;
00283     currentAgent = dynamic_cast<Agent_space*> (AGENT);
00284     if (currentAgent){
00285         plots=currentAgent->getPlots(PLOTS_ALL);
00286         nPlots=plots.size();
00287     }
00288     else{
00289         nPlots=0;
00290     }
00291     for (uint i=0;i<plots.size();i++){
00292         string name = "Plot_"+d2s(plots.at(i)->getID());
00293         resourceNames.push_back(name);
00294     }
00295 };
00296 
00308 void
00309 Opt::updateResourceValues(){
00310 
00311     resourceValues.clear();
00312     resourceValues.resize(resourceNames.size(),0);
00313 
00314     // ..then setting initial resources..
00315     for (int i=0;i<MTHREAD->RD->getResourceSize();i++){
00316         resourceValues.at(i) = AGENT->getResource(resourceNames.at(i));
00317     }
00318     //placing 1 for pixel resources...
00319     for (uint i=MTHREAD->RD->getResourceSize();i<resourceNames.size();i++){
00320         resourceValues[i] = 1;
00321     }   
00322 
00323 };
00324 
00325 /*
00326 // removed 20090701
00327 void
00328 Opt::updateGlpkProblem(){
00329     // ia[] -> row indexes; ja[]->column indexes; ar[]->corresponding values
00330     
00331     // As in Windows I can't allocate more than 120000 elements in the arrys (bho, why ????) I am first checking and emitting a warning if the array to allocate is so big
00332     int maxNZSpace = 2; //shuld be 1, 2 just to be sure...
00333     for (uint j=1;j<ACTS.size()+1;j++){
00334         for (uint i=1;i<resourceNames.size()+1;i++){
00335             if (ACTS[j-1].values[i-1] != 0){
00336                 maxNZSpace++;
00337             }
00338         }
00339     }   
00340     if(maxNZSpace >=120000){
00341         msgOut(MSG_WARNING, "Agent "+i2s(AGENT->getAgentUniqueID())+" has a huge matrix.. on MS Windows system this could lead to a crash.. u are advised!");
00342     }
00343 
00344     //int maxNZSpace= ACTS.size()*resourceNames.size()+1;
00345     int ia[maxNZSpace], ja[maxNZSpace];  // cool! Borland compiler didn't allow me array initialization from a variable !!
00346     double ar[maxNZSpace]; //array of the coefficients
00347 
00348     // deleting all rows and columns...
00349     int nRowsCurrentProblem = glp_get_num_rows(lpglpk);
00350     int nColsCurrentProblem = glp_get_num_cols(lpglpk);
00351     
00352     if(nRowsCurrentProblem>0){
00353         int num[nRowsCurrentProblem];
00354         for(int i=1;i<nRowsCurrentProblem+1;i++){
00355             num[i]=i;
00356         }
00357         glp_del_rows(lpglpk, nRowsCurrentProblem, num);
00358     }
00359     if(nColsCurrentProblem>0){
00360         int num[nColsCurrentProblem];
00361         for(int i=1;i<nColsCurrentProblem+1;i++){
00362             num[i]=i;
00363         }
00364         glp_del_cols(lpglpk, nColsCurrentProblem, num);
00365     }
00366 
00367     // adding rows and placing bounds:
00368     glp_add_rows(lpglpk, resourceNames.size());
00369     // checking if this year we are for forced to use ALL the land we have (cross-complain)
00370     bool fixedLand = MTHREAD->RD->getBoolSetting("fullLandUsage", DATA_NOW);
00371     for (uint i=1;i<resourceNames.size()+1;i++){
00372         if (((int)i)<MTHREAD->RD->getResourceSize()+1 || !fixedLand ){
00373             glp_set_row_bnds(lpglpk, i, GLP_UP, 0.0, resourceValues[i-1]); // <= setting the constrain upper limit
00374         }
00375         else {
00376             // the resource is a plot and we are forced to use it all..
00377             glp_set_row_bnds(lpglpk, i, GLP_FX, resourceValues[i-1], resourceValues[i-1]); // <= setting the constrain limit as fixed
00378         }
00379     }
00380 
00381 
00382     // adding columns, placing bounds and obj coefficients:
00383     glp_add_cols(lpglpk, ACTS.size());
00384     for (uint i=1;i<ACTS.size()+1;i++){
00385         glp_set_obj_coef(lpglpk, i, ACTS[i-1].objValue);
00386         // Investments are not made on a separate MIP. They are done in the same normal production MIP, in one go.
00387         // If we go for two separate MIPS, we would need to fix investments decision quantities to 0:
00388         //if (prod) {  // production lp, no investments
00389         //  if ((i-1)< prodcols)
00390         //      glp_set_col_bnds(lpglpk, i, GLP_LO, 0.0, 0.0); // proction: 0->+inf
00391         //  else
00392         //      glp_set_col_bnds(lpglpk, i, GLP_FX, 0.0, 0.0); // investments: fixed to 0
00393         //}
00394         //else { // normal lp
00395         glp_set_col_bnds(lpglpk, i, GLP_LO, 0.0, 0.0);
00396         //}
00397     }
00398     
00399     // creating the three arrays needed for lpx_load_matrix(): rows, column, value
00400     // zero coefficients are not allowed
00401     int nz_counter=1; // nz_conter stand for "non-zero counter"
00402     for (uint j=1;j<ACTS.size()+1;j++){
00403         for (uint i=1;i<resourceNames.size()+1;i++){
00404             if (ACTS[j-1].values[i-1] != 0){
00405                 ia[nz_counter] = i;
00406                 ja[nz_counter] = j;
00407                 ar[nz_counter] = ACTS[j-1].values[i-1];
00408                 nz_counter++;
00409             }
00410         }
00411     }
00412     // loading the constrain coefficient matrix..
00413     glp_load_matrix(lpglpk, nz_counter-1, ia, ja, ar);
00414 
00415     // setting integer parameters
00416     for (uint i=0;i<ACTS.size();i++){
00417         if (ACTS[i].isInvest){
00418             glp_set_col_kind(lpglpk, i+1, GLP_IV);
00419         }
00420     }
00421 };
00422 */
00423 
00424 void
00425 Opt::debug(string debugMessage, bool useCallCounter){
00426     int callCounter=0; // 20090701 removed static !
00427     string directoryToSave = MTHREAD->RD->getBaseDirectory()+MTHREAD->RD->getOutputDirectory()+"debugMatrices/";
00428     string filenameToSave = "";
00429     if (useCallCounter){
00430         filenameToSave  = "ag"+i2s(AGENT->getAgentUniqueID())+"_-_"+i2s(MTHREAD->SCD->getYear())+"_-_"+i2s(callCounter)+"_-_"+debugMessage+".csv";
00431     } else {
00432         filenameToSave  = "ag"+i2s(AGENT->getAgentUniqueID())+"_-_"+i2s(MTHREAD->SCD->getYear())+"_-_"+debugMessage+".csv";
00433     }
00434     string fullFilename = directoryToSave+filenameToSave;
00435     ofstream out;
00436     out.open(fullFilename.c_str(), ios::out); //ios::app to append..
00437     if (!out){ msgOut(MSG_ERROR,"Error in opening the file "+fullFilename+".");}
00438     out << "*** Debug Matrix ***"<<  "\n\n";
00439     out << "Optimal Value (Z);Stat;Year;Agent;Mould;Msg" << "\n";
00440     out << z << ";" << stat << ";" << MTHREAD->SCD->getYear() << ";" << AGENT->getAgentUniqueID() << ";" << AGENT->getMouldLocalID() << ";" << debugMessage << "\n\n";
00441     
00442     // printing activity names..
00443     out << ";RESOURCES;;";
00444     for (uint i=0;i<ACTS.size();i++){
00445         out << ACTS.at(i).fullName << ";" ;
00446     }
00447     out << "\n";
00448     // printing activity type (continuous/intger)..
00449     out << "type   -->;;;";
00450     for (uint i=0;i<ACTS.size();i++){
00451         out << ACTS.at(i).isInvest << ";" ;
00452     }
00453     out << "\n";
00454     // printing target function coefficients..
00455     out << "gm     -->;;;";
00456     for (uint i=0;i<ACTS.size();i++){
00457         out << ACTS.at(i).objValue << ";" ;
00458     }
00459     out << "\n";
00460     // printing (solved) optimal quantities..
00461     out << "opt q  -->;;;";
00462     for (uint i=0;i<ACTS.size();i++){
00463         out << ACTS.at(i).q << ";" ;
00464     }
00465     out << "\n";
00466     out << "Resources:;"<<"\n";
00467 
00468     for (uint i=0;i<resourceNames.size();i++){
00469         out << resourceNames.at(i) << ";" ;
00470         out << resourceValues.at(i) << ";;" ;
00471         for (uint j=0;j<ACTS.size();j++){
00472             out << ACTS.at(j).values.at(i) << ";" ;
00473         }
00474         out << "\n";
00475     }
00476     out << "\n\n";
00477 
00478     out.close();
00479     callCounter++;
00480 };
00481 
00487 void
00488 Opt::solve(){
00489     
00490     solveGlpk();
00491     return;
00492 
00493 }
00494 
00495 
00501 void
00502 Opt::solveGlpk(){
00503     bool fixedLand;
00504     int resourceSize;
00505     //QMutex localMutex1, localMutex2, localMutex3; // 20090703 mutexes must be shared along several instances !This is wrong!
00506     //localMutex1.lock();
00507     // checking if this year we are for forced to use ALL the land we have (cross-complain)
00508     fixedLand = MTHREAD->RD->getBoolSetting("fullLandUsage", DATA_NOW);
00509     resourceSize = MTHREAD->RD->getResourceSize();
00510     //localMutex1.unlock();
00511 
00512     // ###### FROM OLD HEADER/CONSTRUCTOR... #######
00513     glp_prob*  lpglpk; // pointer to the glpk problem
00514     glp_iocp*  parm; // parameter structur for glp_intopt routine (from glpk v. >= 4.20)
00515     lpglpk = glp_create_prob();
00516     glp_set_prob_name(lpglpk, "farmerProblem");
00517     glp_set_obj_dir(lpglpk, GLP_MAX);
00518     // Suppress Output from glpk
00519     //lpx_set_int_parm(lpglpk, LPX_K_MSGLEV, 0); //deprecated
00520     glp_term_out(GLP_OFF); //new, it also delete the "crashing..." messages that is a glpk terminology meaning totally safe and different thing than normal "crashing"
00521     // for glp_intopt() function, from glpk >= 4.20
00522     parm = new glp_iocp;
00523     //parm = NULL;
00524     glp_init_iocp(parm);
00525     // Suppress Output from glpk
00526     parm->msg_lev = GLP_MSG_OFF;
00527 
00528 
00529 
00530     // ###### FROM OLD updateGlpkProblem.. ######
00531     // ia[] -> row indexes; ja[]->column indexes; ar[]->corresponding values
00532     
00533     // As in Windows I can't allocate more than 120000 elements in the arrys (bho, why ????) I am first checking and emitting a warning if the array to allocate is so big
00534     int maxNZSpace = 2; //shuld be 1, 2 just to be sure...
00535     for (uint j=1;j<ACTS.size()+1;j++){
00536         for (uint i=1;i<resourceNames.size()+1;i++){
00537             if (ACTS[j-1].values[i-1] != 0){
00538                 maxNZSpace++;
00539             }
00540         }
00541     }   
00542     //localMutex2.lock();
00543     if(maxNZSpace >=120000){
00544         msgOut(MSG_WARNING, "Agent "+i2s(AGENT->getAgentUniqueID())+" has a huge matrix.. on MS Windows system this could lead to a crash.. u are advised!");
00545     }
00546     //localMutex2.unlock();
00547 
00548     //int maxNZSpace= ACTS.size()*resourceNames.size()+1;
00549     int ia[maxNZSpace], ja[maxNZSpace];  // cool! Borland compiler didn't allow me array initialization from a variable !!
00550     double ar[maxNZSpace]; //array of the coefficients
00551 
00552     // deleting all rows and columns...
00553     int nRowsCurrentProblem = glp_get_num_rows(lpglpk);
00554     int nColsCurrentProblem = glp_get_num_cols(lpglpk);
00555     
00556     if(nRowsCurrentProblem>0){
00557         int num[nRowsCurrentProblem];
00558         for(int i=1;i<nRowsCurrentProblem+1;i++){
00559             num[i]=i;
00560         }
00561         glp_del_rows(lpglpk, nRowsCurrentProblem, num);
00562     }
00563     if(nColsCurrentProblem>0){
00564         int num[nColsCurrentProblem];
00565         for(int i=1;i<nColsCurrentProblem+1;i++){
00566             num[i]=i;
00567         }
00568         glp_del_cols(lpglpk, nColsCurrentProblem, num);
00569     }
00570 
00571     // adding rows and placing bounds:
00572     glp_add_rows(lpglpk, resourceNames.size());
00573     
00574 
00575     for (uint i=1;i<resourceNames.size()+1;i++){
00576         if (((int)i)<resourceSize+1 || !fixedLand ){
00577             glp_set_row_bnds(lpglpk, i, GLP_UP, 0.0, resourceValues[i-1]); // <= setting the constrain upper limit
00578         }
00579         else {
00580             // the resource is a plot and we are forced to use it all..
00581             glp_set_row_bnds(lpglpk, i, GLP_FX, resourceValues[i-1], resourceValues[i-1]); // <= setting the constrain limit as fixed
00582         }
00583     }
00584 
00585 
00586     // adding columns, placing bounds and obj coefficients:
00587     glp_add_cols(lpglpk, ACTS.size());
00588     for (uint i=1;i<ACTS.size()+1;i++){
00589         glp_set_obj_coef(lpglpk, i, ACTS[i-1].objValue);
00590         // Investments are not made on a separate MIP. They are done in the same normal production MIP, in one go.
00591         // If we go for two separate MIPS, we would need to fix investments decision quantities to 0:
00592         //if (prod) {  // production lp, no investments
00593         //  if ((i-1)< prodcols)
00594         //      glp_set_col_bnds(lpglpk, i, GLP_LO, 0.0, 0.0); // proction: 0->+inf
00595         //  else
00596         //      glp_set_col_bnds(lpglpk, i, GLP_FX, 0.0, 0.0); // investments: fixed to 0
00597         //}
00598         //else { // normal lp
00599         glp_set_col_bnds(lpglpk, i, GLP_LO, 0.0, 0.0);
00600         //}
00601     }
00602     
00603     // creating the three arrays needed for lpx_load_matrix(): rows, column, value
00604     // zero coefficients are not allowed
00605     int nz_counter=1; // nz_conter stand for "non-zero counter"
00606     for (uint j=1;j<ACTS.size()+1;j++){
00607         for (uint i=1;i<resourceNames.size()+1;i++){
00608             if (ACTS[j-1].values[i-1] != 0){
00609                 ia[nz_counter] = i;
00610                 ja[nz_counter] = j;
00611                 ar[nz_counter] = ACTS[j-1].values[i-1];
00612                 nz_counter++;
00613             }
00614         }
00615     }
00616     // loading the constrain coefficient matrix..
00617     glp_load_matrix(lpglpk, nz_counter-1, ia, ja, ar);
00618 
00619     // setting integer parameters
00620     for (uint i=0;i<ACTS.size();i++){
00621         if (ACTS[i].isInvest){
00622             glp_set_col_kind(lpglpk, i+1, GLP_IV);
00623         }
00624     }
00625 
00626     // ###### FROM OLD SOLVE FUNCTION... ######
00627     //recreate the standard bases..
00628     //glp_adv_basis(lpglpk,0); //no longer needed
00629 
00630     // solving the problem with only continuous variables..
00631     stat=lpx_simplex(lpglpk);
00632 
00633     // setting the problem as integer
00634     //lpx_set_class(lpglpk, LPX_MIP);
00635 
00636     // solving the problem with the integer variables
00637     stat=lpx_integer(lpglpk); // old 11.? seconds . Now only 8.45 sec
00638 
00639     //stat=glp_intopt(lpglpk, parm); // 8.60 seconds, like lpx_integer()
00640 
00641     //stat=lpx_intopt(lpglpk); I can't shut down the messages, so very slow
00642 
00643      //lpx_intopt(lpglpk);  // as of version 4.9 lpx_intopt is buggy (we discover it ;-) )
00644     z = glp_mip_obj_val(lpglpk);
00645 
00646     // retrive activity levels...
00647     for (uint i=0; i<ACTS.size(); i++){
00648         ACTS[i].q = glp_mip_col_val(lpglpk, i+1);  // I need to be fast here !!
00649     }
00650 
00651     //refreshGUI();
00652 
00653     // ###### FROM OLD DESTRUCTOR... ######
00654     glp_delete_prob(lpglpk);
00655     delete parm;
00656 
00657 }
00658 
00665 void
00666 Opt::saveToCache(){
00667     cachedZ = z;
00668     for (uint i=0;i<ACTS.size();i++){
00669         ACTS[i].cachedQ = ACTS[i].q; // I need to be fast here !!
00670     }
00671     cachedStat = stat;
00672 }
00673 
00680 void
00681 Opt::restoreFromCache(){
00682     z = cachedZ;
00683     for (uint i=0;i<ACTS.size();i++){
00684         ACTS[i].q = ACTS[i].cachedQ;  // I need to be fast here !!
00685     }
00686     stat = cachedStat;
00687 }
00688 
00697 void
00698 Opt::addPixel(const Pixel* px_h){
00699 
00700     Agent_space* currentAgent;
00701     currentAgent = dynamic_cast<Agent_space*> (AGENT);
00702     //QMutex localMutex;
00703 
00704 
00705     if (currentAgent){ // if our agent is not spatially explicit we don't have anything to do ;-)
00706         //localMutex.lock();
00707         double plotId;
00708         vector<RegActivities*> actMoulds;
00709         vector<ModelObject*> objects;
00710         double landUse;
00711         string lusecode;
00712 
00713 
00714         plotId=px_h->getID();
00715         actMoulds = MTHREAD->RD->getRegActivities();
00716         objects     = MTHREAD->RD->getObjectsDefinitionVector();
00717         lusecode = d2s(px_h->getDoubleValue("landUse"));
00718         //localMutex.unlock();
00719         
00720         actsAddedOnLastPixel=0;
00721         resourceNames.push_back("Plot_"+d2s(plotId));
00722         resourceValues.push_back(1);
00723 
00724         for (uint i=0;i<ACTS.size();i++){
00725             ACTS.at(i).values.push_back(0);
00726         }
00727         
00728         /*if (MTHREAD->RD->getBoolSetting("fullLandUsage", DATA_NOW)){ // we are in a "forced to use all land" mode..
00729             addResourceToGlpk(GLP_FX, 1, 1);
00730         } else {
00731             addResourceToGlpk(GLP_UP, 0, 1);
00732         }*/
00733 
00734 
00735 
00736 
00737         // adding spatial activities...
00738         for (uint i=0;i<actMoulds.size();i++){
00739             if(actMoulds.at(i)->getSpatiallyExplicit()){
00740                 vector <int> requiredLandUseCodes = actMoulds.at(i)->getRequiredLandUseCodes();         // required any of them...
00741                 string requiredObjectOnPlot = actMoulds.at(i)->getRequiredObjectOnPlot();    // required ALL of them...
00742                 string landUseCodesToken;
00743                 //string requiredObjectsToken;
00744                 for (uint j=0;j<requiredLandUseCodes.size();j++){
00745                     landUseCodesToken = landUseCodesToken + " " + i2s(requiredLandUseCodes.at(j));
00746                 }
00747                 unsigned int z;
00748                 bool fulfilledObjectRequirement = false; // bug, 20071123, Antonello
00749                 z = landUseCodesToken.find(lusecode); //search the pixel land use code if it is whitin the ones required by the current activity
00750                 // we already know this activity mould is spacial explicit and so requiredLandUseCodes.size() is > 0
00751                 if (z!=string::npos){ // z in not at the end of the string, means land use code founded!
00752                     // this pixel is one of those supporting this activity. Now we see if the pixel has all the required objects...
00753                     if (requiredObjectOnPlot != ""){
00754                         vector <string> pixelsObjects = px_h->getIncludedObjectNames();
00755                         for (uint y=0;y<pixelsObjects.size();y++){
00756                             if ( pixelsObjects.at(y) == requiredObjectOnPlot) {
00757                                 fulfilledObjectRequirement = true;
00758                                 break;
00759                             }
00760                         }
00761                     }
00762                     else {
00763                         fulfilledObjectRequirement = true;
00764                     }
00765                     if (fulfilledObjectRequirement){
00766                         // OK, we add the activity mould on this plot !!
00767                         matrixActivities ACT;
00768                         ACT.name=actMoulds.at(i)->getName();
00769                         ACT.fullName=actMoulds.at(i)->getName()+"_on_"+d2s(px_h->getID());
00770                         ACT.isInvest = false;
00771                         ACT.q = 0;
00772                         ACT.objValue = actMoulds.at(i)->getMatrixGrossMargin();
00773                         vector <double> matrixCoefficients = actMoulds.at(i)->getMatrixCoefficients();
00774                         ACT.values = matrixCoefficients;
00775                         for (int y=0;y<currentAgent->getNPlots();y++){
00776                             ACT.values.push_back(0);
00777                         }
00778                         ACT.values.push_back(1);
00779                         ACT.plotHost=px_h;
00780                         ACT.actMould = actMoulds.at(i); // bug, 20071123, Antonello
00781                         ACT.objMould = 0;
00782                         bool test=AGENT->filterActivity(&ACT); //filter the activity eg. inserting trasnport costs in the gm
00783                         if(test) ACTS.push_back(ACT);
00784                         actsAddedOnLastPixel++;
00785                         //addActivityToGlpk(&ACT);
00786                     }
00787                 }
00788             }
00789         }
00790 
00791         // adding spatial investment objects
00792         //DONE: add spatial investment objects
00793         for (uint i=0;i<objects.size();i++){
00794             if(objects.at(i)->getSpatiallyExplicit()){
00795                 vector <int> requiredLandUseCodes = objects.at(i)->getRequiredLandUseCodes();          // required any of them...
00796                 string landUseCodesToken;
00797                 //string requiredObjectsToken;
00798                 for (uint j=0;j<requiredLandUseCodes.size();j++){
00799                     landUseCodesToken = landUseCodesToken + " " + i2s(requiredLandUseCodes.at(j));
00800                 }
00801                 // setting activities with spatial requirement...
00802                 unsigned int z;
00803                 string lusecode = d2s(px_h->getDoubleValue("landUse"));
00804                 z = landUseCodesToken.find(lusecode); //search the current pixel land use code if it is whitin the ones required by the current activity
00805                 // we already know this activity mould is spacial explicit and so requiredLandUseCodes.size() is > 0
00806                 if (z!=string::npos){ // z in not at the end of the string, means land use code founded!
00807                     // we check that the plot doesn't already have the investment object we want offer:
00808                     vector <string> pixelsObjects = px_h->getIncludedObjectNames();
00809                     bool fulfilledObjectRequirement = true;
00810                     for (uint y=0;y<pixelsObjects.size();y++){
00811                         if ( pixelsObjects.at(y) == objects.at(i)->getName()) {
00812                             fulfilledObjectRequirement = false;
00813                             break;
00814                         }
00815                     }
00816                     if (fulfilledObjectRequirement){
00817                         // OK, we add the activity mould on this plot !!
00818                         matrixActivities ACT;
00819                         ACT.name=objects.at(i)->getName();
00820                         ACT.fullName=objects.at(i)->getName()+"_on_"+d2s(px_h->getID());
00821                         ACT.isInvest = true;
00822                         ACT.q = 0;
00823                         ACT.objValue = objects.at(i)->getMatrixGrossMargin();
00824                         vector <double> matrixCoefficients = objects.at(i)->getMatrixCoefficients();
00825                         ACT.values = matrixCoefficients;
00826                         for (int y=0;y<currentAgent->getNPlots();y++){
00827                             ACT.values.push_back(0);
00828                         }
00829                         ACT.values.push_back(1);
00830                         ACT.plotHost=px_h;
00831                         ACT.actMould = 0;
00832                         ACT.objMould = objects.at(i);
00833                         bool test=AGENT->filterActivity(&ACT);//filter the activity eg. inserting trasnport costs in the gm
00834                         if(test) ACTS.push_back(ACT);
00835                         actsAddedOnLastPixel++;
00836                         //addActivityToGlpk(&ACT);
00837                     }
00838                 }
00839             }   
00840         }
00841         //localMutex.unlock();
00842     }
00843 };
00844 
00845 /*
00846 // removed 20090701
00847 void
00848 Opt::addResourceToGlpk(int glpkBoundType, double minValue, double maxValue){
00849     int newAddedRowNumber = glp_add_rows(lpglpk,1);
00850     glp_set_row_bnds(lpglpk, newAddedRowNumber, glpkBoundType, minValue, maxValue);
00851 };
00852 
00853 void
00854 Opt::addActivityToGlpk(const matrixActivities* ACT){
00855     int newAddedColumnNumber = glp_add_cols(lpglpk, 1);
00856     glp_set_obj_coef(lpglpk, newAddedColumnNumber, ACT->objValue);
00857     glp_set_col_bnds(lpglpk, newAddedColumnNumber, GLP_LO, 0.0, 0.0);
00858 
00859     int maxSize = ACT->values.size()+1;
00860     int lpCounters[maxSize+1];
00861     double lpValues[maxSize+1];
00862 
00863     int nz_counter=1; // nz_conter stand for "non-zero counter"
00864     for(int i=1;i<maxSize;i++){
00865         if(ACT->values[i-1] != 0){
00866             lpCounters[nz_counter] = i;
00867             lpValues[nz_counter] = ACT->values[i-1];
00868             nz_counter++;
00869         }
00870     }
00871     nz_counter--;
00872     glp_set_mat_col(lpglpk, newAddedColumnNumber, nz_counter, lpCounters, lpValues);
00874     if (ACT->isInvest){
00875         glp_set_col_kind(lpglpk, newAddedColumnNumber, GLP_IV);
00876     }
00877 };
00878 */
00879 
00886 void
00887 Opt::removeLastAddedPixel(){
00888 
00889     int temp[1+1];
00890     temp[0] = resourceNames.size();
00891     temp[1] = resourceNames.size();
00892     //glp_del_rows(lpglpk, 1, temp); // removing last row from glpk object 
00893     resourceNames.pop_back();
00894     resourceValues.pop_back();
00895 
00896     //removing 1 row...
00897     for (uint i=0;i<ACTS.size();i++){
00898         ACTS.at(i).values.pop_back();
00899     }
00900     // removing actsAddedOnLastPixel columns...
00901     for (int i=0;i<actsAddedOnLastPixel;i++){
00902         temp[0] = ACTS.size();
00903         temp[1] = ACTS.size();
00904         //glp_del_cols(lpglpk,1,temp); // deleting the last one. next line assures that ACTS.size() change correctly 
00905         ACTS.pop_back();
00906     }
00907 }
00908 
00909 vector <matrixActivities*>
00910 Opt::getActs(){
00911     vector <matrixActivities*> toReturn;
00912     for (uint i=0;i< ACTS.size();i++){
00913         toReturn.push_back(&ACTS[i]);
00914     }
00915     return toReturn;
00916 }
00917 
00918 void
00919 Opt::test(){
00920     //test for GLPK
00921     glp_prob *lp;
00922     int ia[1+1000], ja[1+1000];
00923     double ar[1+1000], z;
00924     lp = glp_create_prob();
00925     glp_set_prob_name(lp, "sample");
00926     glp_set_obj_dir(lp, GLP_MAX);
00927     glp_add_rows(lp, 3);
00928     glp_set_row_name(lp, 1, "p");
00929     glp_set_row_bnds(lp, 1, GLP_UP, 0.0, 100.0);
00930     glp_set_row_name(lp, 2, "q");
00931     glp_set_row_bnds(lp, 2, GLP_UP, 0.0, 600.0);
00932     glp_set_row_name(lp, 3, "r");
00933     glp_set_row_bnds(lp, 3, GLP_UP, 0.0, 300.0);
00934     glp_add_cols(lp, 3);
00935     glp_set_col_name(lp, 1, "x1");
00936     glp_set_col_bnds(lp, 1, GLP_LO, 0.0, 0.0);
00937     glp_set_obj_coef(lp, 1, 10.0);
00938     glp_set_col_name(lp, 2, "x2");
00939     glp_set_col_bnds(lp, 2, GLP_LO, 0.0, 0.0);
00940     glp_set_obj_coef(lp, 2, 6.0);
00941     glp_set_col_name(lp, 3, "x3");
00942     glp_set_col_bnds(lp, 3, GLP_LO, 0.0, 0.0);
00943     glp_set_obj_coef(lp, 3, 4.0);
00944     ia[1] = 1, ja[1] = 1, ar[1] = 1.0; /* a[1,1] = 1 */
00945     ia[2] = 1, ja[2] = 2, ar[2] = 1.0; /* a[1,2] = 1 */
00946     ia[3] = 1, ja[3] = 3, ar[3] = 1.0; /* a[1,3] = 1 */
00947     ia[4] = 2, ja[4] = 1, ar[4] = 10.0; /* a[2,1] = 10 */
00948     ia[5] = 3, ja[5] = 1, ar[5] = 2.0; /* a[3,1] = 2 */
00949     ia[6] = 2, ja[6] = 2, ar[6] = 4.0; /* a[2,2] = 4 */
00950     ia[7] = 3, ja[7] = 2, ar[7] = 2.0; /* a[3,2] = 2 */
00951     ia[8] = 2, ja[8] = 3, ar[8] = 5.0; /* a[2,3] = 5 */
00952     ia[9] = 3, ja[9] = 3, ar[9] = 6.0; /* a[3,3] = 6 */
00953     glp_load_matrix(lp, 9, ia, ja, ar);
00954     // Suppress Output from glpk
00955     lpx_set_int_parm(lp, LPX_K_MSGLEV, 0);
00956     lpx_simplex(lp);   // solve with simplex method
00957 
00958     // setting the problem as integer..
00959     lpx_set_class(lp, LPX_MIP);
00960     // setting 2nd row as integer
00961     lpx_set_col_kind(lp, 2, LPX_IV);
00962 
00963     // solving the problem with the integer variables
00964     lpx_integer(lp);
00965     z = lpx_mip_obj_val(lp);
00966 
00967     //lpx_interior(lp);  // solve with interior points method
00968     //z = glp_get_obj_val(lp); // simplex
00969     //z = glp_ipt_obj_val(lp); // interior points
00970     //x1 = glp_get_col_prim(lp, 1);
00971     //x2 = glp_get_col_prim(lp, 2);
00972     //x3 = glp_get_col_prim(lp, 3);
00973     //printf("\nz = %g; x1 = %g; x2 = %g; x3 = %g\n",
00974     //  z, x1, x2, x3);
00975     msgOut(MSG_DEBUG, "Optimal value is: "+d2s(z));
00976     glp_delete_prob(lp);
00977 }
00978 
00979 double
00980 Opt::getActivityObjValue(string name_h){
00981     for (uint i=0;i<ACTS.size();i++){
00982         if(ACTS.at(i).fullName == name_h){
00983             return ACTS.at(i).objValue;
00984         }
00985     }
00986     msgOut(MSG_ERROR, "Activity "+name_h+" not found. Returning 0");
00987     return 0;
00988 }