[PYTHON] Farmer economy simulation ② (net-seller, self-sufficient farmer, net-buyer utility maximization action) _

This article is a continuation of "Farmer Economy Simulation ①", so I would appreciate it if you could read only the introductory part of that article first. In "... ①", we explained the model inside the simulation and the final goal.

So In this "... ②", I will introduce the code of the farm economy simulation that I made by myself. Let's take a look at "Model Overview", "Code", and "Simulation Results"!

Environmental information

This article python 3.8.3 scipy 1.5.0 Is used on jupyter notebook. (Is this the way to write ...?)

Model overview

Explanation of farmer behavior

Farmers have a "labor force" and "farmland" that they use to produce grain A, which they eat, sell, and buy on their own.

Grain A has the image of corn for feed, and the place has the image of rural Mexico.

At the same time, farmers are also consumers, so they consume "leisure" and "other goods" to maximize their utility. Therefore, in this simulation, the "problem of maximizing the utility of farmers under budget constraints" is the core of the logic.

In addition, based on Janvry (1991), farmers were divided into the following three patterns. ** net-seller ** = "Sell the surplus after self-sufficiency of grain A" ** Self-sufficient farmer ** = "Completely self-sufficient in grain A" ** net-buyer ** = "Self-sufficient grain A and buy the shortage from others"

The details are explained in "... ①", so please check there.

Code flow description

① Use Class to set 3 patterns of farmer behavior. (2) Use Class to set the Market (role that holds price information). ③ Create a function that increases the price of grain A by 1.5 times. Create a function that multiplies the price of other goods by 0.9. Create a function that increases the price of grain A by 1.5 times and at the same time the price of other goods by 0.9 times. ④ The price of grain A and the price of other goods are changed as follows. ** Note ** </ sup> 1-10 period: Initial price stable 11th term: A price increase 12-20 period: Price stability 21st term: Decrease in prices of other goods 22-30 period: Price stability 31st term: A and other goods price changes 32-40 period: Price stability ⑤ Put the result in a list and output it.

** Note ** </ sup> The reason for the long span of stability is that we plan to fluctuate variables other than price in the next phase of what we did in this blog.

code

Calculate the parameters of the utility function

First, check out "trabajos_2018.csv", "poblacion_2018.csv", and "concentradohogar_2018.csv" from the 2018 Household Consumption Survey (ENIGH) published by the National Institute of Statistics and Geography (INEGI) of Mexico. Put it in the directory you are currently opening. https://www.inegi.org.mx/programas/enigh/nc/2018/

Then run the following code.

#Module import
import numpy as np
import pandas as pd
from tqdm import tqdm_notebook as tqdm

#Estimating the parameters used in the utility function
#Total number of hours worked per week (probably the total number of hours worked by adult members)
tr_ori = pd.read_csv("trabajos_2018.csv", usecols=["folioviv", "htrab"])
#The folio viv was duplicated. Perhaps different households in the same wife are separated. Add this.
#Make a box
tr = pd.DataFrame(np.arange(4).reshape(2,2), columns=["folioviv", "htrab"], index=[1, 2])
tr = tr.drop(tr.index[[0, 1]])
tr = tr.reset_index(drop=True)
#Calculate the sum for each unique folioviv and put it in the box.
vivs = tr_ori["folioviv"].unique()
vivs = vivs.tolist()
for viv in tqdm(vivs):
    trr = tr_ori[tr_ori["folioviv"]==viv]
    htrab = trr["htrab"].sum()
    #append
    tr = tr.append({"folioviv":viv, "htrab":htrab}, ignore_index=True)

#cost
"""
mayores:12 years old and over, ing_cor:Monthly gross income, trabajo:Negocio, the income earned by working outside the monthly self-employed:Monthly self-employed income, vesti_calz:Total cost for clothing,
salud:Total cost spent on medical care, foraneo:Overseas shipping costs, mantenim:Automotive system, comunica:Information transmission, educa_espa:Education and Fiesta etc.
"""
co = pd.read_csv("concentradohogar_2018.csv", usecols=["folioviv", "tam_loc", "mayores", "ing_cor", "trabajo", "negocio", "frutas", "azucar",
                                                      "cafe", "bebidas", "tabaco", "vesti_calz", "salud", "foraneo", "mantenim",
                                                      "comunica", "educa_espa"])

