Agent_farmer.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 <algorithm>
00021 #include <cmath>
00022 
00023 #include "Init.h"
00024 #include "Agent_farmer.h"
00025 #include "Pixel.h"
00026 #include "ThreadManager.h"
00027 #include "Scheduler.h"
00028 #include "Manager_base.h"
00029 #include "Manager_farmers.h"
00030 
00031 Agent_farmer::Agent_farmer(ThreadManager* MTHREAD_h, Manager_base* manager_h): Agent_space(MTHREAD_h, manager_h){
00032     // constructor for the agent moulds
00033 }
00034 
00035 Agent_farmer::Agent_farmer(ThreadManager* MTHREAD_h, int uniqueID_h, Manager_base* manager_h): Agent_space(MTHREAD_h, uniqueID_h, manager_h){
00036     
00037     // constructor used for arising the real agents in the model
00038 
00039     //init the decoupling right counters...
00040     vector<RegActivities*> actMoulds = MTHREAD->RD->getRegActivities();
00041     int nPolicyPremiums = MTHREAD->RD->getResourceSize(RESTYPE_POLICYPREMIUM);
00042     vector <double> tempVector1(nPolicyPremiums, 0);
00043     vector <int> tempVector2(nPolicyPremiums, 0);
00044     for(uint i=0;i<actMoulds.size();i++){
00045         decRights.push_back(tempVector1);
00046         decYears.push_back(tempVector2);
00047         decHa.push_back(tempVector1);
00048     }
00049     grossCoupledPremiums     = 0; // pre-modulation coupled premiums
00050     grossDecoupledPayment  = 0; // pre-modulation decoupled premium
00051     netTotalPremium         = 0; // post-modulation coupled and decoupled premiums
00052 
00053 }
00054 
00055 Agent_farmer::~Agent_farmer(){
00056 
00057 }
00058 
00059 void
00060 Agent_farmer::initMIP(){
00061     OPT.update();
00062     OPT.solve();
00063 }
00064 
00065 void
00066 Agent_farmer::test(){
00067     OPT.solve();
00068 }
00069 
00070 double
00071 Agent_farmer::getAgrDistCost(const Pixel* px1){
00072     return getDistance(px1)* MTHREAD->RD->getDoubleSetting("agrDistCost");
00073 }
00074 
00075 bool
00076 Agent_farmer::filterActivity(matrixActivities* ACT){
00077     if (ACT->plotHost){
00078         if (MTHREAD->GIS->layerExist("dtm")){
00079             // subtracting x% from the gross margin every 100 meters (conservative approach..)
00080             double altitude = ACT->plotHost->getDoubleValue("dtm");
00081             double toSubtract = fabs(ACT->objValue) * (MTHREAD->RD->getDoubleSetting("altitudeGMReduction")* altitude/100);
00082             ACT->objValue -= toSubtract;
00083         }
00084         // subtracting agricultural distance costs...
00085         ACT->objValue -= getAgrDistCost(ACT->plotHost);
00086     }
00087     return true;
00088     // no max (0,returnvalue) as some spatial activities are already negative (e.g. gross silage)
00089 }
00090 
00098 double
00099 Agent_farmer::getShadowPrice(const Pixel* px_h, bool initSolve){
00100 
00101     //QMutex mutexLocal;
00102 
00103     double z1=0, z2=0;
00104     //mutexLocal.lock();
00105     if(initSolve) OPT.solve();
00106     //mutexLocal.unlock();
00107     z1 = OPT.getZ();
00108     OPT.saveToCache();
00109     OPT.addPixel(px_h);
00110     OPT.solve();
00111     z2 = OPT.getZ();
00112     OPT.removeLastAddedPixel();
00113     OPT.restoreFromCache();
00114     return max(((double) 0), z2-z1);
00115 }
00116 
00123 double
00124 Agent_farmer::offerRentalPrice(const Pixel* px_h, bool initSolve){
00125 
00126     /*
00127     double debug1=0;
00128     double debug2=0;
00129     vector<RegActivities*> actMoulds = MTHREAD->RD->getRegActivities();
00130     vector<ModelObject*> objects     = MTHREAD->RD->getObjectsDefinitionVector();
00131     for (int i=0;i<1000;i++){
00132         debug1 = MTHREAD->RD->getDoubleSetting("fixedRentalCosts")+debug1;
00133         debug2 = MTHREAD->RD->getDoubleSetting("variableRentalCosts")+debug2;
00134     }
00135 
00136     return (debug1+debug2)/1000;
00137     */
00138 
00139 
00140     double shPrice, toOffer;
00141     double fixedRentalCosts, variableRentalCosts;
00142     //mutex.lock();
00143     fixedRentalCosts = MTHREAD->RD->getDoubleSetting("fixedRentalCosts");
00144     variableRentalCosts = MTHREAD->RD->getDoubleSetting("variableRentalCosts");
00145     //mutex.unlock();
00146     shPrice = getShadowPrice(px_h, initSolve);
00147     toOffer = (shPrice - fixedRentalCosts)*(1-variableRentalCosts);
00148 
00149     if (toOffer >= 0 ) {
00150         return toOffer;
00151     } else {
00152         return ((double)0);
00153     }
00154 
00155 }
00156 
00157 double
00158 Agent_farmer::getUAA(int ptype){
00159     int nPlots=0;
00160     if (ptype == PLOTS_OWNED || ptype== PLOTS_ALL){
00161         nPlots += ownedPlots.size();
00162     }
00163     if (ptype==PLOTS_RENTED || ptype== PLOTS_ALL){
00164         nPlots += rentedPlots.size();
00165     }
00166     return nPlots*MTHREAD->GIS->getHaByPixel();
00167 }
00168 
00169 
00170 void
00171 Agent_farmer::collectProductionEffects(){
00172 
00173     //OPT.debug();
00174 
00175     debugLandUse = 0;
00176     vector <string> policyPremiumNames = MTHREAD->RD->getResourceNames(RESTYPE_POLICYPREMIUM);
00177     int nPolicyPremiums = policyPremiumNames.size();
00178     double plotHostID;
00179 
00180     // initializing the recording of decoupling premium rights...
00181     vector<RegActivities*> actMoulds = MTHREAD->RD->getRegActivities();
00182     vector< vector<double> > currentCoupledPremiums; // by activities/premiumTypes
00183     vector< vector<double> > currentCoupledHa; // by activities/premiumTypes
00184     for(uint i=0;i<actMoulds.size();i++){
00185             vector<double> currentCoupledPremiumsTemp(nPolicyPremiums,0);
00186             vector<double> currentCoupledHaTemp(nPolicyPremiums,0);
00187             currentCoupledPremiums.push_back(currentCoupledPremiumsTemp);
00188             currentCoupledHa.push_back(currentCoupledHaTemp);
00189     }
00190 
00191     // add newly invested objects to the farmer or to the plot and editing the farmActivities layer..
00192     vector <matrixActivities*> activities = OPT.getActs();
00193     for(uint i=0; i<activities.size(); i++){
00194         if(activities[i]->isInvest){
00195             for(uint q=0; q< ((uint)activities[i]->q); q++){
00196                 ModelObject newObject = MTHREAD->RD->getObjectByName(activities[i]->name);
00197                 liquidity -= newObject.getInitialCost();
00198                 if(activities[i]->isSpatial()){ // we assign the object to the plot...
00199                     // activities[i]->plotHost->acquireObject(newObject); // now it's const !
00200                     plotHostID = activities[i]->plotHost->getID();
00201                     MTHREAD->GIS->getPixel(plotHostID)->acquireObject(newObject);
00202                 }
00203                 else { // we assign the object to the farmer...
00204                     this->acquireObject(newObject);
00205                 }
00206             }
00207         }
00208 
00209         // changed 24.nov.2007. It was missing to report the quantities of activities associated with the spatial new objects (that are coupled with their activities)
00210         // If it is a spatial activity, both as "normal" activity or as a spatial new investment (rather than a "traditionale" new investment activity), and has been selected by the farmer
00211         if(activities[i]->isSpatial() && activities[i]->q >0 ){
00212             RegActivities* actMould=0;
00213             plotHostID = activities[i]->plotHost->getID();
00214             if (activities[i]->actMould) { actMould = activities[i]->actMould;}
00215             else if ( activities[i]->objMould) {
00216                 actMould=MTHREAD->RD->getRegActivityByName(activities[i]->objMould->getRequiredFor());
00217             }
00218             else {msgOut(MSG_CRITICAL_ERROR, "BOOM! All spatial activities should have an object or activity mould!");}
00222             if( activities[i]->q > 0.6){
00223                 MTHREAD->GIS->getPixel(plotHostID)->changeValue("farmActivities",actMould->getMapCode());
00224             }
00225             else {
00226                 if(activities[i]->plotHost->getDoubleValue("farmActivities")==MTHREAD->GIS->getNoValue()){
00227                     MTHREAD->GIS->getPixel(plotHostID)->changeValue("farmActivities",900);
00228                 }
00229             }
00230             debugLandUse += activities[i]->q;
00231         }
00232 
00233         // getting the premium right associated to each each activityMould (from activities and spatial objects that embed the activity)
00234         if(activities[i]->q >0 ){           
00235             for(uint j=0;j<actMoulds.size();j++){
00236                 bool pass = false;
00237                 if (activities[i]->actMould && (activities[i]->name == actMoulds[j]->getName())) {
00238                     pass = true;
00239                 } else if (activities[i]->objMould && (activities[i]->objMould->getRequiredFor() == actMoulds[j]->getName())) {
00240                     pass = true;
00241                 }
00242 
00243                 if(pass ){
00244                     for(uint y=0;y<nPolicyPremiums;y++){
00245                         currentCoupledPremiums[j][y] += -activities[i]->q * actMoulds[j]->getMatrixCoefficientByName(policyPremiumNames[y]);
00246                         currentCoupledHa[j][y] += activities[i]->q;
00247                     }
00248                     break;
00249                 }
00250             }
00251         }
00252     }
00253 
00254     // recording decoupling premium rights...
00255     for(uint i=0;i<actMoulds.size();i++){
00256         for(uint y=0;y<nPolicyPremiums;y++){
00257             if (actMoulds[i]->getDecouplingOption(y) == -1) { // we are in a "registration mode"
00258                 double oldDecRights = decRights[i][y];
00259                 double oldDecHa = decHa[i][y];
00260                 int  oldCountedYears = decYears[i][y];
00261                 // new average = old average * years + new value, all divided by years of the old average plus one (this year)
00262                 // checked
00263                 decRights[i][y]= (oldDecRights*((double)oldCountedYears) + currentCoupledPremiums[i][y]) / ((double) oldCountedYears +1);
00264                 decHa[i][y]= (oldDecHa*((double)oldCountedYears) + currentCoupledHa[i][y]) / ((double) oldCountedYears +1);
00265                 decYears[i][y]++;
00266             }
00267         }
00268     }
00269 
00270     // calculating premiums and storing results...
00271     // TODO: (maybe) make the modulation enter the MIP, even if now coupled premium are of much less importance..
00272     grossCoupledPremiums=0;   // pre-modulation coupled premiums
00273     for(uint i=0;i<actMoulds.size();i++){
00274         for(uint y=0;y<nPolicyPremiums;y++){
00275             if(currentCoupledPremiums[i][y]>0){ // without this check also the "cash the premium" activity enter the counter, making it 0 !! 
00276                 grossCoupledPremiums += currentCoupledPremiums[i][y];
00277             }
00278         }
00279     }
00280     netProductionProfit  = OPT.getZ()-grossCoupledPremiums;
00281     grossDecoupledPayment = getDecoupledPayments();
00282 
00283     netTotalPremium = applyModulation(grossCoupledPremiums + grossDecoupledPayment);
00284 
00285     //int debugID = agentUniqueID;
00286     //int debugIteration = MTHREAD->SCD->getIteration();
00287     //double debugOPT = OPT.getZ();
00288     //double debugGrossCoupledPremiums = grossCoupledPremiums;
00289     //double debugGrossDecoupledPayment = grossDecoupledPayment;
00290 
00291     // add profit to liquidity...
00292     liquidity += (netProductionProfit+netTotalPremium);
00293 
00294 }
00295 
00296 double
00297 Agent_farmer::applyModulation(double grossPremium){
00298 
00299     double threshold1         = MTHREAD->RD->getDoubleSetting("threshold1",DATA_NOW);
00300     double threshold2         = MTHREAD->RD->getDoubleSetting("threshold2",DATA_NOW);
00301     double threshold3         = MTHREAD->RD->getDoubleSetting("threshold3",DATA_NOW);
00302     double threshold4         = MTHREAD->RD->getDoubleSetting("threshold4",DATA_NOW);
00303     double threshold5         = MTHREAD->RD->getDoubleSetting("threshold5",DATA_NOW);
00304 
00305     double modulationShare1   = MTHREAD->RD->getDoubleSetting("modulationShare1",DATA_NOW);
00306     double modulationShare2   = MTHREAD->RD->getDoubleSetting("modulationShare2",DATA_NOW);
00307     double modulationShare3   = MTHREAD->RD->getDoubleSetting("modulationShare3",DATA_NOW);
00308     double modulationShare4   = MTHREAD->RD->getDoubleSetting("modulationShare4",DATA_NOW);
00309     double modulationShare5   = MTHREAD->RD->getDoubleSetting("modulationShare5",DATA_NOW);
00310     double modulationShare6   = MTHREAD->RD->getDoubleSetting("modulationShare6",DATA_NOW);
00311 
00312 
00313     bool firstSpecial  = MTHREAD->RD->getBoolSetting("firstModLevelIsATreasholdOnly",DATA_NOW);
00314 
00315     double byeByeMoney=0; // ;-)
00316 
00317     // If firstModLevelIsATreasholdOnly has been actived the first level of modulation is "spacial" and it applyes only to payments below threshold1..
00318     if (firstSpecial && grossPremium >= threshold1) modulationShare1 = 0;
00319 
00320     if(grossPremium > threshold5){
00321         byeByeMoney =    modulationShare6 * (grossPremium-threshold5)
00322                        + modulationShare5 * (threshold5 -threshold4)
00323                        + modulationShare4 * (threshold4 -threshold3)
00324                        + modulationShare3 * (threshold3 -threshold2)
00325                        + modulationShare2 * (threshold2 -threshold1)
00326                        + modulationShare1 * threshold1;
00327 
00328     } else if (grossPremium > threshold4){
00329         byeByeMoney =    modulationShare5 * (grossPremium -threshold4)
00330                        + modulationShare4 * (threshold4 -threshold3)
00331                        + modulationShare3 * (threshold3 -threshold2)
00332                        + modulationShare2 * (threshold2 -threshold1)
00333                        + modulationShare1 * threshold1;
00334 
00335     } else if (grossPremium > threshold3){
00336         byeByeMoney =    modulationShare4 * (grossPremium  -threshold3)
00337                        + modulationShare3 * (threshold3 -threshold2)
00338                        + modulationShare2 * (threshold2 -threshold1)
00339                        + modulationShare1 * threshold1;
00340 
00341     } else if (grossPremium > threshold2){
00342         byeByeMoney =    modulationShare3 * (grossPremium -threshold2)
00343                        + modulationShare2 * (threshold2 -threshold1)
00344                        + modulationShare1 * threshold1;
00345 
00346     } else if (grossPremium > threshold1){
00347         byeByeMoney =    modulationShare2 * (grossPremium -threshold1)
00348                        + modulationShare1 * threshold1;
00349 
00350     } else {
00351         byeByeMoney =    modulationShare1 * grossPremium;
00352     }
00353 
00354     return grossPremium-byeByeMoney;
00355 
00356 }
00357 
00358 void
00359 Agent_farmer::update(){
00360     // removing dead investment objects
00361     vector<ModelObject>::iterator p;
00362     for ( p = myObjects.begin() ; p != myObjects.end();){
00363         if(p->getLastYear() <= MTHREAD->SCD->getYear()){
00364             myObjects.erase(p);
00365         }
00366         else {
00367             ++p;
00368         }
00369     }
00370 
00371     // removing pixel pointers from the list of rented plots. Before doing that I call nextYear() on plots so I am sure that out-of-scope objects are deleted before run OPT->upgrade()
00372     vector<Pixel*>:: iterator p2;
00373     for ( p2 = rentedPlots.begin(); p2 != rentedPlots.end();){
00374         if( (*p2)->getLastRentingYear() <= MTHREAD->SCD->getYear()){
00375             (*p2)->newYear();
00376             rentedPlots.erase(p2);
00377         }
00378         else {
00379             ++p2;
00380         }
00381     }
00382     OPT.update(); // update as the farmer may have lost pixels and objects
00383 }
00384 
00385 int
00386 Agent_farmer::leaveActivity(){
00387     //TOexDO: changeValue on farmsteads layer on NULL. Check the owned and rented plots as well. It is the manager that will do it
00388     double minEqC = MTHREAD->RD->getDoubleSetting("minEC");
00389     bool forceFarmingForCashPremium = MTHREAD->RD->getBoolSetting("forceFarmingForCashPremium", DATA_NOW);
00390     
00391     if(getCapital(true)<=0){
00392         msgOut(MSG_DEBUG, "Farm "+i2s(getAgentUniqueID())+" left the model for shortage of owned capital.. bye, bye..");
00393         return AGEXIT_NOCAPITAL;
00394     } else if (liquidity < - ( getCapital(true) * (1-minEqC)/minEqC) ) {
00395         msgOut(MSG_DEBUG, "Farm "+i2s(getAgentUniqueID())+" left the model for shortage of liquidity.. bye, bye..");
00396         return AGEXIT_DEBS;
00397     } else {
00398         double realProfit = netProductionProfit + netTotalPremium - sunkCostsPaid;
00399         liquidityShPrice = max(((double)0), liquidity)* OPT.getActivityObjValue("sellLiquidity");
00400         labourShPrice =  getResource("labour") * OPT.getActivityObjValue("offFarmLabour");
00401         landShPrice = 0 ;
00402         vector <double> rentalPrices = MTHREAD->RD->getDoubleVectorSetting("agrRentalPrices");
00403         vector <int> agrLandTypes = MTHREAD->RD->getIntVectorSetting("agrLandTypes");
00404 
00405         
00406         for (uint i=0;i<ownedPlots.size();i++){
00407             // SHADOW VALUE CALIBRATED ON FIRST YEAR AND THEN RETRIEVED FROM AVG RENTAL PRICE
00408             int type= ((int)ownedPlots[i]->getDoubleValue("landUse"));
00409             for (uint j=0;j<agrLandTypes.size();j++){
00410                 if (type == agrLandTypes[j]){
00411                     double  plotShadowPrice = rentalPrices.at(j)*ownedPlots[i]->getShRentalPriceCoeff();
00412                     landShPrice += plotShadowPrice; // /3 is a good number... no, it was for a bug. now doesn't needed
00413                     break;
00414                 }
00415             }
00416         }
00417 
00418         double premiumLeaving =0; // premium the farmer receive even in the case of leaving
00419         if (!forceFarmingForCashPremium){
00420             premiumLeaving += applyModulation(grossDecoupledPayment);
00421         }
00422 
00423         if (realProfit < (MTHREAD->RD->getDoubleSetting("oppCostsCoeff") * (liquidityShPrice+labourShPrice+landShPrice) ) + premiumLeaving ) {
00424             msgOut(MSG_DEBUG, "Farm "+i2s(getAgentUniqueID())+" left the model for better shadow prices of owned factors.. bye, bye..");
00425             return AGEXIT_SHPRICES;
00426         }
00427     }
00428     return AGEXIT_FALSE;
00429     
00430 }
00431 
00432 double
00433 Agent_farmer::getDecoupledPayments(){
00434     
00435     double decPayments = initialDecPayment;
00436     vector<RegActivities*> actMoulds = MTHREAD->RD->getRegActivities();
00437     vector <string> policyPremiums = MTHREAD->RD->getResourceNames(RESTYPE_POLICYPREMIUM);
00438     int nPolicyPremiums = policyPremiums.size();
00439 
00440     int debugYear = MTHREAD->SCD->getYear();
00441     int farmerID = getAgentUniqueID(); 
00442 
00443     if(!MTHREAD->RD->getBoolSetting("regionalisation", DATA_NOW)){  // history-based
00444         for(uint i=0;i<actMoulds.size();i++){
00445             for(uint y=0; y<nPolicyPremiums;y++){
00446                 if (actMoulds[i]->getDecouplingOption(y) >= 0) { // we are NOT in a "registration mode"
00447                     decPayments += actMoulds[i]->getDecouplingOption(y)*decRights.at(i).at(y);
00448                 }
00449             }
00450         }
00451     } else { // regionalisation
00452         double totHa = 0;
00453         for(uint i=0;i<actMoulds.size();i++){
00454             totHa += dVSum(decHa[i]);
00455         }
00456         decPayments += ((Manager_farmers*)manager) -> getAverageRightsByAct() * totHa;
00457     }
00458 
00459     return decPayments;
00460 }
00461