Manager_farmers.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 <math.h>
00021 
00022 #include "Manager_farmers.h"
00023 #include "RegData.h"
00024 #include "Agent_farmer.h"
00025 #include "SuperAgentManager.h"
00026 //#include "Pixel.h"
00027 #include "Opt.h"
00028 #include "Init.h"
00029 #include "ThreadManager.h"
00030 #include "Output.h"
00031 #include "Scheduler.h"
00032 
00033 
00034 //constructor
00035 Manager_farmers::Manager_farmers(ThreadManager* MTHREAD_h, string name_h) : Manager_space(MTHREAD_h, name_h){
00036     msgOut(MSG_DEBUG,"Manager_farmers::Manager_farmers");
00037     collectorAgent = new Agent_farmer(MTHREAD_h, -managerID-1, ((Manager_base*) this));
00038 }
00039 
00040 //destructor
00041 Manager_farmers::~Manager_farmers(){
00042     delete collectorAgent;
00043 }
00044 
00045 //functions:
00051 void
00052 Manager_farmers::setAgentMoulds(){
00053 
00054     msgOut(MSG_DEBUG,"Setting farmer moulds..");
00055     LLData table = MTHREAD->RD->getTable("farmers");
00056 
00057     for (int i=0; i<table.nrecords();i++){
00058         Agent_farmer* FARMER = new Agent_farmer(MTHREAD, this);
00059         FARMER->setMouldLocalID(getNewMouldLocalID());
00060         FARMER->setComments(table.getData(i,"comments"));
00061         FARMER->setFadnID(table.getData(i,"fadnID"));
00062         FARMER->setMouldCoeff(s2i(table.getData(i,"upsCoeff")));
00063         FARMER->setFarmType(table.getData(i,"farmType"));
00064         FARMER->setHomeLandUseCode(s2i(table.getData(i,"homeLandUseCode")));
00065         FARMER->setLandCapital(s2d(table.getData(i,"landCapital")));
00066         FARMER->setInitialDecPayment(s2d(table.getData(i,"initialDecPayment")));
00067         if (MTHREAD->RD->getBoolSetting("useAgrRegions")){
00068             FARMER->setAgrRegionNumber(s2i(table.getData(i,"agrRegionNumber")));
00069         } else {
00070             FARMER->setAgrRegionNumber(0);
00071         }
00072         vector <string> resources = MTHREAD->RD->getResourceNames();
00073         for (uint j=0;j<resources.size();j++){
00074             double value = s2d(table.getData(i,resources.at(j)));
00075             FARMER->initialResources.insert(pair<string, double>(resources.at(j),value));
00076         }
00077         vector <int> agrLandTypes = MTHREAD->RD->getIntVectorSetting("agrLandTypes");
00078         for (uint z=0;z<agrLandTypes.size();z++){
00079             string rentedName = "land_r_"+i2s(agrLandTypes.at(z));
00080             string ownerName = "land_o_"+i2s(agrLandTypes.at(z));
00081             double rentedValue = s2d(table.getData(i,rentedName));
00082             double ownedValue = s2d(table.getData(i,ownerName));
00083             FARMER->initialRentedPlots.insert(pair<int, double>(agrLandTypes.at(z),rentedValue));
00084             FARMER->initialOwnedPlots.insert(pair<int, double>(agrLandTypes.at(z),ownedValue));
00085         }
00086         agentsMoulds.push_back(FARMER);
00087     }
00088 
00089     /*
00090 
00091     string directory;
00092     string filename;
00093     string filename_complete;
00094     vector<IFiles> iFilesVector = MTHREAD->RD->getIFilesVector();
00095     for (uint i=0; i<iFilesVector.size(); i++){
00096         if (iFilesVector.at(i).type == "farmers"){
00097             directory=iFilesVector.at(i).directory;
00098             filename=iFilesVector.at(i).name;
00099             break;
00100         }
00101     }
00102     string baseDirectory=MTHREAD->RD->getBaseDirectory();
00103     filename_complete = baseDirectory+directory+filename;
00104     InputNode objectDocument;
00105     msgOut(MSG_DEBUG, filename_complete);
00106     bool test=objectDocument.setWorkingFile(filename_complete);
00107     if (!test){msgOut(MSG_CRITICAL_ERROR, "Error opening the agents definition file "+filename_complete);}
00108 
00109     vector<InputNode> nodes = objectDocument.getNodesByName("record");
00110 
00111     for (uint i=0; i<nodes.size();i++){
00112         Agent_farmer* FARMER = new Agent_farmer(MTHREAD, this);
00113         FARMER->setMouldLocalID(getNewMouldLocalID());
00114         FARMER->setComments(nodes.at(i).getNodeByName("comments").getStringContent());
00115         FARMER->setFadnID(nodes.at(i).getNodeByName("fadnID").getStringContent());
00116         FARMER->setMouldCoeff(nodes.at(i).getNodeByName("upsCoeff").getIntContent());
00117         FARMER->setFarmType(nodes.at(i).getNodeByName("farmType").getStringContent());
00118         FARMER->setHomeLandUseCode(nodes.at(i).getNodeByName("homeLandUseCode").getIntContent());
00119         FARMER->setLandCapital(nodes.at(i).getNodeByName("landCapital").getDoubleContent());
00120         FARMER->setInitialDecPayment(nodes.at(i).getNodeByName("initialDecPayment").getDoubleContent());
00121 
00122         vector <string> resources = MTHREAD->RD->getResourceNames();
00123         for (uint j=0;j<resources.size();j++){
00124             double value = nodes.at(i).getNodeByName(resources.at(j)).getDoubleContent();
00125             FARMER->initialResources.insert(pair<string, double>(resources.at(j),value));
00126         }
00127         vector <int> agrLandTypes = MTHREAD->RD->getIntVectorSetting("agrLandTypes");
00128         for (uint z=0;z<agrLandTypes.size();z++){
00129             string rentedName = "land_r_"+i2s(agrLandTypes.at(z));
00130             string ownerName = "land_o_"+i2s(agrLandTypes.at(z));
00131             double rentedValue = nodes.at(i).getNodeByName(rentedName).getDoubleContent();
00132             double ownedValue = nodes.at(i).getNodeByName(ownerName).getDoubleContent();
00133             FARMER->initialRentedPlots.insert(pair<int, double>(agrLandTypes.at(z),rentedValue));
00134             FARMER->initialOwnedPlots.insert(pair<int, double>(agrLandTypes.at(z),ownedValue));
00135         }
00136         agentsMoulds.push_back(FARMER);
00137     }
00138     */
00139 }
00140 
00145 void
00146 Manager_farmers::riseMyAgents(){
00147     msgOut(MSG_DEBUG,"Rising farmer agents..");
00148     // about 5700 agents creted here..
00149     for (uint i=0;i<agentsMoulds.size();i++){
00150         Agent_farmer * currentAgent = ((Agent_farmer*)agentsMoulds.at(i));
00151         for (int z=0;z<currentAgent->getMouldCoeff();z++){ // the mould coefficient change if we are in the subregion mode !!!
00152             Agent_farmer* FARMER= new Agent_farmer(MTHREAD, MTHREAD->SAM->getNewUniqueAgentID(), this);
00153             FARMER->setAgentLocalID(getNewAgentLocalID());
00154             FARMER->setMouldLocalID(currentAgent->getMouldLocalID());
00155             FARMER->setFadnID(currentAgent->getFadnID());
00156             FARMER->setFarmType(currentAgent->getFarmType());
00157             FARMER->setHomeLandUseCode(currentAgent->getHomeLandUseCode());
00158             FARMER->setLandCapital(currentAgent->getLandCapital());
00159             FARMER->setInitialDecPayment(currentAgent->getInitialDecPayment());
00160             FARMER->setInitialResources(currentAgent->getInitialResources());
00161             FARMER->setInitialRentedPlots(currentAgent->getInitialRentedPlots());
00162             FARMER->setInitialOwnedPlots(currentAgent->getInitialOwnedPlots());
00163             FARMER->setMouldLocalID(currentAgent->getMouldLocalID());
00164             FARMER->setMouldCoeff(-1);
00165             FARMER->setLiquidity(currentAgent->getInitialResourceByName("liquidity"));
00166             FARMER->setAgrRegionNumber(currentAgent->getAgrRegionNumber());
00167             FARMER->setCategory(this->getName());
00168             //here things to differenciate agents... e.g. age..
00169             managedAgents.push_back(FARMER);    
00170         }
00171     } 
00172     MTHREAD->treeViewerManagerPropertyChangeValue(getName(),"managed agents",i2s(managedAgents.size()));
00173     /*for (uint i=0;i<managedAgents.size();i++){
00174         cout <<"ID: "<<managedAgents[i]->getAgentUniqueID() << " MouldID: " << managedAgents[i]->getMouldLocalID() << endl;
00175     }*/
00176 }
00177 
00178 void
00179 Manager_farmers::locateMyAgents(){
00180 
00181     msgOut(MSG_DEBUG,"Locating farmers..");
00182 
00183     MTHREAD->GIS->addLayer("farmsteads", "Farmstead position", true, true);
00184     MTHREAD->GIS->addLayer("farmOwnedPlots", "Farmers ID (owned plots)", true, true);
00185     MTHREAD->GIS->addLayer("farmRentedPlots", "Farmers ID (rented plots)", true, true);
00186 
00187     string managerIDString = i2s(-managerID-1);
00188     MTHREAD->GIS->addLegendItem("farmOwnedPlots", -managerID-1, managerIDString, 0, 0, 0, -managerID-1, -managerID-1); // adding a black legend item for pixels owned by dead agents
00189 
00190 
00191     vector <int> agrLandTypes = MTHREAD->RD->getIntVectorSetting("agrLandTypes");
00192     vector <vector <Pixel*> > freePlotsByLandTypes;
00193     for (uint i=0;i<agrLandTypes.size();i++){
00194         vector <Pixel * > freePlots;
00195         freePlots = MTHREAD->GIS->getAllPlotsByValue("landUse",agrLandTypes.at(i),true, MSG_CRITICAL_ERROR); // filtering only the free plots
00196         freePlotsByLandTypes.push_back(freePlots);
00197     }
00198 
00199     // locating the farmstead...
00200     msgOut(MSG_INFO,"Assigning location to each managed agent..");
00201     for (uint i=0;i<managedAgents.size();i++){
00202         Agent_farmer * currentAgent = ((Agent_farmer*) managedAgents.at(i));
00203 
00204         //remainingRentingYears = minAgrContract +( (double)rand() / ((double)(RAND_MAX)+(double)(1)) )*(maxAgrContract-minAgrContract+1); // [minAgrContract, maxAgrContract]
00205         //int random = min + ( (double)rand() / ((double)(RAND_MAX)+(double)(1)) )*(max-min+1);
00206         // 20080117: RGB colors restricted to the [50,255] interval to avoid too dark pixels (and because black is used for collectorAgent)
00207         int randomRed = int (50+( (double)rand() / ((double)(RAND_MAX)+(double)(1)) )*(255-50+1)); // randomRed is [50,255] Don't use "randomNumber % range" !!
00208         int randomGreen = int (50+( (double)rand() / ((double)(RAND_MAX)+(double)(1)) )*(255-50+1));
00209         int randomBlue = int (50+( (double)rand() / ((double)(RAND_MAX)+(double)(1)) )*(255-50+1));
00210 
00211         int ID = managedAgents.at(i)->getAgentLocalID();
00212         string ID_str = i2s(ID);
00213         MTHREAD->GIS->addLegendItem("farmsteads", ID, ID_str, randomRed, randomGreen, randomBlue, ID, ID);
00214         MTHREAD->GIS->addLegendItem("farmOwnedPlots", ID, ID_str, randomRed, randomGreen, randomBlue, ID, ID);
00215         MTHREAD->GIS->addLegendItem("farmRentedPlots", ID, ID_str, randomRed, randomGreen, randomBlue, ID, ID);
00216 
00217         Pixel* assignedPlot;
00218         int homeLandUseCode = currentAgent->getHomeLandUseCode();
00219         int idx =-1;
00220         for (uint j=0;j<agrLandTypes.size();j++){
00221             if(homeLandUseCode == agrLandTypes.at(j)){
00222                 idx = j;
00223                 break;
00224             }
00225         }
00226         if (idx<0) {
00227             msgOut(MSG_CRITICAL_ERROR, "Looks like farmer "+i2s(ID)+" (mould ID " + i2s(currentAgent->getMouldLocalID())+  ") has a homeLandUseCode that is not within the agricultural sets!");
00228         }
00229         if (freePlotsByLandTypes.at(idx).size()<1){
00230             msgOut(MSG_CRITICAL_ERROR, "Trying to assign a plot from an empty vector.");
00231         }
00232 
00233         /*int vectorSize = freePlotsByLandTypes.at(idx).size();
00234         assignedPlot = freePlotsByLandTypes.at(idx).at(vectorSize-1);
00235         freePlotsByLandTypes.at(idx).pop_back();
00236         assignedPlot->changeValue("farmsteads", ID);
00237         currentAgent->setHomePlot(assignedPlot);*/
00238 
00239         int vectorSize = freePlotsByLandTypes.at(idx).size();
00240         vector <Pixel*> tempVector;
00241 
00242         bool boolFlagAssigned = 0;
00243         if(MTHREAD->RD->getBoolSetting("useAgrRegions")){
00244             for(uint j=0;j<vectorSize;j++){
00245                 Pixel* tempPixel = freePlotsByLandTypes.at(idx).at(j);
00246                 /*int debugAgrRegion = tempPixel->getDoubleValue("agrRegions");
00247                 int debugAgentAgrRegion = currentAgent->getAgrRegionNumber();
00248                 int debugPxLandUseCode = tempPixel->getDoubleValue("landUse");*/
00249                 if (tempPixel->getDoubleValue("agrRegions") == currentAgent->getAgrRegionNumber()
00250                         && (! boolFlagAssigned)
00251                 ){
00252                     assignedPlot = tempPixel;
00253                     assignedPlot->changeValue("farmsteads", ID);
00254                     currentAgent->setHomePlot(assignedPlot);
00255                     boolFlagAssigned = 1;
00256                 }
00257                 else {
00258                     tempVector.push_back(tempPixel);
00259                 }
00260             }
00261         }
00262         if(!boolFlagAssigned){
00263             assignedPlot = freePlotsByLandTypes.at(idx).at(vectorSize-1);
00264             freePlotsByLandTypes.at(idx).pop_back();
00265             assignedPlot->changeValue("farmsteads", ID);
00266             currentAgent->setHomePlot(assignedPlot);
00267         } else {
00268             freePlotsByLandTypes.at(idx).clear();
00269             freePlotsByLandTypes.at(idx).resize(tempVector.size());
00270             copy(tempVector.begin(), tempVector.end(),freePlotsByLandTypes.at(idx).begin() );
00271         }
00272 
00273         if (currentAgent->uncompletePlotDotation(homeLandUseCode,PLOTS_OWNED)){
00274             assignPlot(assignedPlot, currentAgent, 0, PLOTS_OWNED); // assign as a owned plot
00275         }
00276         else if (currentAgent->uncompletePlotDotation(homeLandUseCode,PLOTS_RENTED)){
00277             double startRentalCosts = assignedPlot->getStartingRentalCosts();
00278             assignPlot(assignedPlot, currentAgent, startRentalCosts, PLOTS_RENTED);  // assigned as a rented plot
00279             assignedPlot->setRemainingRentingTerm(999); // hack, if the farmstead is on a rented plot - it means this farm doesn't have owned land - the rental contract is perpetual.
00280         }
00281         else {
00282             msgOut(MSG_CRITICAL_ERROR, "Looks like farmer "+i2s(ID)+" (mould ID " + i2s(currentAgent->getMouldLocalID())+  ")doesn't have any initial plot to place the farmstead!");
00283         }
00284         refreshGUI();
00285 
00286         /*int debug1 = currentAgent->getAgentUniqueID();
00287         int debug2 = currentAgent->getHomeLandUseCode();
00288         int debug3 = currentAgent->getAgrRegionNumber();
00289         int debug4 = currentAgent->getHomePlot()->getID();
00290         int debug5 = currentAgent->getHomePlot()->getDoubleValue("landUse");
00291         int debug6 = currentAgent->getHomePlot()->getDoubleValue("agrRegions");
00292 
00293         cout <<"Farmer ID/mould ID/home land use code/Agr.R.Num: " << 
00294                currentAgent->getAgentUniqueID() << " - " <<
00295                currentAgent->getMouldLocalID() << " - " <<
00296                currentAgent->getHomeLandUseCode() << " - " <<
00297                currentAgent->getAgrRegionNumber() << " Host plot's ID/land use code/region number/: " <<
00298                currentAgent->getHomePlot()->getID() << " - " <<
00299                currentAgent->getHomePlot()->getDoubleValue("landUse") << " - " <<
00300                currentAgent->getHomePlot()->getDoubleValue("agrRegions") << endl;*/
00301         //DONE: the problem was in the maps with wrong regionalNumer, not in the code. land allocation by agr region doesn't work! 
00302     }
00303     refreshGUI();
00304 
00305     MTHREAD->GIS->updateImage("farmsteads");
00306 
00307     // assigning plots to the closer farm with free slots...
00308     msgOut(MSG_INFO, "Assigning plots to each farm..");
00309 
00310     // caching the farmstead owner on each plots...
00311     msgOut(MSG_DEBUG, "Cashing pixels with their farmstead owners...");
00312     double nPixels = MTHREAD->GIS->getXyNPixels();
00313     double noValue = MTHREAD->GIS->getNoValue();
00314     double farmID;
00315     for (double i=0; i<nPixels; i++){
00316         Pixel* currentPixel= MTHREAD->GIS->getPixel(i);
00317         farmID = currentPixel->getDoubleValue("farmsteads");
00318         currentPixel->clearCache();
00319         if (farmID != noValue){
00320             Agent_farmer * currentFarmer = ((Agent_farmer*) getAgentByLocalID(farmID));
00321             currentPixel->setCachedAgent(currentFarmer);
00322         }
00323     }
00324 
00325     // merging and mixing the remained freeplots... 
00326     vector <Pixel*> freePlots;
00327     for (uint i=0;i<agrLandTypes.size();i++){
00328         for (uint j=0;j<freePlotsByLandTypes.at(i).size();j++){
00329             freePlots.push_back(freePlotsByLandTypes.at(i).at(j));
00330         }
00331     }
00332     random_shuffle(freePlots.begin(), freePlots.end());
00333     
00334     int maxRange =   MTHREAD->RD->getIntSetting("initialLandAllocationMaxRange"); // range to search for free plots to match the initial farm capacity (in plots)
00335     int assignedCount = 0;
00336 
00337     msgOut(MSG_DEBUG, "Started the plot assignment algorithm (this may take some minutes)..");
00338     msgOut(MSG_DEBUG, "Total pixels to assign: "+i2s(freePlots.size()));
00339 
00340     /*
00341     Looking over concentical neighbour plots loop for farmers. When a farmer is found, if it is still on a "uncomplete" state assign the plot to her.
00342     */
00343     for (uint i=0;i<freePlots.size();i++){
00344         // it crash at i==19717.. that was for right-bottom corner error in getPixelsAtDistLevel(j), solved on 20070719
00345         int landUseCode = ((int)freePlots.at(i)->getDoubleValue("landUse"));
00346         bool assigned = false;
00347         for (int j=1;j<maxRange;j++){
00348             if (assigned) break;
00349             vector <Pixel *> neighbourPlots = freePlots[i]->getPixelsAtDistLevel(j);
00350             for (uint z=0;z<neighbourPlots.size();z++){
00351                 if (neighbourPlots[z]->getCachedAgent()){
00352                     Agent_farmer * currentFarmer = ((Agent_farmer*) neighbourPlots[z]->getCachedAgent() );
00353                     if (currentFarmer->uncompletePlotDotation(landUseCode,PLOTS_OWNED)){
00354                         assignPlot(freePlots[i], currentFarmer, 0, PLOTS_OWNED); // assign as a owned plot
00355                         assigned = true;
00356                         assignedCount ++;
00357                         break;
00358                     }
00359                     else if (currentFarmer->uncompletePlotDotation(landUseCode,PLOTS_RENTED)){
00360                         double startRentalCosts = freePlots[i]->getStartingRentalCosts();
00361                         assignPlot(freePlots[i], currentFarmer, startRentalCosts, PLOTS_RENTED); // assigned as a rented plot
00362                         assigned = true;
00363                         assignedCount ++;
00364                         break;
00365                     }
00366                 }
00367             }
00368         }
00369         refreshGUI();
00370     }
00371 
00372     msgOut(MSG_DEBUG,"Total assigned pixels: "+i2s(assignedCount));
00373 
00374     MTHREAD->GIS->updateImage("farmOwnedPlots");
00375     MTHREAD->GIS->updateImage("farmRentedPlots");
00376     
00377     if(MTHREAD->RD->getBoolSetting("agentsView")){
00378         double haByPlot = MTHREAD->GIS->getHaByPixel();
00379         for(uint i=0;i<managedAgents.size();i++){
00380             int ownedPlots = ((Agent_space*) managedAgents.at(i)) -> getNPlots(PLOTS_OWNED);
00381             int rentedPlots = ( (Agent_space*) managedAgents.at(i)) -> getNPlots(PLOTS_RENTED);
00382             MTHREAD->treeViewerAgentPropertyChangeValue(managedAgents.at(i)->getAgentUniqueID(),"owned land", d2s(( (double)ownedPlots)*haByPlot));
00383             MTHREAD->treeViewerAgentPropertyChangeValue(managedAgents.at(i)->getAgentUniqueID(),"rented land", d2s(( (double)rentedPlots)*haByPlot));
00384         }
00385     }
00386 
00387 }
00388 
00389 void
00390 Manager_farmers::createBehaviours(){
00391     msgOut(MSG_INFO, "Creating farmers bahaviours (decision matrix)..");
00392     for (uint i=0;i<managedAgents.size();i++){
00393         Agent_farmer * currentAgent = ((Agent_farmer*) managedAgents.at(i));
00394         currentAgent->initMIP();
00395     }
00396     msgOut(MSG_DEBUG, "Ended initialization of the MIP.");
00397     if(MTHREAD->RD->getBoolSetting("agentsView")){
00398         for(uint i=0;i<managedAgents.size();i++){
00399             double liquidity = ((Agent_space*) managedAgents.at(i)) -> getLiquidity();
00400             double capital   = ( (Agent_space*) managedAgents.at(i)) -> getCapital();
00401             MTHREAD->treeViewerAgentPropertyChangeValue(managedAgents.at(i)->getAgentUniqueID(),"liquidity", d2s(liquidity));
00402             MTHREAD->treeViewerAgentPropertyChangeValue(managedAgents.at(i)->getAgentUniqueID(),"capital", d2s(capital));
00403         }
00404     }
00405 }
00406 
00411 void
00412 Manager_farmers::endInit(){
00413 
00414     // initialising the arrays of decoupling rights for dead farmers...
00415     int nActivities = MTHREAD->RD->getActivitiesDefinitionVectorSize();
00416     int nPolicyPremiums = MTHREAD->RD->getResourceSize(RESTYPE_POLICYPREMIUM);
00417     for (int i=0; i< nActivities; i++){
00418         vector<double> tempVector(nPolicyPremiums,0);
00419         for(uint y=0;y<nPolicyPremiums;y++){
00420             sumOfRightsOfDeadAgents.push_back(tempVector);
00421             sumOfHaOfDeadAgents.push_back(tempVector);
00422         }
00423     }
00424      //calibrateRentalCoefficients();
00425 
00426 }
00427 
00428 void
00429 Manager_farmers::prepare(){
00430     msgOut(MSG_INFO, "Preparing of the period has started..");
00431     
00432     for (uint i=0;i<managedAgents.size();i++){
00433         Agent_farmer * currentAgent = ((Agent_farmer*) managedAgents.at(i));
00434         currentAgent->payInitialYearCosts();
00435     }
00436 
00437     for(uint i=0;i<managedAgents.size();i++){
00438         Agent_farmer * currentAgent = ((Agent_farmer*) managedAgents.at(i));
00439         currentAgent->initMIP();
00440     }
00441 
00442     landAllocation();
00443     if(MTHREAD->SCD->getYear() == MTHREAD->RD->getIntSetting("initialYear")){
00444         calibrateLandValues(); // needed for calculating shadow price of owned land when farms must decide if continue
00445     }
00446 
00447     // 2007.11.05 Payment of rent for newly rented plots is now in the assignPlot() function (after each individual assignation)
00448 
00449 }
00450 
00458 // new
00459 void
00460 Manager_farmers::landAllocation(){
00461 
00462     vector <Pixel*> freePlots;
00463     int counterAssigned;
00464     int loopCounter;
00465     vector <int> agrLandTypes;
00466     vector <string> agrLandTypesShortLabels;
00467     int bidSize;
00468     double highestBid;
00469     double secondHighestBid;
00470     Agent_farmer* currentWinner;
00471     int freePlotsCount;
00472     double bid=0;
00473     vector <Agent_space* > closestAgents;
00474     int closestAgentCount;
00475     //int nThreads = MTHREAD->RD->getIntSetting("nThreads");
00476     int nThreads = 1; //TODO: make again nthread loadable in input
00477     //QMutex* mutex = new QMutex;
00478 
00479     agrLandTypes = MTHREAD->RD->getIntVectorSetting("agrLandTypes");
00480     vector <double> sumOfRentalExpendituresBySoilType (agrLandTypes.size(), ((double)0));
00481     vector <int>    assignedPlotsBySoilType (agrLandTypes.size(), 0);
00482     vector <double> avgPricesBySoilType (agrLandTypes.size(), ((double)0));
00483     
00484     agrLandTypesShortLabels = MTHREAD->RD->getStringVectorSetting("agrLandTypesShortLabels");
00485     bidSize = MTHREAD->RD->getIntSetting("askBidsArraySize");
00486 
00487     if(MTHREAD->RD->getBoolSetting("subRegionMode")){ // in case of a sub-region we take less bids, but at least 3
00488         bidSize = ((int)round(bidSize * MTHREAD->RD->getDoubleSetting("scaleCoeff")));
00489         bidSize = max(3, bidSize);
00490     }
00491     QThreadPool::globalInstance()->setMaxThreadCount(nThreads);
00492     vector <Manager_farmers_threads*> wThreads;
00493 
00494     //for (int i=0; i < nThreads; i++){
00495     //  Manager_farmers_threads* wThread = new Manager_farmers_threads;
00496     //  wThreads.push_back(wThread);
00497     //}
00498     
00499     for (uint i=0;i< agrLandTypes.size(); i++){
00500         sumOfRentalExpendituresBySoilType[i] = 0;
00501         assignedPlotsBySoilType[i] = 0;
00502 
00503         freePlots =  MTHREAD->GIS->getAllPlotsByValue("landUse", agrLandTypes.at(i), true, MSG_DEBUG);
00504         counterAssigned=0;
00505         loopCounter=0;
00506         msgOut(MSG_INFO, "Renting plots of type "+i2s(agrLandTypes.at(i))+". "+i2s(freePlots.size())+" plots to assign (this can take a while)..");
00507         freePlotsCount = freePlots.size();
00508         for (int j=0;j<freePlotsCount;j++){
00509             highestBid           = 0;
00510             secondHighestBid     = 0;
00511             currentWinner = 0;
00512 
00513             for(uint ii=0;ii<2;ii++){ //we try two times before we end up declaring a plot unused..
00514                 if(ii==0){ // first, normal attempt
00515                     closestAgents = MTHREAD->GIS->getClosestAgents(freePlots[j], bidSize, name);
00516                 }
00517                 else { // we ask to bid to more farms...
00518                     closestAgents = MTHREAD->GIS->getClosestAgents(freePlots[j], bidSize*3, this->getName());
00519                 }
00520                 closestAgentCount = closestAgents.size();
00521 
00522                 vector<double> offers (closestAgentCount, ((double)0));
00523 
00524                 
00525                 //META CODE:
00526                 //For each agents to ask price
00527                 //  For each thread
00528                 //      We ask the thread if it is running
00529                 //      If not, while it is not running, we pass the thread some infos it will need to elaborate and then we start the thread
00530                 //ATTENCTION! This code require a specifically patched glpk library that, even if not fully //reentrant, doesn't make the application crash in presence of several threads
00531                 
00532 
00533 
00534                 for (uint y=0;y<closestAgents.size();y++){
00535                     Manager_farmers_threads* runElement = new Manager_farmers_threads;
00536                     runElement->setAutoDelete(FALSE);
00537                     runElement->assignJob(closestAgents.at(y),freePlots.at(j));
00538                     wThreads.push_back(runElement);
00539                     QThreadPool::globalInstance()->start(runElement);
00540                 }
00541 
00542 
00543                 // Be sure that all thread have ended their last job before continue..
00544                 //for (int z=0; z < nThreads; z++){
00545                 //  wThreads[z]->wait();
00546                 //}
00547                 QThreadPool::globalInstance()->waitForDone();
00548                 for ( int z=0; z< closestAgentCount; z++){
00549                     offers[z] = ( (Agent_farmer*) closestAgents[z])->getCachedOffer();
00550                 }
00551 
00552                 for (uint i=0;i<wThreads.size();i++){
00553                     delete wThreads[i];
00554                 }
00555                 wThreads.clear();
00556 
00557                 for ( int z=0; z< closestAgentCount; z++){
00558                     if (offers[z]>highestBid){
00559                         secondHighestBid = highestBid;
00560                         highestBid = offers[z];
00561                         currentWinner = ( (Agent_farmer*) closestAgents[z]) ;
00562                     } else if (bid > secondHighestBid) {
00563                         secondHighestBid = offers[z];
00564                     }
00565                 }
00566                 if (currentWinner){
00567                     assignPlot(freePlots[j], currentWinner, secondHighestBid, PLOTS_RENTED);
00568                     counterAssigned++;
00569                     sumOfRentalExpendituresBySoilType[i] += secondHighestBid ;
00570                     assignedPlotsBySoilType[i] ++ ;
00571                     currentWinner->produce(); // 20071106 BUM!!! This is needed as she getShadowPrice() is called without first solving the matrix 
00572                     break;
00573                 }
00574                 else {
00575                     if(ii==1){
00576                         msgOut(MSG_DEBUG,"Plot "+d2s( freePlots.at(j)->getID())+" ("+i2s( freePlots.at(j)->getX())+","+i2s( freePlots.at(j)->getY())+") unrented on the first tempt.. asking to bid to more farms..");
00577                     }
00578                     else {
00579                         msgOut(MSG_DEBUG, "Plot "+d2s( freePlots.at(j)->getID())+" ("+i2s( freePlots.at(j)->getX())+","+i2s( freePlots.at(j)->getY())+")  definitively unrented.. gived up..");
00580                     }
00581                 }
00582             }
00583             if(loopCounter%100==0){
00584                 msgOut(MSG_DEBUG, i2s(loopCounter)+" plots done...");
00585             }
00586             loopCounter ++;
00587             refreshGUI();
00588         }
00589         if(assignedPlotsBySoilType[i]>5) {
00590             avgPricesBySoilType[i] = sumOfRentalExpendituresBySoilType[i] / ((double)assignedPlotsBySoilType[i]);
00591             MTHREAD->RD->setBasicData("agrRentalPrices", avgPricesBySoilType[i], i);
00592             msgOut(MSG_INFO, "Assigned "+i2s(counterAssigned)+" plots of type "+agrLandTypesShortLabels.at(i));
00593             msgOut(MSG_INFO, "Avg. price: "+d2s(avgPricesBySoilType[i])+" euro/ha"  );
00594         }
00595         else {
00596             avgPricesBySoilType[i] = 0;
00597             msgOut(MSG_INFO, "Assigned "+i2s(counterAssigned)+" plots of type "+agrLandTypesShortLabels.at(i));
00598             msgOut(MSG_INFO, "Avg. price not updated as too few assignments to calculate an average.");
00599         }
00600     }
00601 
00602     MTHREAD->GIS->updateImage("farmRentedPlots");
00603 
00604     //for (int i=0; i < nThreads; i++){
00605     //  delete wThreads[i]; // deleting the threads
00606     //}
00607 
00608     //delete mutex;
00609 
00610     if(MTHREAD->RD->getBoolSetting("agentsView")){
00611         double haByPlot = MTHREAD->GIS->getHaByPixel();
00612         for(uint i=0;i<managedAgents.size();i++){
00613             int ownedPlots = ((Agent_space*) managedAgents.at(i)) -> getNPlots(PLOTS_OWNED);
00614             int rentedPlots = ( (Agent_space*) managedAgents.at(i)) -> getNPlots(PLOTS_RENTED);
00615             MTHREAD->treeViewerAgentPropertyChangeValue(managedAgents.at(i)->getAgentUniqueID(),"owned land", d2s(( (double)ownedPlots)*haByPlot));
00616             MTHREAD->treeViewerAgentPropertyChangeValue(managedAgents.at(i)->getAgentUniqueID(),"rented land", d2s(( (double)rentedPlots)*haByPlot));
00617         }
00618     }
00619 }
00620 /*
00621 //old:
00622 void
00623 Manager_farmers::landAllocation(){
00624 
00625 
00626     vector <Pixel*> freePlots;
00627     int counterAssigned;
00628     int loopCounter;
00629     vector <int> agrLandTypes;
00630     vector <string> agrLandTypesShortLabels;
00631     int bidSize;
00632     double highestBid;
00633     double secondHighestBid;
00634     Agent_farmer* currentWinner;
00635     int freePlotsCount;
00636     double bid;
00637     vector <Agent_space* > closestAgents;
00638     int closestAgentCount;
00639 
00640     agrLandTypes = MTHREAD->RD->getIntVectorSetting("agrLandTypes");
00641     vector <double> sumOfRentalExpendituresBySoilType (agrLandTypes.size(), ((double)0));
00642     vector <int>    assignedPlotsBySoilType (agrLandTypes.size(), 0);
00643     vector <double> avgPricesBySoilType (agrLandTypes.size(), ((double)0));
00644     
00645     agrLandTypesShortLabels = MTHREAD->RD->getStringVectorSetting("agrLandTypesShortLabels");
00646     bidSize = MTHREAD->RD->getIntSetting("askBidsArraySize");
00647 
00648     if(MTHREAD->RD->getBoolSetting("subRegionMode")){ // in case of a sub-region we take less bids, but at least 3
00649         bidSize = ((int)round(bidSize * MTHREAD->RD->getDoubleSetting("scaleCoeff")));
00650         bidSize = max(3, bidSize);
00651     }
00652     
00653     for (uint i=0;i< agrLandTypes.size(); i++){
00654         sumOfRentalExpendituresBySoilType[i] = 0;
00655         assignedPlotsBySoilType[i] = 0;
00656 
00657         freePlots =  MTHREAD->GIS->getAllPlotsByValue("landUse", agrLandTypes.at(i), true, MSG_DEBUG);
00658         counterAssigned=0;
00659         loopCounter=0;
00660         msgOut(MSG_INFO, "Renting plots of type "+i2s(agrLandTypes.at(i))+". "+i2s(freePlots.size())+" plots to assign (this can take a while)..");
00661         freePlotsCount = freePlots.size();
00662         for (int j=0;j<freePlotsCount;j++){
00663             highestBid           = 0;
00664             secondHighestBid     = 0;
00665             currentWinner = 0;
00666 
00667 
00668             for(uint ii=0;ii<2;ii++){ //we try two times before we end up declaring a plot unused..
00669                 if(ii==0){ // first, normal attempt
00670                     closestAgents = MTHREAD->GIS->getClosestAgents(freePlots[j], bidSize, name);
00671                 }
00672                 else { // we ask to bid to more farms...
00673                     closestAgents = MTHREAD->GIS->getClosestAgents(freePlots[j], bidSize*3, this->getName());
00674                 }
00675                 closestAgentCount = closestAgents.size();
00676                 for ( int z=0; z< closestAgentCount; z++){
00677                     bid = ( (Agent_farmer*) closestAgents[z])->offerRentalPrice(freePlots[j]);
00678                     if (bid>highestBid){
00679                         secondHighestBid = highestBid;
00680                         highestBid = bid;
00681                         currentWinner = ( (Agent_farmer*) closestAgents[z]) ;
00682                     } else if (bid > secondHighestBid) {
00683                         secondHighestBid = bid;
00684                     }
00685                 }
00686                 if (currentWinner){
00687                     assignPlot(freePlots[j], currentWinner, secondHighestBid, PLOTS_RENTED);
00688                     counterAssigned++;
00689                     sumOfRentalExpendituresBySoilType[i] += secondHighestBid ;
00690                     assignedPlotsBySoilType[i] ++ ;
00691                     currentWinner->produce(); // 20071106 BUM!!! This is needed as she getShadowPrice() is called without first solving the matrix 
00692                     break;
00693                 }
00694                 else {
00695                     if(ii==1){
00696                         msgOut(MSG_DEBUG,"Plot "+d2s( freePlots.at(j)->getID())+" ("+i2s( freePlots.at(j)->getX())+","+i2s( freePlots.at(j)->getY())+") unrented on the first tempt.. asking to bid to more farms..");
00697                     }
00698                     else {
00699                         msgOut(MSG_DEBUG, "Plot "+d2s( freePlots.at(j)->getID())+" ("+i2s( freePlots.at(j)->getX())+","+i2s( freePlots.at(j)->getY())+")  definitively unrented.. gived up..");
00700                     }
00701                 }
00702             }
00703             if(loopCounter%100==0){
00704                 msgOut(MSG_DEBUG, i2s(loopCounter)+" plots done...");
00705             }
00706             loopCounter ++;
00707             refreshGUI();
00708         }
00709         if(assignedPlotsBySoilType[i]>5) {
00710             avgPricesBySoilType[i] = sumOfRentalExpendituresBySoilType[i] / ((double)assignedPlotsBySoilType[i]);
00711             MTHREAD->RD->setBasicData("agrRentalPrices", avgPricesBySoilType[i], i);
00712             msgOut(MSG_INFO, "Assigned "+i2s(counterAssigned)+" plots of type "+agrLandTypesShortLabels.at(i));
00713             msgOut(MSG_INFO, "Avg. price: "+d2s(avgPricesBySoilType[i])+" euro/ha"  );
00714         }
00715         else {
00716             avgPricesBySoilType[i] = 0;
00717             msgOut(MSG_INFO, "Assigned "+i2s(counterAssigned)+" plots of type "+agrLandTypesShortLabels.at(i));
00718             msgOut(MSG_INFO, "Avg. price not updated as too few assignments to calculate an average.");
00719         }
00720     }
00721 
00722     MTHREAD->GIS->updateImage("farmRentedPlots");
00723 
00724     if(MTHREAD->RD->getBoolSetting("agentsView")){
00725         double haByPlot = MTHREAD->GIS->getHaByPixel();
00726         for(uint i=0;i<managedAgents.size();i++){
00727             int ownedPlots = ((Agent_space*) managedAgents.at(i)) -> getNPlots(PLOTS_OWNED);
00728             int rentedPlots = ( (Agent_space*) managedAgents.at(i)) -> getNPlots(PLOTS_RENTED);
00729             MTHREAD->treeViewerAgentPropertyChangeValue(managedAgents.at(i)->getAgentUniqueID(),"owned land", d2s(( (double)ownedPlots)*haByPlot));
00730             MTHREAD->treeViewerAgentPropertyChangeValue(managedAgents.at(i)->getAgentUniqueID(),"rented land", d2s(( (double)rentedPlots)*haByPlot));
00731         }
00732     }
00733 }
00734 */
00735 
00736 
00741 void
00742 Manager_farmers::calibrateLandValues(){
00743     msgOut(MSG_INFO, "Calibrating shadow prices of owned plots (this can take a while)..");
00744     vector <int> agrLandTypes = MTHREAD->RD->getIntVectorSetting("agrLandTypes");
00745     vector <double> rentalPrices = MTHREAD->RD->getDoubleVectorSetting("agrRentalPrices");
00746     vector<Pixel*> ownedPlots;
00747 
00748     for (uint i=0;i<managedAgents.size();i++){
00749         Agent_farmer * currentAgent = ((Agent_farmer*) managedAgents.at(i));
00750         vector<Pixel*> agentOwnedPlots = currentAgent->getPlots(PLOTS_OWNED);
00751         copy (agentOwnedPlots.begin(), agentOwnedPlots.end(), back_inserter(ownedPlots));
00752     }
00753 
00754     msgOut(MSG_INFO, i2s(ownedPlots.size())+" plots to give estimate value..");
00755     for(uint i=0;i<ownedPlots.size();i++){
00756         double shPrice = quotePlot(ownedPlots[i]);
00757         int type= ((int)ownedPlots[i]->getDoubleValue("landUse"));
00758         double avgRentalPrice = 0;
00759         for (uint j=0;j<agrLandTypes.size();j++){
00760             if (type == agrLandTypes[j]){
00761                 avgRentalPrice = rentalPrices.at(j);
00762                 break;
00763             }
00764         }
00765         if(avgRentalPrice>0){
00766             ownedPlots[i]->setShRentalPriceCoeff(shPrice/avgRentalPrice);
00767         }
00768         else {
00769             ownedPlots[i]->setShRentalPriceCoeff(1);
00770         }
00771         if(i%100==0){
00772             msgOut(MSG_DEBUG, i2s(i)+" plots done...");
00773             refreshGUI();
00774         }
00775     }
00776     msgOut(MSG_INFO, "Done: estimated "+i2s(ownedPlots.size())+" plots.");
00777     
00778 }
00779 
00780 
00781 double
00782 Manager_farmers::quotePlot(Pixel* plot){
00783     double highestBid           = 0;
00784     double secondHighestBid     = 0;
00785     double bid                  = 0;
00786     int bidSize                 = MTHREAD->RD->getIntSetting("askBidsArraySize");
00787 
00788     if(MTHREAD->RD->getBoolSetting("subRegionMode")){ // in case of a sub-region we take less bids, but at least 3
00789         bidSize = ((int)round(bidSize * MTHREAD->RD->getDoubleSetting("scaleCoeff")));
00790         bidSize = max(3, bidSize);
00791     }
00792 
00793     Agent_space* owner = plot->getOwner();
00794     vector <Agent_space*> closestAgents;
00795     Agent_farmer* currentWinner=NULL;
00796 
00797 
00798     closestAgents = MTHREAD->GIS->getClosestAgents(plot, bidSize, name);
00799     // remove the plot owner from the array..
00800     if(owner){
00801         vector <Agent_space*>::iterator p;
00802         for ( p = closestAgents.begin() ; p != closestAgents.end();){
00803             if (*p == owner){
00804                 //delete *p .. don't use while() as in the book, otherwise the deletion of the pointer within the cycle will make a SIGFAUL
00805                 closestAgents.erase(p);
00806             }
00807             else {
00808                 ++p;
00809             }
00810         }
00811     }
00812     int closestAgentCount = closestAgents.size();
00813     for ( int z=0; z< closestAgentCount; z++){
00814         bid = ( (Agent_farmer*) closestAgents[z])->offerRentalPrice(plot);
00815         if (bid>highestBid){
00816             secondHighestBid = highestBid;
00817             highestBid = bid;
00818             currentWinner = ( (Agent_farmer*) closestAgents[z]) ;
00819         }
00820     }
00821     if (currentWinner){
00822         return secondHighestBid;
00823     }
00824     else {
00825             return 0;
00826     }   
00827     return 0;
00828 }
00829 
00830 void
00831 Manager_farmers::act(){
00832     // DONE: say the MIP to add activity only if enought rental years.. no not needed any longer.. it is the opposite.. if the farmer do permanent crops, the rental contract is posponed
00833     msgOut(MSG_INFO, "Period activity has started...");
00834     double debugLandUsed=0;
00835     MTHREAD->GIS->resetLayer("farmActivities"); // this is needed as otherwise we'll never report abandoned land, as we have the value on the plot of the previous years
00836     for (uint i=0;i<managedAgents.size();i++){
00837         Agent_farmer * currentAgent = ((Agent_farmer*) managedAgents.at(i));
00838         //int debugID = currentAgent->getAgentUniqueID();
00839         currentAgent->produce(); // just OPT.solve() ;-)))
00840         currentAgent->collectProductionEffects(); // add profit and subtract investment expenses and withdraw to liquidity. Plus add investment objects
00841         currentAgent->withdraw(); // calculate the money withdrawn from the bank for living
00842         debugLandUsed += currentAgent->debugLandUse;
00843     }
00844     MTHREAD->GIS->updateImage("farmActivities");
00845 }
00846 
00847 void
00848 Manager_farmers::update(){
00849     msgOut(MSG_INFO, "Updating agents...");
00850     for (uint i=0;i<managedAgents.size();i++){
00851         Agent_farmer * currentAgent = ((Agent_farmer*) managedAgents.at(i));
00852         currentAgent->update();
00853     }
00854     MTHREAD->treeViewerManagerPropertyChangeValue(getName(),"managed agents",i2s(managedAgents.size()));
00855     if(MTHREAD->RD->getBoolSetting("agentsView")){
00856         for(uint i=0;i<managedAgents.size();i++){
00857             double liquidity = ((Agent_space*) managedAgents.at(i)) -> getLiquidity();
00858             double capital   = ( (Agent_space*) managedAgents.at(i)) -> getCapital(true);
00859             MTHREAD->treeViewerAgentPropertyChangeValue(managedAgents.at(i)->getAgentUniqueID(),"liquidity", d2s(liquidity));
00860             MTHREAD->treeViewerAgentPropertyChangeValue(managedAgents.at(i)->getAgentUniqueID(),"capital", d2s(capital));
00861         }
00862     }
00863     //MTHREAD->GIS->resetLayer("farmActivities"); //20071202: commented so that we can check in the pixArea the meaning of the colors. TO DO: check that this do not lead to bugs.. I thing so, but we can move it on a different place, so that the period that there is no data is minimised.. IMPORTANT !!!! DONE The problem was that otherwise we never have abandoned land, as we have the production of previous years
00864 }
00865 
00866 void
00867 Manager_farmers::planNext(){
00868     msgOut(MSG_INFO, "Planning for the next period has started...");
00869     for (uint i=0;i<managedAgents.size();i++){
00870         Agent_farmer * currentAgent = ((Agent_farmer*) managedAgents.at(i));
00871         int leaveActivity = currentAgent->leaveActivity();
00872         if (leaveActivity){
00873             MTHREAD->DO->printLeavingAgent(currentAgent, leaveActivity);
00874             removeFromModel(currentAgent);
00875         }
00876     }
00877 
00878     MTHREAD->treeViewerManagerPropertyChangeValue(getName(),"managed agents",i2s(managedAgents.size()));
00879 }
00880 
00881 void
00882 Manager_farmers::assignPlot(Pixel* plot_h, Agent_space* agent_h, double rentalCosts, int assignmentType){
00883 
00884     if (assignmentType ==PLOTS_OWNED){
00885         if( MTHREAD->INIT->getInitState() > 4){ // we are no longer in the init stage
00886             msgOut(MSG_CRITICAL_ERROR, "Buying/selling plots is not yet implemented so here is one of that places where the program should has never gonna. Check what went wrong! Aborting..."); 
00887         }
00888         plot_h->changeValue("farmOwnedPlots", agent_h->getAgentLocalID());
00889         agent_h->addPlotToOwnedList(plot_h);
00890         plot_h->setOwner(agent_h);
00891     }
00892     else if (assignmentType==PLOTS_RENTED){
00893 
00894         plot_h->changeValue("farmRentedPlots", agent_h->getAgentLocalID());
00895         plot_h->setRandomRenting("agrContract"); // DONE: if we are in the init the random renting must be randomized even at a remaining level before the minimu contracts, otherwise the first X years no contracts ends !!!!
00896         plot_h->setRentalCosts(rentalCosts);
00897 
00898         if( MTHREAD->INIT->getInitState() > 4){ // we are no longer in the init stage
00899             agent_h->addPlotToMIP(plot_h);
00900             agent_h->pay(rentalCosts);
00901             agent_h->addToSunkCostsPaid(rentalCosts);
00902         }
00903         agent_h->addPlotToRentedList(plot_h); // don't invert !!! this MUST go after the adding to the MIP
00904         plot_h->setTenant(agent_h);
00905         
00906     }
00907     else {
00908         msgOut(MSG_ERROR, "Function assignPlot() called with an unknow type");
00909     }
00910 }
00911 
00912 void
00913 Manager_farmers::removeFromModel(Agent_farmer* agent_h){
00914     agent_h->freeLand();
00915     vector<Agent_base*>::iterator iterator;
00916     int nPolicyPremiums = MTHREAD->RD->getResourceSize(RESTYPE_POLICYPREMIUM);
00917  
00918     for ( iterator = managedAgents.begin() ; iterator !=managedAgents.end();){
00919         if(*iterator == agent_h){
00920             // if we keep also the dead agents (and in particulat their OPT matrix) the memory explode. We are forced to delete them.
00921             
00922             Pixel* farmsteadPx = agent_h->getHomePlot();
00923             vector <Pixel*> ownedPlots = agent_h->getPlots(PLOTS_OWNED);
00924             vector <Pixel*> rentedPlots = agent_h->getPlots(PLOTS_RENTED);
00925             double noValue = MTHREAD->GIS->getNoValue();
00926 
00927             // deleting farmseads...
00928             farmsteadPx->changeValue("farmsteads",noValue);
00929             // assigning owned plots to collectorAgent...
00930             for (uint i=0;i<ownedPlots.size();i++){
00931                 ownedPlots[i]->setOwner((( Agent_space*) collectorAgent));
00932                 //int debug =  collectorAgent->getAgentUniqueID();
00933                 ownedPlots[i]->changeValue("farmOwnedPlots",collectorAgent->getAgentUniqueID() );
00934             }
00935             // free the rented land...
00936             for (uint i=0;i<rentedPlots.size();i++){
00937                 rentedPlots[i]->destroyRentalContract();
00938                 rentedPlots[i]->changeValue("farmRentedPlots",noValue);
00939             }
00940             
00941             vector<RegActivities*> actMoulds = MTHREAD->RD->getRegActivities();
00942             
00943             for (uint j=0;j<actMoulds.size();j++){
00944                 for(uint y=0;y<nPolicyPremiums;y++){
00945                     if(actMoulds[j]->getDecouplingOption(y) > 0){ // this activity is not in registration mode...
00946                         sumOfRightsOfDeadAgents.at(j).at(y) += actMoulds[j]->getDecouplingOption(y) * agent_h->getDecRightsByAct(j,y);
00947                         sumOfHaOfDeadAgents.at(j).at(y) += agent_h->getDecHaByActMould(j,y);
00948                     }
00949                 }
00950             }
00951 
00952 
00953             delete agent_h;
00954             //removedAgents.push_back(agent_h);
00955 
00956             managedAgents.erase(iterator);
00957         }
00958         else {
00959             ++iterator;
00960         }
00961     }
00962 }
00963 
00970 double
00971 Manager_farmers::getAverageRightsByAct(int actMouldCounter){
00972     double sumOfRights=0;
00973     double sumOfHa=0;
00974     vector<RegActivities*> actMoulds = MTHREAD->RD->getRegActivities();
00975     vector <string> policyPremiums = MTHREAD->RD->getResourceNames(RESTYPE_POLICYPREMIUM);
00976     int nPolicyPremiums = policyPremiums.size();
00977 
00978     //TO.DO DONE: include also the dead agents.. this means to keep them and destroy only their OPT object instead of destroy them..
00979     //TODO: make cashed vaues to speed up this calculatio (it's the same for each agent!)
00980     // 2008.09.21, bug corrected.. as the average premium is then multiplied to all hectars, also the "average" should refer to the whole hecterage..  
00981     if(actMouldCounter != -1){// we are asked for a specific activity
00982         for(uint y=0;y< nPolicyPremiums;y++){
00983             if(actMoulds.at(actMouldCounter)->getDecouplingOption(y) >= 0){ //this activity, for this specific premium, is not in "registration rights" mode...
00984                 for (uint i=0;i<managedAgents.size();i++){
00985                     sumOfRights += actMoulds.at(actMouldCounter)->getDecouplingOption(y) *
00986                                    ((Agent_farmer*)managedAgents[i])->getDecRightsByAct(actMouldCounter,y);
00987                     sumOfHa += ((Agent_farmer*)managedAgents[i])->getDecHaByActMould(actMouldCounter,y);
00988                 }
00989                 sumOfRights += sumOfRightsOfDeadAgents.at(actMouldCounter).at(y);
00990                 sumOfHa += sumOfHaOfDeadAgents.at(actMouldCounter).at(y);
00991             }
00992             else {
00993                 for (uint i=0;i<managedAgents.size();i++){
00994                     sumOfHa += ((Agent_farmer*)managedAgents[i])->getDecHaByActMould(actMouldCounter,y);
00995                 }
00996                 sumOfHa += sumOfHaOfDeadAgents.at(actMouldCounter).at(y);
00997             }
00998         }
00999     } else {
01000         for (uint j=0;j<actMoulds.size();j++){
01001             for (uint y=0;y< nPolicyPremiums;y++){
01002                 if(actMoulds[j]->getDecouplingOption(y) >= 0){ // this activity is not in registration mode...
01003                     for (uint i=0;i<managedAgents.size();i++){
01004                         sumOfRights += actMoulds[j]->getDecouplingOption(y) * ((Agent_farmer*)managedAgents[i])->getDecRightsByAct(j,y);
01005                         sumOfHa += ((Agent_farmer*)managedAgents[i])->getDecHaByActMould(j,y);
01006                     }
01007                     sumOfRights += sumOfRightsOfDeadAgents.at(j).at(y);
01008                     sumOfHa += sumOfHaOfDeadAgents.at(j).at(y);
01009                 }
01010                 else {
01011                     for (uint i=0;i<managedAgents.size();i++){
01012                         sumOfHa += ((Agent_farmer*)managedAgents[i])->getDecHaByActMould(j,y);
01013                     }
01014                     sumOfHa += sumOfHaOfDeadAgents.at(j).at(y);
01015                 }
01016             }
01017         }
01018     }
01019 
01020     if(sumOfHa>0){
01021         return sumOfRights/sumOfHa;
01022     } else {
01023         return 0;
01024     }
01025     return 0;
01026     
01027 }
01028 
01029 // ############################ CLASS  Manager_farmers_threads    ####################
01030 
01031 
01032 Manager_farmers_threads::Manager_farmers_threads(){
01033 
01034 }
01035 
01036 void
01037 Manager_farmers_threads::run(){
01038 
01039     //mutex->lock();
01040     //cout << agent->getAgentUniqueID()<< endl;
01041 
01042     //double randChange =  (0+( (double)rand() / ((double)(RAND_MAX)+(double)(1)) )*(10-0+1))/ (double)100; //rand() must be not thread safe !!!!
01043 
01044     //int justn = 10000;
01045     //vector <double> takeTimeVector (justn, 0);
01046     //for (int i =0; i< justn;i++){
01047     //  takeTimeVector.at(i)=i*2;
01048     //}
01049     
01050         ( (Agent_farmer*) agent)->cachedOffer = ( (Agent_farmer*) agent)->offerRentalPrice(plot);
01051     //( (Agent_farmer*) agent)->cachedOffer = ( (Agent_farmer*) agent)->getAgentUniqueID();
01052     //mutex->unlock();
01053 }
01054 
01055 void
01056 Manager_farmers_threads::assignJob(Agent_space* agent_h, const Pixel* plot_h){
01057     agent = agent_h;
01058     plot = plot_h;
01059     //mutex = mutex_h;
01060     ( (Agent_farmer*) agent) ->cachedOffer = 0;
01061 }
01062 
01063