#State identifier
pb = pd.read_csv("poblacion_2018.csv", usecols=["folioviv", "residencia"])

#Join df
df = pd.merge(co, pb, on="folioviv")
df = pd.merge(df, tr, on="folioviv")
df = df[~df.duplicated()]   #For some reason there was duplicate work, so I deleted the duplicate lines
df = df[df["residencia"]!=" "]   #The state is blank for some reason""I deleted that line because it sometimes became
df = df[df["tam_loc"]!=1]   #Limited to the countryside
df = df[df["tam_loc"]!=2]

#Total amount of consumption judged to be relatively close to entertainment
df["sum_cons"] = df["frutas"] + df["azucar"] + df["cafe"] + df["bebidas"] + df["tabaco"] + df["vesti_calz"] + df["salud"] + df["foraneo"] + df["mantenim"] + df["comunica"] + df["educa_espa"]

#Identify if you are self-employed
df["self"] = (df["negocio"] > 0) * 1

#Find the average wage of non-self-employed people
nonself = df[df["self"]==0]
wage = (nonself["trabajo"].sum() / 30) / (nonself["htrab"].sum() / 7)   #Income is monthly and working hours are weekly, so adjust to daily

#Measures per household, per day, and leisure time. Leisure time = number of adult household members x 24-Household working hours/7 -Number of adult household members x sleep time(6)
df["leisure"] = df["mayores"] * 24 - df["htrab"] / 7 - df["mayores"] * 6
#Calculate the monthly income you sacrificed by taking leisure time
df["opportunity"] = df["leisure"] * wage * 30

#Total income from other consumer goods and income sacrificed in leisure+Calculate what percentage of the sacrificed income(Overall average)
income = df["ing_cor"].sum() + df["opportunity"].sum()
consumption = df["sum_cons"].sum()
opportunity = df["opportunity"].sum()
con_in = consumption / income
opp_in = opportunity / income

by this, "Average wage (hourly wage) excluding countryside and self-employed people" = 75.25114451327885 "Opportunity cost when spending leisure time / total consumption" = 0.7171948682330835 "Total consumption of non-necessary goods / total consumption" = 0.06287930254251227 Was obtained.

In this simulation, the utility is represented by a quadratic model, and the latter two obtained in ↑ are used as parameters of the utility function. For details, including that this method is theoretically wrong, please refer to "... ①".

Even if you don't bother to execute the code shown above, you can type in the ↑ value itself in the following code.

Main execution part

Most of the global variables set at the beginning are taken from actual data. Please check "... ①" for what kind of data you used.

① Self-sufficient farmer

↓ Fixed a little (I forgot to import tqdm first, so I added it)

#Module import
from tqdm import tqdm_notebook as tqdm
from scipy.optimize import minimize

#Global variable (4 months as 1 cycle)
ao = 0.06                         #Coefficient when consuming other goods(0.06)
al = 0.72                         #Coefficient when consuming leisure(0.72)
aoo = 0.01                        #Coefficient when consuming only other goods (low because it is hard because there is no time to rest)
aLl = 0.01                        #Coefficient for consuming only leisure time (low because there is nothing to play and free time)
aol = 0.15                        #The joy of using it evenly
w = 75.3                          #wage(Hourly wage)
tw = 20                           #Transaction costs per unit when selling labor in the labor market
ta = 5024207380 / 8324248200 / 10 #Transaction costs when selling A (easily set to 1/10 of the price)
r = 2000 * 4                      #Land price (land rent on the premise of renting in a lump sum for 4 months)
SEED = 12345                      #Seed value
R = 40                            #Setting the number of repetitions
L = (24 - 6) * 30 * 4             #Initial endowed workforce (hours per 4 months)
Yield = 5024207380 / 396397.92    #Single yield (kg/ ha)
Equip = 1 / 52                    #Land equipment rate (ha/time)
appe = 0.25 * 30 * 4              #Satiety restriction (amount to eat per 4 months)
price0 = 5024207380 / 8324248200  #Crop price (peso/ha)
milk_meat = 130/4 + 25/4          #Food expenses

#Class definition
class Autarky:
    """Definition of a class that represents a self-sufficient farmer"""
    def __init__(self, cat):   #constructor
        self.category = cat
        self.oriA = 2         #Land area owned(ha)
        self.oriL = L         #Working hours
        self.utility = 0      #Maximum utility (0 for the time being)
        self.co = 0           #Maximum utility O consumption
        self.l = 0            #Leisure time at maximum utility
        self.C = 0            #Total consumption at maximum utility
        self.profit = 0       #Profit at maximum utility
        self.qa = 0           #A production volume at maximum utility
        self.LA = 0           #Below, the amount of each production factor used at the maximum utility
        self.AA = 0
        self.Ln = 0
        self.An = 0
    """
Utility maximization problem
    x = [co, La, Ln, l, Aa, An]
    """
    def solveUmax(self, Market):   #Produce A and B to maximize profits
        pA = Market.pA
        po = Market.po
        oriA = self.oriA
        oriL = self.oriL
        """Utility function"""
        def utility(x):   #Secondary model
            return -1 * (ao*x[0] + al*x[3] + 1/2*(aoo*x[0]*x[0] + aLl*x[3]*x[3] + aol*x[0]*x[3]))
        """Liquidity constraints"""
        def cons_liquidity(x):
            return (w - tw) * x[2] + r * x[5] - po * x[0] - milk_meat
        """Hunger constraint"""
        def appetite(x):
            return Yield * Equip * x[1] - appe
        """Relationship between land area and input labor force"""
        def labor_land(x):
            return x[4] - Equip * x[1]
        """Endowed element constraints"""
        def labor_cons(x):
            return oriL - x[1] - x[2] - x[3]
        def land_cons(x):
            return oriA - x[4] - x[5]
        """Sign constraint of each variable"""
        def co(x):
            return x[0]
        def La(x):
            return x[1]
        def Ln(x):
            return x[2]
        def l(x):
            return x[3]
        def Aa(x):
            return x[4]
        def An(x):
            return x[5]
        
        cons = ({"type": "ineq", "fun": cons_liquidity}, {"type": "ineq", "fun": appetite}, {"type": "ineq", "fun": labor_land},
               {"type": "ineq", "fun": co}, {"type": "ineq", "fun": La}, {"type": "ineq", "fun": Ln}, {"type": "ineq", "fun": l},
               {"type": "ineq", "fun": Aa}, {"type": "ineq", "fun": An}, {"type": "eq", "fun": labor_cons}, 
               {"type": "ineq", "fun": land_cons})
        
        #The initial value is the state in which all the elements are included in the production of A.
        x0 = [0, oriL, 0, 0, oriA, 0]
        
        res = minimize(utility, x0, constraints=cons, method="SLSQP")   #Command to solve an optimization problem
        
        #What to do when the result is negative
        while (res.x[0] < 0) or (res.x[1] < 0) or (res.x[2] < 0) or (res.x[3] < 0) or (res.x[4] < 0) or (res.x[5] < 0):
            x0 = []
            for X in res.x:
                if X < 0:
                    X = 0
                x0.append(X)
            res = minimize(utility, x0, constraints=cons, method="SLSQP")
        
        
        """I will put away the calculated result"""
        self.LA = res.x[1]
        self.Ln = res.x[2]
        self.AA = res.x[4]
        self.An = res.x[5]
        self.co = res.x[0]
        self.l = res.x[3]
        self.utility = - 1 * res.fun
        self.profit = (w - tw) * res.x[2] + r * res.x[5]
        self.qa = Yield * Equip * res.x[1]
        self.C = po * res.x[0] 
#End of definition of class Autarky


#Class definition Market
class Market:
    def __init__(self):
        self.pA = price0
        self.po = 30   
    def price_A(self):   #pA is 1.Price increase 5 times
        self.pA *= 1.5
    def price_o(self):   #po is 90%Price cut to
        self.po *= 0.9
#End of definition of class Market

        
#Definition of subcontracting function
#Calcn that controls the calculation of the next term when the price does not change_n()Function definition
def calcn_n(t, a, Market):
    #① Put the price at the beginning of this term in the list
    pAlist.append(Market.pA)
    polist.append(Market.po)
    tlist.append(t)            #time
    #② Optimizing the utility of self-sufficient farmers
    for i in range(len(a)):
        a[i].solveUmax(Market)


#Calcn that controls the next calculation when pA changes once_A()Function definition
def calcn_A(t, a, Market):
    #① Change in pB price
    Market.price_A()
    #② Add the price at the beginning of this term to the list
    pAlist.append(Market.pA)   #price
    polist.append(Market.po)
    tlist.append(t)            #time
    #③ Optimizing the utility of farmers
    for i in range(len(a)):
        a[i].solveUmax(Market)

    
#Calcn that controls the next calculation when po changes once_o()Function definition
def calcn_o(t, a, Market):
    #① Change in po price
    Market.price_o()
    #② Add the price at the beginning of this term to the list
    pAlist.append(Market.pA)   #price
    polist.append(Market.po)
    tlist.append(t)            #time
    #③ Optimizing the utility of farmers
    for i in range(len(a)):
        a[i].solveUmax(Market)


#Calcn that controls the next calculation when pA and po change once_Ao()Function definition
def calcn_Ao(t, a, Market):
    #① Changes in pA and po prices
    Market.price_A()
    Market.price_o()
    #② Add the price at the beginning of this term to the list
    pAlist.append(Market.pA)   #price
    polist.append(Market.po)
    tlist.append(t)            #time
    #③ Optimizing the utility of farmers
    for i in range(len(a)):
        a[i].solveUmax(Market)


#Calc that calculates the aggregated value of the element and adds it to the list_list()Function definition
def calc_list(a):
    qa = 0
    profit = 0
    LA = 0
    Ln = 0
    AA = 0
    An = 0
    l = 0
    co = 0
    utility = 0
    C = 0
    for i in range(len(a)):
        qa += a[i].qa
        profit += a[i].profit
        LA += a[i].LA
        AA += a[i].AA
        Ln += a[i].Ln
        An += a[i].An
        l += a[i].l
        co += a[i].co
        utility += a[i].utility
        C += a[i].C
    utilitylistA.append(utility)
    colistA.append(co)
    ClistA.append(C)
    profitlistA.append(profit)
    qalistA.append(qa)
    LAlistA.append(LA)
    AAlistA.append(AA)
    AnlistA.append(An)
    LnlistA.append(Ln)
    llistA.append(l)


#Main executive
#Initialization
Market = Market()      #Put an instance of class Market in a variable
#Duplicate an instance of Autarky of category 0 in the list (planned to be done, this time one by one)
a = [Autarky(0)]
#Listing of farmer status
utilitylistA = []
ca_plistA = []
colistA = []
ClistA = []
profitlistA = []
qalistA = []
qblistA = []
LAlistA = []
AAlistA = []
AnlistA = []
LnlistA = []
llistA = []
#Listing prices and product remainders
pAlist = []
polist = []
#List of times
tlist = []

#simulation
for t in tqdm(range(R)):
    if t <= 10:                     # 1~10th term: Initial price
        calcn_n(t, a, Market)
        calc_list(a)
    if t == 11:                     #11th term: A price change
        calcn_A(t, a, Market)
        calc_list(a)
    if (t > 11) and (t <= 20):      # 12~20th term: A Stable after price change
        calcn_n(t, a, Market)
        calc_list(a)
    if t == 21:                     #21st term: o Price change
        calcn_o(t, a, Market)
        calc_list(a)
    if (t > 21) and (t <= 30):      # 22~30th term: o Stable after price change
        calcn_n(t, a, Market)
        calc_list(a)
    if t == 31:                     #31st term: A and o price changes
        calcn_Ao(t, a, Market)
        calc_list(a)
    if (t > 31) and (t <= 40):     # 32~40th term: A and o Stable after price change
        calcn_n(t, a, Market)
        calc_list(a)
#End of simulation part

#View the list of important variables as is
print("income",profitlistA,"\n","\n","A production",qalistA,"\n","\n","LA",LAlistA,"\n","\n","Ln",LnlistA,"\n","\n","l", llistA, "\n","\n", 
      "A farmland", AAlistA, "\n","\n","Rental farmland",AnlistA, "\n","\n","utility",utilitylistA, "\n","\n", "o consumption",colistA,"\n","\n","C",ClistA, "\n","\n",
      "pA",pAlist,"\n","\n","po",polist)

# sell&buy.py

②net-seller (1) Change the part of the code shown by the self-sufficient farmer up to "# Class definition // Class Autarky: ~ # End of definition of class Autarky" to the following code.

#Class definition
class Seller:
    """Definition of a class that represents a self-sufficient farmer"""
    def __init__(self, cat):   #constructor
        self.category = cat
        self.oriA = 2         #Land area owned
        self.oriL = L        #Working hours
        self.utility = 0      #Maximum utility (0 for the time being)
        self.co = 0           #Maximum utility O consumption
        self.l = 0            #Leisure time at maximum utility
        self.C = 0            #Total consumption at maximum utility
        self.profit = 0       #Profit at maximum utility
        self.qa = 0           #A production volume at maximum utility
        self.LA = 0           #Below, the amount of each production factor used at the maximum utility
        self.AA = 0
        self.Ln = 0
        self.An = 0
    """
Utility maximization problem
    x = [co, La, Ln, l, Aa, An]
    """
    def solveUmax(self, Market):   #Produce A and B to maximize profits
        pA = Market.pA
        po = Market.po
        oriA = self.oriA
        oriL = self.oriL
        """Utility function"""
        def utility(x):   #Secondary model
            return -1 * (ao*x[0] + al*x[3] + 1/2*(aoo*x[0]*x[0] + aLl*x[3]*x[3] + aol*x[0]*x[3]))
        """Liquidity constraints"""
        def cons_liquidity(x):
            return (pA - ta) * (Yield * Equip * x[1] - appe) - po * x[0] - (w + tw) * x[2] - r * x[5] - milk_meat
        """Hunger constraint"""
        def appetite(x):
            return Yield * Equip * x[1] - appe
        """Relationship between land area and input labor force"""
        def labor_land(x):
            return x[4] + x[5] - Equip * (x[1] + x[2])
        """Endowed element constraints"""
        def labor_cons(x):
            return oriL - x[1] - x[3]
        def land_cons(x):
            return oriA - x[4]
        """Sign constraint of each variable"""
        def co(x):
            return x[0]
        def La(x):
            return x[1]
        def Ln(x):
            return x[2]
        def l(x):
            return x[3]
        def Aa(x):
            return x[4]
        def An(x):
            return x[5]
        def Anmax(x):
            return 100 - x[5]
        
        cons = ({"type": "ineq", "fun": cons_liquidity}, {"type": "ineq", "fun": appetite}, {"type": "ineq", "fun": labor_land},
               {"type": "ineq", "fun": co}, {"type": "ineq", "fun": La}, {"type": "ineq", "fun": Ln}, {"type": "ineq", "fun": l},
               {"type": "ineq", "fun": Aa}, {"type": "ineq", "fun": An}, {"type": "eq", "fun": labor_cons}, 
               {"type": "ineq", "fun": land_cons}, {"type": "ineq", "fun": Anmax})
        
        #The initial value is the state in which all the elements are included in the production of A.
        x0 = [0, oriL, 0, 0, oriA, 0]
        
        res = minimize(utility, x0, constraints=cons, method="SLSQP")   #Command to solve an optimization problem
        
        #What to do when the result is negative
        while (res.x[0] < 0) or (res.x[1] < 0) or (res.x[2] < 0) or (res.x[3] < 0) or (res.x[4] < 0) or (res.x[5] < 0):
            x0 = []
            for X in res.x:
                if X < 0:
                    X = 0
                x0.append(X)
            res = minimize(utility, x0, constraints=cons, method="SLSQP")
        
        #What to do when the labor input becomes 0 even though the farmland input is quite large(Change the initial value a little and start over)
        if (res.x[1] <= 0) and (res.x[4] > 1):
            x0 = [0, oriL - 1, 0, 1, Equip * (oriL - 1), 0]
            res = minimize(utility, x0, constraints=cons, method="SLSQP")
            #What to do when the result is negative 2
            while (res.x[0] < 0) or (res.x[1] < 0) or (res.x[2] < 0) or (res.x[3] < 0) or (res.x[4] < 0) or (res.x[5] < 0):
                x0 = []
                for X in res.x:
                    if X < 0:
                        X = 0
                    x0.append(X)
                res = minimize(utility, x0, constraints=cons, method="SLSQP")
        
        """I will put away the calculated result"""
        self.LA = res.x[1]
        self.Ln = res.x[2]
        self.AA = res.x[4]
        self.An = res.x[5]
        self.co = res.x[0]
        self.l = res.x[3]
        self.utility = - 1 * res.fun
        self.profit = (pA - ta) * (Yield * Equip * res.x[1] - appe)
        self.qa = Yield * Equip * res.x[1]
        self.C = po * res.x[0] + (w + tw) * res.x[2] + r * res.x[5]
#End of definition of class Seller

Next, the 4th line below "# Main Execution Department"

a = [Autarky(0)]

To

a = [Seller(0)]

Please.

③net-buyer (1) Change the part of the code shown by the self-sufficient farmer up to "# Class definition // Class Autarky: ~ # End of definition of class Autarky" to the following code.

#Class definition
class Buyer:
    """Definition of a class that represents a self-sufficient farmer"""
    def __init__(self, cat):   #constructor
        self.category = cat
        self.oriA = 2         #Land area owned
        self.oriL = L        #Working hours
        self.utility = 0      #Maximum utility (0 for the time being)
        self.co = 0           #Maximum utility O consumption
        self.ca = 0
        self.l = 0            #Leisure time at maximum utility
        self.C = 0            #Total consumption at maximum utility
        self.profit = 0       #Profit at maximum utility
        self.qa = 0           #A production volume at maximum utility
        self.LA = 0           #Below, the amount of each production factor used at the maximum utility
        self.AA = 0
        self.Ln = 0
        self.An = 0
    """
Utility maximization problem
    x = [co, La, Ln, l, Aa, An, ca]
    """
    def solveUmax(self, Market):   #Produce A and B to maximize profits
        pA = Market.pA
        po = Market.po
        oriA = self.oriA
        oriL = self.oriL
        """Utility function"""
        def utility(x):   #Secondary model
            return -1 * (ao*x[0] + al*x[3] + 1/2*(aoo*x[0]*x[0] + aLl*x[3]*x[3] + aol*x[0]*x[3]))
        """Liquidity constraints"""
        def cons_liquidity(x):
            return (w - tw) * x[2] + r * x[5] - po * x[0] - (pA + ta) * x[6] - milk_meat
        """Hunger constraint"""
        def appetite(x):
            return Yield * Equip * x[1] + x[6] - appe
        """Relationship between land area and input labor force"""
        def labor_land(x):
            return x[4] - Equip * x[1]
        """Endowed element constraints"""
        def labor_cons(x):
            return oriL - x[1] - x[2] - x[3]
        def land_cons(x):
            return oriA - x[4] - x[5]
        """Sign constraint of each variable"""
        def co(x):
            return x[0]
        def La(x):
            return x[1]
        def Ln(x):
            return x[2]
        def l(x):
            return x[3]
        def Aa(x):
            return x[4]
        def An(x):
            return x[5]
        def ca(x):
            return x[6]
        
        cons = ({"type": "ineq", "fun": cons_liquidity}, {"type": "ineq", "fun": appetite}, {"type": "ineq", "fun": labor_land},
               {"type": "ineq", "fun": co}, {"type": "ineq", "fun": La}, {"type": "ineq", "fun": Ln}, {"type": "ineq", "fun": l},
               {"type": "ineq", "fun": Aa}, {"type": "ineq", "fun": An}, {"type": "ineq", "fun": ca}, {"type": "eq", "fun": labor_cons}, 
               {"type": "ineq", "fun": land_cons})
        
        #The initial value is the state in which all the elements are included in the production of A.
        x0 = [0, oriL, 0, 0, oriA, 0, 0]
        
        res = minimize(utility, x0, constraints=cons, method="SLSQP")   #Command to solve an optimization problem
        
        #What to do when the result is negative
        while (res.x[0] < 0) or (res.x[1] < 0) or (res.x[2] < 0) or (res.x[3] < 0) or (res.x[4] < 0) or (res.x[5] < 0):
            x0 = []
            for X in res.x:
                if X < 0:
                    X = 0
                x0.append(X)
            res = minimize(utility, x0, constraints=cons, method="SLSQP")
        
        
        """I will put away the calculated result"""
        self.LA = res.x[1]
        self.Ln = res.x[2]
        self.AA = res.x[4]
        self.An = res.x[5]
        self.co = res.x[0]
        self.ca = res.x[6]
        self.l = res.x[3]
        self.utility = - 1 * res.fun
        self.profit = (w - tw) * res.x[2] + r * res.x[5]
        self.qa = Yield * Equip * res.x[1]
        self.C = po * res.x[0] + (pA + ta) * res.x[6]
#End of definition of class Buyer

Next, the 4th line below "# Main Execution Department"

a = [Autarky(0)]

To

a = [Buyer(0)]

Please.

result

Executing the above code will return a list of the optimal solution for each selection variable at each time.

Now that we have obtained the simulation results, Let's compare "self-sufficient farmers", "net-seller" and "net-buyer" focusing on income and utility!

Comparison result of income and utility

image.png

In the column comparing the three types of farmers for "income" and "utility" in the table, the cell with the highest value in each period is painted in yellow. What we can see from this table is divided into "income" and "utility".

〇 Focus on income: net-seller is responsive to price changes

First, At the beginning, we can see that the net-seller's income is only about one sixth of the other two types of farmers. The initial price is a good reflection of reality, so what this result shows is "A single farmer who grows feed corn on 2ha of farmland will earn six times more if he quits farming." Actually, the farmer who owns about 2ha of farmland also makes cash crops, so the situation is a little better, but you can see how bad the farmer's situation is. Indeed, there are many abandoned farmers.

next, If you look at "income", you can see that the value of net-seller is rising. When the price increased 1.5 times, the income increased more than 10 times. In fact, against this background, net-sellers are steadily shaving off their "leisure" time and putting it into grain A cultivation. The price of agricultural products has risen, so you've done your job. Therefore, it was found that farmers who participate in the market as sellers of agricultural products are sensitive to the prices of agricultural products.

It's a natural result, but if a net-seller can be transformed into a "self-sufficient farmer" or a "net-buyer", would that farmer want to continue to be a "net-seller" that is vulnerable to price fluctuations? The fact that net-sellers are too sensitive to price changes may also be a member of farming.

〇 Focus on utility: Net-buyer has the highest utility

First, I will explain why self-sufficient farmers and net-buyer have almost the same utility (and income). This shows that it is very easy to be self-sufficient in grain A for yourself. Although not shown in the table, the farmland allocated to the cultivation of grain A by self-sufficient farmers was 0.0023ha = 0.23a = 23m ^ 2. The time spent was 0.12 hours = 7.2 minutes. Since we assumed feed corn here, it is possible that it will be produced on a larger scale than the corn that humans eat by using large-scale machines. Also, I don't know if the same situation will be reproduced in the situation where one person makes enough corn for self-sufficiency. However, in any case, it can be said that corn cultivation is fairly easy. The advantage of rice cultivation in Japan is that it can be grown in a short amount of time, so it is said that it is suitable for side jobs.

Next, if you compare the next net-seller in the middle with other farmers, you will notice a poor fact. The income of net-seller is three times that of other farmers, but the utility is almost the same. This suggests that the net-seller is overworked and has very little leisure time.

In any case, in order for the world's net-sellers to be as effective as other farmers, increase the initial price of grain A by a factor of 1.5. It turns out that we need to reduce our leisure time and triple our income.

at the end

So, this time I checked the code and result of the farm economy simulation. From the simulation results, you can see how pitiful the net-seller is (laughs).

As a future task, I would like to try to adjust the parameters a little more and realize the initial settings that are close to reality. Somehow, I feel that the wages are too high.

After that, I will consider whether it is possible to incorporate compound cultivation and subsidies that are provided in a fixed amount per planted area. After that, I will finally start making multi-agent simulations.

At present, the answer (code) is not visible, but when many farmers make a game that moves in the same field, the landing point = price and contract in the exchange between each farmer is matched. Prices and contracts should be determined by supply = demand, gain of A = gain of B, but what kind of code should be written to make such a move?

Well, for the time being, I'll try to make it like that. Thank you to everyone who has read this far!

Recommended Posts

Farmer economy simulation ② (net-seller, self-sufficient farmer, net-buyer utility maximization action) _
Farmer economy simulation ① (net-seller, self-sufficient farmer, net-buyer utility maximization action) _Explanation