Endogenous Agricultural Price Model With Heterogenous Agents

No preview image

1 collaborator

Default-person Per Hung Yap (Author)

Tags

(This model has yet to be categorized with any tags)
Visible to everyone | Changeable by everyone
Model was written in NetLogo 6.2.2 • Viewed 75 times • Downloaded 9 times • Run 0 times
Download the 'Endogenous Agricultural Price Model With Heterogenous Agents' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

extensions [ls matrix]

breed [buyers buyer]
breed [sellers seller]
breed [farmers farmer]
breed [speculators speculator]
breed [firms firm]
breed [deads dead]


Globals [b-price s-price bid_schedule ask_schedule last_price round_price number_of_buyers_left highest_bid lowest_ask number_of_sellers_left rounds periods last_price_list average_price
  annual_price_list
  normalised_price_list
  matrix_result
  price_prediction
  price_variance
  new_annual_price

  ;; dying and breeding stuff for firms
  Quantity_Penalty Delay_Penalty
  firms_quantity_ranking firms_quantity_ranking_B firms_point_ranking firms_point_ranking_B winner_list loser_list qualifier

  brain_price_pool    ;; for brain-price-only!!
  brain_harvest_pool
  brain_quantity_pool

  time_to_evolve_firms

  farmer_profit_ranking farmer_profit_ranking_B best_farmer_list worse_farmer_list

  time_to_evolve_farmers

  ;;autocorrelation stuff
  annual_prices ;;list
  autocorrelation
  kurtosis
  skewness
  MSE_autocorrelation
  MSE_kurtosis
  MSE_skewness

  harvest_learn_counter

]


buyers-own [bid stock_demanded Own_ID Money_Holdings Points slope constant risk_attitude
  own-brain-price

  total_sampled_capacity  ;;asked how much acres all farmers have
  total_sampled_used_capacity

  used_capacity_A   ;; for input in bidding brain
  used_capacity_B   ;; for input in harvest brain

  total_sampled_inventory_space
  total_sampled_inventory

  sampled_inventory  ;; for input for all brains

  brain_input_price

  n_of_contact
  proto_contact_list
  contact_list

  price_brain_output
  price_brain_output_denormalised

  stocks_gained
]

firms-own [bid stock_demanded Own_ID Money_Holdings Points slope constant risk_attitude
  own-brain-price

  total_sampled_capacity  ;;asked how much acres all farmers have
  total_sampled_used_capacity

  used_capacity_A   ;; for input in bidding brain
  used_capacity_B   ;; for input in harvest brain

  total_sampled_inventory_space
  total_sampled_inventory

  sampled_inventory  ;; for input for all brains

  brain_input_price

  n_of_contact
  proto_contact_list
  contact_list

  price_brain_output
  price_brain_output_denormalised

  stocks_gained
]


sellers-own [  ask_offer inventory_offered inventory inventory_space  Own_ID Money_Holdings Own-Yield VC VC_2 FC OpC Capacity risk_attitude
  own-brain-harvest
  own-brain-price
  own-brain-quantity

  unused_capacity
  used_capacity
  total_sampled_capacity  ;;asked how much acres all farmers have
  total_sampled_used_capacity


  used_capacity_A   ;; for input in bidding brain
  used_capacity_B   ;; for input in harvest brain

  total_sampled_inventory_space
  total_sampled_inventory

  sampled_inventory  ;; for input for all brains

  brain_input_harvest
  brain_input_price
  brain_input_quantity

  n_of_contact
  proto_contact_list
  contact_list

  harvest_brain_output
  harvest_brain_output_denormalised

  price_brain_output
  price_brain_output_denormalised

  quantity_brain_output

  profit_counter  ;; to check when to buy or sell capacity, yes it's badly named
  profit_calculator   ;; for fit function

  ori_offer
  revenue

  last_input_A
  last_input_B
  realised_price_A
  realised_price_B

]

farmers-own [ask_offer inventory_offered inventory inventory_space Own_ID Money_Holdings Own-Yield VC VC_2 FC OpC Capacity risk_attitude
  own-brain-harvest ; for farmers to predict harvest price
  own-brain-price
  own-brain-quantity

  unused_capacity
  used_capacity
  total_sampled_capacity  ;;asked how much acres all farmers have
  total_sampled_used_capacity


  used_capacity_A   ;; for input in bidding brain
  used_capacity_B   ;; for input in harvest brain

  total_sampled_inventory_space
  total_sampled_inventory

  sampled_inventory  ;; for input for all brains

  brain_input_harvest
  brain_input_price
  brain_input_quantity

  n_of_contact
  proto_contact_list
  contact_list

  harvest_brain_output
  harvest_brain_output_denormalised

  price_brain_output
  price_brain_output_denormalised

  quantity_brain_output

  profit_counter
  profit_calculator

  ori_offer
  revenue

  last_input_A
  last_input_B
  realised_price_A
  realised_price_B
]
speculators-own [bid stock_demanded ask_offer inventory Own_ID Money_Holdings risk_attitude]

patches-own[
  yield
  Variable_Cost
  Variable_Cost_2
  Ownership_Cost
  Opportunity_Cost
]

to Setup
  clear-all
  ls:close ls:models
  set brain_price_pool []
  set brain_harvest_pool []
  set brain_quantity_pool []
  setup-patch
  create-firms Number-of-Firms [
    set Own_ID 0
    set color blue
    setxy random-xcor random-ycor
    set risk_attitude random-normal 0 1
    ;if risk_attitude > 1 [ set risk_attitude 1]
    ;if risK_attitude < -1 [set risk_attitude -1]
    set bid 0 ;random bid-variation                    ; to be deleted and replaced  in go
    set stock_demanded 0 ;random demand-variation      ; to be deleted and replaced in go
    ;set Money_Holdings 500
    set stocks_gained 0

    setup-brain-price
    ls:assign own-brain-price input_data "[1 1 1 1 1]"            ;special for firms as they have 5 inputs, not 4
    ls:ask own-brain-price [setup]

    set brain_input_price []

    set total_sampled_used_capacity []
    set total_sampled_capacity []
    set used_capacity_A 0
    set used_capacity_B 0

    set total_sampled_inventory_space []
    set total_sampled_inventory []
    set sampled_inventory 0 ;; for brain input


    set contact_list []
    set proto_contact_list []
    set n_of_contact n_contact_for_firms

    set Points 0
    set slope Firms_Slope
    set constant Firms_Constant
  ]
  create-farmers Number-of-Farmers [
    set Own_ID 1
    set color red
    set Capacity round random-normal 175 50 ; sd from assmption
    setxy random-xcor random-ycor
    set risk_attitude random-normal 0 1              ;;; to be changed
    if risk_attitude > 1 [ set risk_attitude 1]
    if risK_attitude < -1 [set risk_attitude -1]
    set Own-Yield [yield] of patch-here
    set VC [Variable_Cost] of patch-here
;    set VC_2 [Variable_Cost_2] of patch-here
    set FC [Ownership_Cost] of patch-here
    set OpC [Opportunity_Cost] of patch-here

    setup-brain-harvest
    setup-brain-price
    setup-brain-quantity

    set brain_input_harvest []
    set brain_input_price []
    set brain_input_quantity []

    set inventory_space storage_multiplier * (Own-Yield * Capacity)
    set inventory 0

    set Money_Holdings money_to_start_with

    set used_capacity Capacity - random (Capacity )  ; supposed to be current period's used capacity, but we pretend that it's the last's for now
    set unused_capacity Capacity - round (used_capacity)
    if unused_capacity < 0 [
      set unused_capacity 0]
    set total_sampled_used_capacity []
    set total_sampled_capacity []
    set used_capacity_A 0
    set used_capacity_B 0


    set total_sampled_inventory_space []
    set total_sampled_inventory []
    set sampled_inventory 0 ;; for brain input


    set contact_list []
    set proto_contact_list []
    set n_of_contact n_contact

    set profit_counter 0
    set profit_calculator 0
    set revenue 0
  ]                                                    ; create a sort-of supply curve

  compile_used_capacity_B_and_sampled_inventory   ;; to create input for harvest_brain,

  create-speculators Number-of-Speculators [
    set Own_ID 2
    set color green
    setxy random-xcor random-ycor
    set bid 0
    set ask_offer 0
    set inventory 0
    set Money_Holdings money_to_start_with ;;??
  ]
  set average_price 0
  set last_price_list []
  set s-price []
  set bid_schedule []
  set ask_schedule []
  set last_price 5.83
  set number_of_buyers_left 0
  set number_of_sellers_left 0
  set rounds 12
  set periods 0

  set Quantity_Penalty Quantity_Penalty_For_Firms
  set Delay_Penalty Delay_Penalty_For_Firms

  set annual_price_list [5.69 4.82 4.87 5.61 5.52 5.83]   ;;used for input to harvest_brain
  set normalised_price_list []
  set new_annual_price 5.83
  set time_to_evolve_firms 0
  set time_to_evolve_farmers 0

  set annual_prices []
  set autocorrelation 0
  set kurtosis 0
  set skewness 0
  set harvest_learn_counter 2

  reset-ticks
end 

to setup-patch                         ;; setup 'endowments' farmers get from the land they landed on
  ; to create yield distribution
  let a_y precision (random-normal 47.7 13.9951) 1
  let b_y precision (random-normal 47.7 13.9951) 1
  let c_y precision (random-normal 47.7 13.9951) 1
  let d_y precision (random-normal 47.7 13.9951) 1

  ; to create Operating Cost distribution

  let a_OC precision (random-normal 114.89 37.53) 1
  let b_OC precision (random-normal 114.89 37.53) 1
  let c_OC precision (random-normal 114.89 37.53) 1
  let d_OC precision (random-normal 114.89 37.53) 1

  ; to create Ownership Cost distribution

  let a_FC precision (random-normal 63.10 20.2) 1
  let b_FC precision (random-normal 63.10 20.2) 1
  let c_FC precision (random-normal 63.10 20.2) 1
  let d_FC precision (random-normal 63.10 20.2) 1

  ; to create Opportunity Cost distribution for labour

  let a_LabourOC precision (random-normal 15.87 2.036) 1
  let b_LabourOC precision (random-normal 15.87 2.036) 1
  let c_LabourOC precision (random-normal 15.87 2.036) 1
  let d_LabourOC precision (random-normal 15.87 2.036) 1

  ; to create Opportunity Cost distribution for land

  let a_LandOC precision (random-normal 46.20 25.053) 1
  let b_LandOC precision (random-normal 46.20 25.053) 1
  let c_LandOC precision (random-normal 46.20 25.053) 1
  let d_LandOC precision (random-normal 46.20 25.053) 1

  ;to get final OC

  let a_OppCost a_LabourOC + a_LandOC
  let b_OppCost b_LabourOC + b_LandOC
  let c_OppCost c_LabourOC + c_LandOC
  let d_OppCost d_LabourOC + d_LandOC


  ask patches [
    if pxcor <= 0 and pycor <= 0[
      set yield precision (random-normal c_y 5) 1
      set Variable_Cost precision (random-normal c_OC 5) 1
      set Ownership_Cost precision (random-normal c_FC 5) 1
      set Opportunity_Cost precision (random-normal c_OppCost 5) 1
      set pcolor Yield
    ]
    if pxcor < 0 and pycor >= 0[
      set yield precision (random-normal a_y 5) 1
      set Variable_Cost precision (random-normal a_OC 5) 1
      set Ownership_Cost precision (random-normal a_FC 5) 1
      set Opportunity_Cost precision (random-normal a_OppCost 5) 1
      set pcolor Yield
    ]
    if pxcor > 0 and pycor <= 0[
      set yield precision (random-normal d_y 5) 1
      set Variable_Cost precision (random-normal d_OC 5) 1
      set Ownership_Cost precision (random-normal d_FC 5) 1
      set Opportunity_Cost precision (random-normal d_OppCost 5) 1
      set pcolor Yield
    ]
    if pxcor >= 0 and pycor > 0[
      set yield precision (random-normal b_y 5) 1
      set Variable_Cost precision (random-normal b_OC 5) 1
      set Ownership_Cost precision (random-normal b_FC 5) 1
      set Opportunity_Cost precision (random-normal b_OppCost 5) 1
      set pcolor Yield
    ]
  ]
end 

;;;;;; To go ;;;;;;;;;;;

to go
  if rounds = 12 [;print "this is the part where you do harvest and sets bid"
    agents_learn
    CapA_to_CapB
    harvest_plant ;;; Harvest_here, this is when you increase the inventory
    gather_prediction_information

    farmers_plant ;; set the total capcity used
    gather_price_information   ;info gathering for prices,

    put_input_into_price_brain
    decide_ask   ;    decides asking price for sellers (farmers)
    put_input_into_quantity_brain      ;    decides asking quantity for sellers (farmers)
    decide_quantity_offered

    decide_bid              ; decides bidding price for buyers
    get_firm_demand         ; decides bidding quantity for buyers
  ]
  storage_cost
  create_buyers
  create_sellers
  create_bid_schedule
  create_ask_schedule
;;  print last first ask_schedule - when want to know the lowest asking price
;;  print last first bid_schedule - when want to know the highest bid price
;;  print last first bid_schedule
;; print first first bid_schedule  - when want to know who is the higest bidder
  if any? buyers with [stock_demanded > 0] and any? sellers with [inventory_offered > 0] [ ; need to readjust based on rounds in the future
    auction_round
    readjustment
  ]
  plot_stuff
  return_to_original_breed
  round_accounting             ; let this be where all the killing and breeding begins  ;; this is where we wil rank the firms based on quantity gained, and how fast they gained it
  tick
end 

;________________________________________________________________________________;
;; Go components ;;
;________________________________________________________________________________;

to create_sellers
  ask farmers [
    set breed sellers]
;  ask speculators [           This is to let speculators become sellers under certain condition, yet to be introduced
;    if .... [
;      set breed sellers]
end 

to create_buyers
  ask firms [
    set breed buyers]
;  ask speculators [           This is to let speculators become buyers under certain condition, yet to be introduced
;    if .... [
;      set breed buyers]
end 

to create_bid_schedule
  let d []
  set d sort ([who] of buyers)
  set bid_schedule []
  foreach d [ ID ->
    let temp2 []
    set temp2 lput ID temp2
    set temp2 lput ([bid] of buyer ID) temp2
    set bid_schedule lput temp2 bid_schedule]
  set bid_schedule sort-by [ [x y] ->  last x > last y] bid_schedule ; ordering the schedule from the highest bidder to the lowest bidder
;  print length bid_schedule
;  print bid_schedule
end 

to create_ask_schedule
  let d []
  set d sort ([who] of sellers)
  set ask_schedule []
  foreach d [ ID ->
    let temp2 []
    set temp2 lput ID temp2
    set temp2 lput ([ask_offer] of seller ID) temp2
    set ask_schedule lput temp2 ask_schedule]
  set ask_schedule sort-by [ [x y] ->  last x < last y] ask_schedule ; ordering the schedule from the lowest ask offer to the highest
;    print ask_schedule
end 

to auction_round        ;is independent of quantity - this deals with price only,
  if empty? bid_schedule [stop print "Help1"] ; highly unlikely
  while [(last first bid_schedule) >= (last first ask_schedule)] [
    ask buyer (first first bid_schedule) [   ; the highest bidder has the right to buy first, she will of course buy from the lowest asker
      let bid_price []
      let Q_bid []
      let ask_price []
      let Q_ask []
      set bid_price bid
      set Q_bid stock_demanded
      ask seller (first first ask_schedule) [ ; gathering info from the seller we face

        set ask_price ask_offer
        set Q_ask inventory_offered
      ]

      ;;;; Auction starts for real ;;;;;;;;

      ifelse stock_demanded = 0 [  ; if buyer already exit the market, still has nothing to buy, she will leave the market again. This is admitedly a convoluted way of eliminating bidders who exit from previous rounds
        set bid_schedule remove-item 0 bid_schedule
      ]
      [;;;;;;; if bidder really has something to buy
      ifelse Q_bid <= Q_ask [ ; when quantity needed is more than quantity offered by seller
        set stocks_gained stocks_gained + Q_bid
        set stock_demanded stock_demanded - Q_bid
       ; set Money_Holdings Money_Holdings - ((bid_price + ask_price) / 2) * Q_bid ; buyers have to pay, which takes away her money holdings
        ask seller (first first ask_schedule) [
          set Money_Holdings Money_Holdings + ((bid_price + ask_price) / 2) * Q_bid ; sellers got paid, it's money holdings are increased
          set profit_calculator profit_calculator + ((bid_price + ask_price) / 2) * Q_bid
          set revenue revenue + ((bid_price + ask_price) / 2) * Q_bid
          set inventory inventory_offered - Q_bid
          set inventory_offered inventory_offered - Q_bid
          if inventory_offered = 0 [set ask_schedule remove-item 0 ask_schedule]   ; sellers only exit when they run out of inventory
        ]
        set bid_schedule remove-item 0 bid_schedule                        ; if bid is fulfilled, then they exit the auction
        set last_price ((bid_price + ask_price) / 2)
        ]
        ;;;;;;;;  when initial bid cannot be fulfilled by initial ask. This is the case where  Q_bid > Q_ask
        [
        ifelse Q_ask = 0 [                                     ; eliminate sellers that already have nothing to sell
          set ask_schedule remove-item 0 ask_schedule]
        [
        set stocks_gained stocks_gained + Q_ask
        set stock_demanded stock_demanded - Q_ask
        ;set Money_Holdings Money_Holdings - ((bid_price + ask_price) / 2) * Q_ask
        ask seller (first first ask_schedule) [
          set Money_Holdings Money_Holdings + ((bid_price + ask_price) / 2) * Q_ask
          set profit_calculator profit_calculator + ((bid_price + ask_price) / 2) * Q_ask
          set revenue revenue + ((bid_price + ask_price) / 2) * Q_ask
          set inventory inventory - inventory_offered
          set inventory_offered 0
        ]
        set ask_schedule remove-item 0 ask_schedule             ; eliminate sellers that already have nothing to sell, won't eliminate buyer yet as full ordernot yet fufilled
        set last_price ((bid_price + ask_price) / 2)            ; last price is like mid-point price here
      ]]  ; in usual times, this just makes sure buyers gets their orders fulfilled. If askers already left, this just eliminates them from the ask schedule until bidder can deal with asker with something to sell
  ]]      ; after all current demand and supply orders are filled , which would result in the end of this procedure, and move on to 'readjustment'
    if empty? bid_schedule [stop print "help2"]         ; this feels like it's going to be a problem in the future
    if empty? ask_schedule [stop print "help3"]]

  ask sellers [
    ifelse harvest_learn_counter = 1
    [
      set realised_price_B last_price
      ] [
        set realised_price_A last_price]
  ]
end 

to readjustment   ; To be replaced with something more complicated
  foreach (bid_schedule) [Buyer_ID ->
    ask buyer first Buyer_ID[                            ; change the bid, and remove them from the list so a new list can be generated in the future
      if Own_ID = 0 [
        let demand_fulfilled ( Constant + Slope * bid ) * Quantity_Multiplier - stock_demanded

        set bid bid + random-float U_readjustment_rate

        let i ( Constant + Slope * bid ) * Quantity_Multiplier          ;;may want to make this part exclusely for firms only
        set stock_demanded i - demand_fulfilled           ; if previous demand already fulfilled it, why bother demand more?
        ifelse stock_demanded <= 0 [
          set stock_demanded 0
        ][
          set Points Points - Delay_Penalty]      ;; will deduct points only if you still have some demand
      ]

      ;; if Own_ID speculator

    ]
    set bid_schedule remove-item 0 bid_schedule
  ]

  foreach (ask_schedule) [Seller_ID ->
    ask seller first Seller_ID [
      if Own_ID = 1 [
        set ask_offer ask_offer - random-float D_readjustment_rate
        if ask_offer < ( VC / Own-Yield ) [
          set ask_offer (VC / Own-Yield)]

        let stocks_sold ori_offer - inventory_offered
        ;; if already sell certain amount, already have some revenue, so
        let Totcos (used_capacity *  VC + ( used_capacity ) * VC_2 + FC * Capacity) - revenue
        let break_even_quantity ( TotCos / ask_offer )
        let excess_inventory inventory - break_even_quantity   ;if stocks sold is 0, nothing changes, if not, makes account of original
        ifelse break_even_quantity <= inventory [
          set inventory_offered quantity_brain_output * excess_inventory + break_even_quantity
          set inventory_offered inventory_offered

          if inventory_offered < 0 [
            set inventory_offered 0]
        ][
           set inventory_offered inventory
         ]
      ]

      ; if Own_ID = speculator....
    ]
    set ask_schedule remove-item 0 ask_schedule
  ]
end 

to plot_stuff
  set number_of_buyers_left count buyers with [stock_demanded > 0]
  set number_of_sellers_left count sellers with [inventory > 0]
  if number_of_buyers_left > 0 [
    set highest_bid max [bid] of buyers with [stock_demanded > 0]]
  if number_of_sellers_left > 0 [
    set lowest_ask min [ask_offer] of sellers with [inventory > 0]]
end 

to return_to_original_breed
  ask turtles [
    if Own_ID = 0 [
      set breed firms]
    if Own_ID = 1 [
      set breed farmers]
    if Own_ID = 2 [
      set breed speculators]
  ]
end 

to  round_accounting                   ;to be changed to include back-propogation of ANN and readjustment of policy
  ifelse rounds < 12 [
    set last_price_list lput last_price last_price_list
    set rounds rounds + 1

    if rounds = 12 [     ;; so the entire time rounds is supposed to be 12, it is technically 11 until the above operation.
          ;;; fixed cost and opportunity cost settled
      settle_fixed_and_opportunity_cost
      rank_firms_by_fit
      rank_farmers_by_fit
      ;rank farmers by fit. or just force them to evolve. Kill first, and then give birth. After that, clear the profit calculator
   ]
  ]
   [ ; at round 13 - when it transitioned from 11 to 12, there's no 'adjustment' to new period yet
;    print "are we there yet"
;    print last_price_list
    set average_price (sum last_price_list) / 12
    set new_annual_price average_price  ;; for the price_stuff in new period
    set annual_prices lput average_price annual_prices
    calculate_autocorrelation
    calculate_kurtosis
    calculate_skewness
    ;reset
    set periods periods + 1
    set rounds 1  ;from 13 to 0
    set last_price_list []
    set last_price_list lput last_price last_price_list  ; this round has it's own price


  ]
end 

to storage_cost
  ask farmers  [
    if inventory > 0 [
      set Money_Holdings Money_Holdings - 0.16 * Inventory
      set profit_calculator profit_calculator - 0.16 * Inventory
    ]
  ]
  ;ask speculators...
end 

;;______________________________________________________________________
;;;;;;;;;;;;;;;;;;; new period stuff ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;_____________________________________________________________________

to CapA_to_CapB
    ask farmers [
      set used_capacity_B used_capacity_A]
    ask firms [
      set used_capacity_B used_capacity_A]
end 

;________________________________________________________________
;;;;;;;; brain stuff ;;;;;;;;
;_______________________________________________________________
;;; for farmers to predict harvest price

to setup-brain-harvest
  set own-brain-harvest make-brain-harvest
  (ls:assign own-brain-harvest learning-rate 0.5)  ;; might want to make this random, and weigtage too!
  ls:ask own-brain-harvest [setup]
end 

to-report make-brain-harvest
  let b 0
  ifelse empty? brain_harvest_pool [
    (ls:create-models 1 "neural network for regression 2.nlogo" [id -> ls:hide id set b id])
  ][
    set b first brain_harvest_pool
    set brain_harvest_pool but-first brain_harvest_pool
  ]
  report b
end 

to setup-brain-price
  set own-brain-price make-brain-price
  (ls:assign own-brain-price learning-rate 0.5)  ;;might want to make this random
  ;; make weightage assigned random too I guess
  ls:ask own-brain-price [setup]
end 

to-report make-brain-price
  let b 0
  ifelse empty? brain_price_pool [
    (ls:create-models 1 "neural network for regression 2.nlogo" [id -> ls:hide id set b id])
  ][
    set b first brain_price_pool
    set brain_price_pool but-first brain_price_pool
  ]
  report b
end 

to setup-brain-quantity
  set own-brain-quantity make-brain-quantity
  (ls:assign own-brain-quantity learning-rate 0.5)  ;; might want to make this random, and weightage should also be random
  ls:ask own-brain-quantity [setup]
end 

to-report make-brain-quantity
  let b 0
  ifelse empty? brain_quantity_pool [
    (ls:create-models 1 "neural network for regression ranged 2.nlogo" [id -> ls:hide id set b id])
  ][
    set b first brain_quantity_pool
    set brain_quantity_pool but-first brain_quantity_pool
  ]
  report b
end 

;;_____________________________________________________________________
;;;;;;; harvest brain input and (some) output stuff;;;;;;;;;;;;;
;;_____________________________________________________________________

to compile_used_capacity_B_and_sampled_inventory ;;supposed to be in setup. First of all instead of used_capacity_B, it will be A, and will be changed in round 12
  let d []
  set d sort ([who] of farmers)
  ask farmers [
    foreach sort d [ID ->
      let l []
      set l lput [distance farmer ID] of self l
      set l lput ID l
      set proto_contact_list lput l proto_contact_list
    ]

    set proto_contact_list sort-by [[x y] -> first x < first y] proto_contact_list

    repeat n_of_contact [
      set contact_list lput last (first proto_contact_list) contact_list
      set proto_contact_list remove-item 0 proto_contact_list
    ]
    ;print n_of_contact
    foreach contact_list [ID ->
      set total_sampled_used_capacity lput [used_capacity] of farmer ID total_sampled_used_capacity
      set total_sampled_capacity lput [Capacity] of farmer ID total_sampled_capacity
      ;print total_sampled_capacity
    ]
    let A 0
    set A sum total_sampled_used_capacity
    let B 0
    set B sum total_sampled_capacity
    set used_capacity_A (A / B)
;    print used_capacity_A   ;;checks out
  ]
  ask firms [
    foreach sort d [ID ->
      let l []
      set l lput [distance farmer ID] of self l
      set l lput ID l
      set proto_contact_list lput l proto_contact_list
    ]
    set proto_contact_list sort-by [[x y] -> first x < first y] proto_contact_list

    repeat n_of_contact [
      set contact_list lput last (first proto_contact_list) contact_list
      set proto_contact_list remove-item 0 proto_contact_list
    ]

    foreach contact_list [ID ->
      set total_sampled_used_capacity lput [used_capacity] of farmer ID total_sampled_used_capacity
      set total_sampled_capacity lput [Capacity] of farmer ID total_sampled_capacity
    ]
    let A 0
    set A sum total_sampled_used_capacity
    let B 0
    set B sum total_sampled_capacity
    set used_capacity_A (A / B)
;    print used_capacity_A   ;;checks out
  ]
end 

to gather_prediction_information
  annual_price_info
  get_inventory_info ;; ask farmer to gather information from surroundings
  get_harvest_info   ;;[past price data/ predicted price data (up to us), slope curve, used_capacity_B, neighbour inventories]
  put_input_into_harvest_brain   ;; get output from harvest brain
end 

to get_inventory_info
  let d []
  set d sort ([who] of farmers)
  ask farmers [
    set proto_contact_list []      ; 'refresh' the list for space in case update is needed
    set contact_list []
    set total_sampled_inventory []
    set total_sampled_inventory_space []
    set brain_input_harvest []

    foreach sort d [ID ->
      let l []
      set l lput [distance farmer ID] of self l
      set l lput ID l
      set proto_contact_list lput l proto_contact_list
    ]
    set proto_contact_list sort-by [[x y] -> first x < first y] proto_contact_list
    repeat n_of_contact [
      set contact_list lput last (first proto_contact_list) contact_list
      set proto_contact_list remove-item 0 proto_contact_list
    ]

    foreach contact_list [ID ->
      set total_sampled_inventory lput [inventory] of farmer ID total_sampled_inventory
      set total_sampled_inventory_space lput [inventory_space] of farmer ID total_sampled_inventory_space
    ]

    let C 0
    set C sum total_sampled_inventory
    let DE 0
    set DE sum total_sampled_inventory_space

    set sampled_inventory (C / DE)    ;; for harvest input
  ]
end 

to get_harvest_info
  ask farmers [
    let Pr 0
    set Pr price_normalisation item 0 matrix_result ; forecasted price, if want latest price instead, it's set pr item 5 annual_price_list (will give unnormalised data!)
    set brain_input_harvest lput Pr brain_input_harvest
    let Sl 0
    set Sl ((item 2 matrix_result) + 5) / (10) ;gets the slope of the OLS curve
    set brain_input_harvest lput Sl brain_input_harvest
    let LYPD 0
    set LYPD used_capacity_B
    set brain_input_harvest lput LYPD brain_input_harvest
    set brain_input_harvest lput sampled_inventory brain_input_harvest
;    print brain_input_harvest
    ;; [pr, sl, LYPD, Sampled_inventory]

    ifelse harvest_learn_counter = 1 [
      set last_input_A brain_input_harvest
  ][
      set last_input_B brain_input_harvest
    ]
  ]
end 

to put_input_into_harvest_brain
  ask farmers [
    let i word brain_input_harvest ""
    (ls:assign own-brain-harvest input_data i)
    ls:ask own-brain-harvest [train]
    set harvest_brain_output [end-value] ls:of own-brain-harvest
    set harvest_brain_output_denormalised price_denormalisation ([end-value] ls:of own-brain-harvest)
;    print harvest_brain_output_denormalised
  ]
end 

to agents_learn  ;; will need to get speculators involved too
    ifelse harvest_learn_counter = 1 [
      set harvest_learn_counter harvest_learn_counter + 1
  ][ set harvest_learn_counter 1
    ]
    ask farmers [
      ;;; need to edit this part
    if periods > 2 [
      ifelse harvest_learn_counter = 1 [
        let i word last_input_A ""
        (ls:assign own-brain-harvest input_data i)
        ls:ask own-brain-harvest [train]
        (ls:assign own-brain-harvest target_value (price_normalisation realised_price_A))
          ls:ask own-brain-harvest [learn]
        ][
         let i word last_input_B ""
        (ls:assign own-brain-harvest input_data i)
        ls:ask own-brain-harvest [train]
        (ls:assign own-brain-harvest target_value (price_normalisation realised_price_B))
          ls:ask own-brain-harvest [learn]
          ]
    ]

      (ls:assign own-brain-price target_value (price_normalisation last_price))
      ls:ask own-brain-price [learn]
    ]
    ask firms [
      (ls:assign own-brain-price target_value (price_normalisation last_price))
      ls:ask own-brain-price [learn]
    ]
end 

;_________________________________________________________
;;;;;; to stock up the inventory before bidding
;__________________________________________________________

to harvest_plant
  ask farmers [
    set inventory inventory + Own-Yield * used_capacity
    if inventory > inventory_space [
      set inventory inventory_space]
  ]
end 


;;;; ________________________________________________
;;;;;;;;;;;;; for prices ;;;;;;;;;;;;;;;;;
;____________________________________________________

to annual_price_info
  update_list
  transformation
  give_matrix_result
  get_variance
end 

to update_list
  set annual_price_list remove-item 0 annual_price_list
  set annual_price_list lput new_annual_price annual_price_list   ;;set new_annual_price list everytime a new average end price is acheived for the period!!!
end 

to transformation
  set normalised_price_list map [x ->  (x - 3.78) / (12.99 - 3.78) ] annual_price_list
  set normalised_price_list map [x -> precision x 2] normalised_price_list
end 

to give_matrix_result
  set matrix_result matrix:forecast-linear-growth annual_price_list
  set matrix_result map [x -> precision x 2] matrix_result
end 

to get_variance
  set price_variance variance annual_price_list
  set price_variance precision price_variance 2
end 

to-report price_normalisation [input]
  let p 0
  set p (input - 3.78) / (12.99 - 3.78)
  report p
end 

to-report price_denormalisation [input]
  let p 0
  set p input * (12.99 - 3.78) + 3.78
  report p
end 

;;____________________________________________________________________
;;;;;;;; To plant or not to plant ::::::::::::::::::
;;___________________________________________________________________

to farmers_plant
  ask farmers [
    if (harvest_brain_output_denormalised * Own-Yield - VC) > 0 [
      ifelse risk_attitude <= 0 [
        set used_capacity Capacity
      ]
      [
        let q 0
        ifelse (VC_2 + risk_attitude * price_variance) = 0 [   ;; rare occurance, but better be careful
          set used_capacity Capacity]
        [
        set q ( harvest_brain_output_denormalised * Own-Yield - VC ) / ( VC_2 + risk_attitude * price_variance)  ;;; get optimal capacity usage

        ifelse q >= Capacity [
          set used_capacity Capacity]
        [set used_capacity q]
        ]
      ]
    ]
    set used_capacity round used_capacity

    if used_capacity > 0 and (inventory_space - inventory) < Own-Yield * used_capacity [    ;;when there is too much being planted, we will reduce the acre used to approproate amount
      set used_capacity (inventory_space - inventory) / Own-Yield
      set used_capacity round used_capacity
    ]

    ;; unused_capacity rule, important for opportunity cost or when farmers decide to forgo planting wheat in this period
    ifelse used_capacity = Capacity [
      set unused_capacity 0
    ]
    [set unused_capacity Capacity - used_capacity]

    if unused_capacity < 0 [
      set unused_capacity 0
    ]

  ;; decide on cost here
    set Money_Holdings Money_Holdings - ( VC * used_capacity)
    set profit_calculator profit_calculator - ( VC * used_capacity)
  ]
end 

;__________________________________________________________________
;;;;;;;;;;;;;; to gather information to decide on bid;;;;;;;;;;;;;;
;_________________________________________________________________
;; ask farmers, speculators, and firms

;; get final predicted price? Or last final price?
; current year planting decision
; last period's planting decision
; current stock

to gather_price_information
  ask farmers [                                ;;get forecasted price
    set brain_input_price []                   ;;;; Very important!!!
    let Pr 0
    set Pr harvest_brain_output
    set brain_input_price lput Pr brain_input_price
  ]

  ask firms [
    set brain_input_price []
    let Pr price_normalisation item 0 matrix_result
    set brain_input_price lput Pr brain_input_price


    let Sl ((item 2 matrix_result) + 5) / ( 10 ) ;gets the slope of the OLS curve
    set brain_input_price lput Sl brain_input_price
  ]

  compile_used_capacity_A

  ask farmers [                             ;;retrieve used_capacity_B
    set brain_input_price lput used_capacity_B brain_input_price
  ]

  ask firms [
    set brain_input_price lput used_capacity_B brain_input_price
  ]

  get_inventory_info_for_price
;  ask farmers [print brain_input_price]
;  ask firms [    print brain_input_price  ]; checks out
end 

to compile_used_capacity_A
  let d []
  set d sort ([who] of farmers)
  ask farmers [
    set proto_contact_list []      ; 'refresh' the list for space in case update is needed
    set contact_list []
    set total_sampled_used_capacity []
    set total_sampled_capacity []

    foreach sort d [ID ->
      let l []
      set l lput [distance farmer ID] of self l
      set l lput ID l
      set proto_contact_list lput l proto_contact_list
    ]
    set proto_contact_list sort-by [[x y] -> first x < first y] proto_contact_list

    repeat n_of_contact [
      set contact_list lput last (first proto_contact_list) contact_list
      set proto_contact_list remove-item 0 proto_contact_list
    ]

    foreach contact_list [ID ->
      set total_sampled_used_capacity lput [used_capacity] of farmer ID total_sampled_used_capacity
      set total_sampled_capacity lput [Capacity] of farmer ID total_sampled_capacity
    ]
    let A 0
    set A sum total_sampled_used_capacity
    let B 0
    set B sum total_sampled_capacity
    ifelse B > 0 [
      set used_capacity_A (A / B)] [set used_capacity_A 0]
    set brain_input_price lput used_capacity_A brain_input_price
  ]

  ask firms [
    set proto_contact_list []      ; 'refresh' the list for space in case update is needed
    set contact_list []
    set total_sampled_used_capacity []
    set total_sampled_capacity []
    foreach sort d [ID ->
      let l []
      set l lput [distance farmer ID] of self l
      set l lput ID l
      set proto_contact_list lput l proto_contact_list
    ]
    set proto_contact_list sort-by [[x y] -> first x < first y] proto_contact_list

    repeat n_of_contact [
      set contact_list lput last (first proto_contact_list) contact_list
      set proto_contact_list remove-item 0 proto_contact_list
    ]

    foreach contact_list [ID ->
      set total_sampled_used_capacity lput [used_capacity] of farmer ID total_sampled_used_capacity
      set total_sampled_capacity lput [Capacity] of farmer ID total_sampled_capacity
    ]
    let A 0
    set A sum total_sampled_used_capacity
    let B 0
    set B sum total_sampled_capacity
    ifelse B > 0 [
      set used_capacity_A (A / B)] [set used_capacity_A 0]
    set brain_input_price lput used_capacity_A brain_input_price
  ]
end 

to get_inventory_info_for_price
  let d []
  set d sort ([who] of farmers)
  ask farmers [
    set proto_contact_list []      ; 'refresh' the list for space in case update is needed
    set contact_list []
    set total_sampled_inventory []
    set total_sampled_inventory_space []

    foreach sort d [ID ->
      let l []
      set l lput [distance farmer ID] of self l
      set l lput ID l
      set proto_contact_list lput l proto_contact_list
    ]
    set proto_contact_list sort-by [[x y] -> first x < first y] proto_contact_list
    repeat n_of_contact [
      set contact_list lput last (first proto_contact_list) contact_list
      set proto_contact_list remove-item 0 proto_contact_list
    ]

    foreach contact_list [ID ->
      set total_sampled_inventory lput [inventory] of farmer ID total_sampled_inventory
      set total_sampled_inventory_space lput [inventory_space] of farmer ID total_sampled_inventory_space
    ]

    let C 0
    set C sum total_sampled_inventory
    let DE 0
    set DE sum total_sampled_inventory_space

    ifelse DE > 0 [

      set sampled_inventory (C / DE)]    ;; for price input, wiil override the previous one for harvest]
      [set sampled_inventory 0]
    set brain_input_price lput sampled_inventory brain_input_price
  ]
  ask firms [
    set proto_contact_list []      ; 'refresh' the list for space in case update is needed
    set contact_list []
    set total_sampled_inventory []
    set total_sampled_inventory_space []

    foreach sort d [ID ->
      let l []
      set l lput [distance farmer ID] of self l
      set l lput ID l
      set proto_contact_list lput l proto_contact_list
    ]
    set proto_contact_list sort-by [[x y] -> first x < first y] proto_contact_list
    repeat n_of_contact [
      set contact_list lput last (first proto_contact_list) contact_list
      set proto_contact_list remove-item 0 proto_contact_list
    ]

    foreach contact_list [ID ->
      set total_sampled_inventory lput [inventory] of farmer ID total_sampled_inventory
      set total_sampled_inventory_space lput [inventory_space] of farmer ID total_sampled_inventory_space
    ]

    let C 0
    set C sum total_sampled_inventory
    let DE 0
    set DE sum total_sampled_inventory_space
    ifelse DE > 0 [
      set sampled_inventory (C / DE)]    ;; for price input, wiil override the previous one for harvest
        [set sampled_inventory 0]
    set brain_input_price lput sampled_inventory brain_input_price
  ]
end 

;________________________________________________________________________________________
;;;;;;;;;; deciding on bid and ask (quantity and price) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;________________________________________________________________________________________

to put_input_into_price_brain
  ask farmers [
    let i word brain_input_price ""
    (ls:assign own-brain-price input_data i)
    ls:ask own-brain-price [train]
    set price_brain_output [end-value] ls:of own-brain-price           ;price -brain-ouput?
    set price_brain_output_denormalised price_denormalisation ([end-value] ls:of own-brain-price)
;    print price_brain_output_denormalised
  ]

  ask firms [
    let i word brain_input_price ""
    (ls:assign own-brain-price input_data i)
    ls:ask own-brain-price [train]
    set price_brain_output [end-value] ls:of own-brain-price           ;price -brain-ouput?
    set price_brain_output_denormalised price_denormalisation ([end-value] ls:of own-brain-price)
;    print price_brain_output_denormalised
  ]
end 

to decide_ask
  ask farmers [
    set ask_offer price_brain_output_denormalised  ;;maybe add something to do with risk-attitude here?
    if ask_offer < ( VC / Own-Yield) [
      set ask_offer ( VC / Own-Yield) ]
  ]
end 

to put_input_into_quantity_brain
  ask farmers [
    let i word brain_input_price ""       ;; because the inputs are essentially the same
    (ls:assign own-brain-quantity input_data i)
    ls:ask own-brain-quantity [train]
    set quantity_brain_output [end-value] ls:of own-brain-quantity          ;price -brain-ouput?
;    print quantity_brain_output
  ]
end 

to decide_quantity_offered
  ask farmers [
    let TotCos used_capacity *  VC + ( used_capacity ) * VC_2 + FC * Capacity
    let break_even_quantity ( TotCos / ask_offer )
    let excess_inventory inventory - break_even_quantity
    ifelse break_even_quantity <= inventory [
      set inventory_offered quantity_brain_output * excess_inventory + break_even_quantity
  ][
      set inventory_offered inventory
    ]
    set ori_offer inventory_offered
  ]
end 

to decide_bid
  ask firms [
    set bid price_brain_output_denormalised  ;;maybe add something to do with risk-attitude here?
    if bid <= 0 [
      set bid 0.1]
   ; print bid
  ]
end 

to get_firm_demand
  ask firms [
    set stocks_gained 0      ;; reset the stocks_gained
    let i ( Constant + Slope * bid ) * Quantity_Multiplier
    set stock_demanded i
;    print stock_demanded
  ]
end 


;;;______________________________________________________________________________________________
;;;;;;;;; for dying and breeding stuff
;________________________________________________________________________________________________

to rank_firms_by_fit
  sort_firms_by_quantity
  get_firms_ranking
  give_points
  rank_points
  sort_firms_by_points
  get_winner
  get_loser
  ifelse time_to_evolve_firms = 2 [
    kill_loser
    birth_winner
    clear_points]
  [set time_to_evolve_firms time_to_evolve_firms + 1]
end 

to sort_firms_by_quantity
  let byrs []
  set byrs sort ([who] of firms)
  set firms_quantity_ranking []
  foreach byrs [ ID ->
    let i []
    set i lput [stocks_gained] of firm ID i
    set i lput ID i
    set firms_quantity_ranking lput i firms_quantity_ranking
  ]
  set firms_quantity_ranking sort-by [[x y] -> first x > first y] firms_quantity_ranking
  ;print firms_quantity_ranking
end 

to get_firms_ranking
  set firms_quantity_ranking_B []
  foreach firms_quantity_ranking [ ID ->
    let i 0
    set i (last ID)
    set firms_quantity_ranking_B lput i firms_quantity_ranking_B]
  ;print firms_quantity_ranking_B  ;[2 6 5 9 8 7 0 3 1 4]
end 

to give_points
  let ranking 0
  foreach firms_quantity_ranking_B [ ID ->
    ask firm ID [
      set points points - ranking * quantity_penalty
      set ranking ranking + 1
    ]
  ]
end 

to rank_points
  let ranking 0
  let b []
  set b sort ([who] of firms)
  set firms_point_ranking []
  foreach b [ ID ->
    let i []
    set i lput [points] of firm ID i
    set i lput ID i
    set firms_point_ranking lput i firms_point_ranking
  ]
  set firms_point_ranking sort-by [[x y] -> first x > first y] firms_point_ranking
;  print firms_point_ranking ;[[0 3] [-50 8] [-100 6] [-150 5] [-200 0] [-250 7] [-300 2] [-350 4] [-400 1] [-450 9]]
end 

to sort_firms_by_points
  set firms_point_ranking_B []
  foreach firms_point_ranking [ ID ->
    let i 0
    set i (last ID)
    set firms_point_ranking_B lput i firms_point_ranking_B]
;  print firms_point_ranking_B
end 

to get_winner
  set winner_list []
  set qualifier round (( 1 / 10 ) * Number-of-Firms)
  let positions 0
  repeat qualifier [
    set winner_list lput item positions firms_point_ranking_B winner_list
    set positions positions + 1
  ]
;  print winner_list
end 

to get_loser
  set loser_list []
  set qualifier round (( 1 / 10 ) * Number-of-Firms)
  let positions length firms_point_ranking_B - 1
  repeat qualifier [
    set loser_list lput item positions firms_point_ranking_B loser_list
    set positions positions - 1
  ]
;  print loser_list
end 

to kill_loser
  foreach loser_list [ID ->
    ask firm ID [
      set brain_price_pool fput own-brain-price brain_price_pool
      die
    ]
  ]
end 

to birth_winner
  let firm_ID winner_list
  foreach firm_ID [ID ->
    ask firm ID [
      ;print self
      ls:let child-weights map [ w -> random-normal w mut-rate ] [get-weights] ls:of own-brain-price
      ;show length [get-weights] ls:of own-brain-price
      let inherit-inputs [input_data] ls:of own-brain-price
      ;let inherit-learning [learning-rate] ls:of own-brain-price
      hatch 1 [
        ;print self
        setup-brain-price
        (ls:assign own-brain-price input_data inherit-inputs)
        ;let l random-normal inherit-learning mut-rate
        ;if l < 0.25 [set l 0.25]
        ;if l > 0.75 [set l 0.75]
        ;(ls:assign own-brain-price learning-rate l)
        ls:ask own-brain-price [setup]
        ls:ask own-brain-price [train]
        ls:ask own-brain-price [set-weights child-weights]
        set risk_attitude random-normal risk_attitude mut-rate
        if risk_attitude > 1 [ set risk_attitude 1]
        if risK_attitude < -1 [set risk_attitude -1]
        right random 361
        forward random 5
      ]
    ]
  ]
end 

to clear_points
  ask firms [
    set points 0
  ]
end 

;______________________________________________________________
;;;;; fixed_cost and opportunity_cost being accounted for
;_____________________________________________________________

to settle_fixed_and_opportunity_cost
  ask farmers [
    set Money_Holdings Money_Holdings - FC * Capacity
    set profit_calculator profit_calculator - FC * Capacity
    set Money_Holdings Money_Holdings + OpC * unused_capacity
    set profit_calculator profit_calculator + OpC * unused_capacity
  ]
end 

to buy_or_sell_capacity     ;; will not put profit calculator here as this is after profit calculator is used for fit function.
                             ;;May want to incorporate risk based on Money_Holdings use (more risky, more likely to buy more Capacity)
  ask farmers [
      if Money_Holdings < 0 and Capacity > 0 [
        let i ( -1 * Money_Holdings)
        let Quant_to_sell round ( i / 2700 ) ; 2,700 is the average price of an Acre of farmland

        if Quant_to_sell > Capacity [
          set Quant_to_sell Capacity]

        set Money_Holdings Money_Holdings + 2700 * Quant_to_sell
        set Capacity Capacity - Quant_to_sell
        ]

      if Money_Holdings > 0 [
        set profit_counter profit_counter + 1
        if profit_counter = 5 [
          let i ( Money_Holdings / 2 )
          let to_buy round ( i / 2700 )
          if to_buy > 1 [
            set Capacity Capacity + to_buy
            set Money_Holdings Money_Holdings - to_buy * 2700
            ]
          set profit_counter 0
        ]
      ]
    ]
end 

;;______________________________________________________________________________
;;; to let farmers evolve
;_________________________________________________________________________________

to rank_farmers_by_fit
  account_for_asset
  sort_farmers_by_profit
  rank_firms_by_profit
  get_best_farmer
  get_worse_farmer
  ifelse time_to_evolve_farmers = 2 [
    learn_from_best_farmer
    reset_profit_calculator
    buy_or_sell_capacity  ;; happens after we rank farmers and 'evolve them'
    kill_farmer  ;;if any have 0 capacity of course
    set time_to_evolve_farmers 0
  ][ set time_to_evolve_farmers time_to_evolve_farmers + 1 ]
end 

to account_for_asset
  ask farmers [
    set profit_calculator profit_calculator / (2700 * Capacity)  ;;took away money_holdings for the possibility that it could be negative. Been accounted for by profit_calculator
    ;print profit_calculator
  ]
end 

to sort_farmers_by_profit
  let farm []
  set farm sort ([who] of farmers)
  set farmer_profit_ranking []
  foreach farm [ID ->
    let i []
    set i lput [profit_calculator] of farmer ID i
    set i lput ID i
    set farmer_profit_ranking lput i farmer_profit_ranking
  ]
  set farmer_profit_ranking sort-by [[x y] -> first x > first y] farmer_profit_ranking
  ;print farmer_profit_ranking
end 

to rank_firms_by_profit
  set farmer_profit_ranking_B []
  foreach farmer_profit_ranking [ ID ->
    let i []
    set i (last ID)
    set farmer_profit_ranking_B lput i farmer_profit_ranking_B]
  ;print farmer_profit_ranking_B
end 

to get_best_farmer
  set best_farmer_list []
  set qualifier round (( 1 / 10) * Number-of-Farmers)
  let positions 0
  repeat qualifier [
    set best_farmer_list lput item positions farmer_profit_ranking_B best_farmer_list
    set positions positions + 1
  ]
  ;print best_farmer_list
end 

to get_worse_farmer
  set worse_farmer_list []
  set qualifier round (( 1 / 10 ) * Number-of-Farmers)
  let positions length farmer_profit_ranking_B - 1
  repeat qualifier [
    set worse_farmer_list lput item positions farmer_profit_ranking_B worse_farmer_list
    set positions positions - 1
  ]
  ;print worse_farmer_list
end 

to learn_from_best_farmer
  foreach worse_farmer_list [ID ->
    ;print ID
    ask farmer ID [
      let child-weights_H []
      let child-weights_P []
      let child-weights_Q []

      let inherit-inputs_H []
      let inherit-inputs_P []
      let inherit-inputs_Q []

      ask farmer one-of best_farmer_list [
        ;print self
        set child-weights_H map [w -> random-normal w mut-rate] [get-weights] ls:of own-brain-harvest
        set child-weights_P map [w -> random-normal w mut-rate] [get-weights] ls:of own-brain-price
        set child-weights_Q map [w -> random-normal w mut-rate] [get-weights] ls:of own-brain-quantity

        set inherit-inputs_H [input_data] ls:of own-brain-harvest
        set inherit-inputs_P [input_data] ls:of own-brain-price
        set inherit-inputs_Q [input_data] ls:of own-brain-quantity
      ]
    ;; for harvest
     ls:let child-weights_H_2 child-weights_H
     ls:let child-weights_P_2 child-weights_P
     ls:let child-weights_Q_2 child-weights_Q
     (ls:assign own-brain-harvest input_data inherit-inputs_H)
     ls:ask own-brain-harvest [setup]
     ls:ask own-brain-harvest [train]
     ls:ask own-brain-harvest [set-weights child-weights_H_2]

    ;; for brain
     (ls:assign own-brain-price input_data inherit-inputs_P)
     ls:ask own-brain-price [setup]
     ls:ask own-brain-price [train]
     ls:ask own-brain-price [set-weights child-weights_P_2]

    ;; for quantity
     (ls:assign own-brain-quantity input_data inherit-inputs_Q)
     ls:ask own-brain-quantity [setup]
     ls:ask own-brain-quantity [train]
     ls:ask own-brain-quantity [set-weights child-weights_Q_2]
    ]
  ]
end 

to reset_profit_calculator
  ask farmers [
    set profit_calculator 0
  ]
end 

to kill_farmer
  let i count (farmers with [Capacity = 0])
  ;print i
  ifelse i = Number-of-Farmers [   ;; that means everyone failed, no choice but to let best farmers repopulate instead
    let candidate sort ([who] of farmers)
    let kill_list candidate
    foreach best_farmer_list [ID ->
      set kill_list remove ID kill_list   ;; returns a kill_list without the best
    ]
    let n_to_kill length kill_list
    foreach kill_list [ ID ->
      ask farmer ID [
        make_farmer_die ;;tell farmers to suicide
      ]
    ]
    repeat n_to_kill [
      ask farmer one-of best_farmer_list [
        make_farmer_repopulate
      ]
    ]
  ][
    ;;; to identify if this is the case where some of the winners have capacity (0), or none of them do  (1)
    let all_best_farmers_no_capacity 0
    let back_up_list best_farmer_list
    foreach best_farmer_list [ ID ->
      ask farmer ID [
        if Capacity <= 0 [
          set best_farmer_list remove ID best_farmer_list
        ]
      ]
      ]
    if empty? best_farmer_list [
      set best_farmer_list back_up_list
      set all_best_farmers_no_capacity 1   ;meaning yes
    ]

    ;;two distinct areas now whether all_best_farmers_no_capacity 0 or 1

    ifelse all_best_farmers_no_capacity = 0 [
      ;; find out who has 0 capacity first
      let those_without_capacity sort ([who] of farmers)
      ;print those_without_capacity
      foreach those_without_capacity [ID ->                            ;;something is wrong here
        ask farmer ID [
          if Capacity > 0 [
            set those_without_capacity remove ID those_without_capacity]
        ]
      ]  ;; should return those_without_capacity with a list of people to be eliminated
      ;print those_without_capacity

      let n_without_capacity length those_without_capacity

      foreach those_without_capacity [ID ->
       ask farmer ID [
         make_farmer_die
        ]
      ]
      repeat n_without_capacity [
        ask farmer one-of best_farmer_list [
          make_farmer_repopulate
        ]
      ]
     ;; kill all those with 0 capacity
     ;; repopulate with what is left of winner_list
    ][  ;; this is when all best farmers themselves have no capacity, which shouldn't make any sense, but just in case  ;;do what we did with no Capacity for everyone
      let candidate sort ([who] of farmers)
      let kill_list candidate
      foreach best_farmer_list [ID ->
        set kill_list remove ID kill_list   ;; returns a kill_list without the best
      ]
      foreach kill_list [ID ->          ;; if have Capacity, won't be killed
        ask farmer ID [
          if Capacity > 0 [
            set kill_list remove ID kill_list]
        ]
      ]

      let n_to_kill length kill_list
      foreach kill_list [ ID ->
        ask farmer ID [
          make_farmer_die ;;tell farmers to suicide
        ]
      ]
      repeat n_to_kill [
        ask farmer one-of best_farmer_list [
          make_farmer_repopulate
        ]
      ]
    ]
  ]
end 

to make_farmer_die
  set brain_harvest_pool fput own-brain-harvest brain_harvest_pool
  set brain_price_pool fput own-brain-price brain_price_pool
  set brain_quantity_pool fput own-brain-quantity brain_quantity_pool
  die
end 

to make_farmer_repopulate
  ;print self
  ls:let child-weights_H map [w -> random-normal w mut-rate] [get-weights] ls:of own-brain-harvest
  ls:let child-weights_P map [w -> random-normal w mut-rate] [get-weights] ls:of own-brain-price
  ls:let child-weights_Q map [w -> random-normal w mut-rate] [get-weights] ls:of own-brain-quantity

  let inherit-inputs_H [input_data] ls:of own-brain-harvest
  let inherit-inputs_P [input_data] ls:of own-brain-price
  let inherit-inputs_Q [input_data] ls:of own-brain-quantity

  hatch 1 [
    ;print self
    setup-brain-harvest
    (ls:assign own-brain-harvest input_data inherit-inputs_H)
    ls:ask own-brain-harvest [setup]
    ls:ask own-brain-harvest [train]
    ls:ask own-brain-harvest [set-weights child-weights_H]

    setup-brain-price
    (ls:assign own-brain-price input_data inherit-inputs_P)
    ls:ask own-brain-price [setup]
    ls:ask own-brain-price [train]
    ls:ask own-brain-price [set-weights child-weights_P]

    setup-brain-quantity
    (ls:assign own-brain-quantity input_data inherit-inputs_Q)
    ls:ask own-brain-quantity [setup]
    ls:ask own-brain-quantity [train]
    ls:ask own-brain-quantity [set-weights child-weights_Q]

    set risk_attitude random-normal risk_attitude mut-rate
    if risk_attitude > 1 [ set risk_attitude 1]
    if risK_attitude < -1 [set risk_attitude -1]
    right random 361
    forward random 5
    set Own-Yield [yield] of patch-here
    set VC [Variable_Cost] of patch-here
;    set VC_2 [Variable_Cost_2] of patch-here
    set FC [Ownership_Cost] of patch-here
    set OpC [Opportunity_Cost] of patch-here
    set Capacity round random-normal 175 50
    set Money_Holdings money_to_start_with
    set used_capacity 0                          ;;; these parts may cause problem in coming
    set unused_capacity 0                        ;;; they don't deserve the OpC yet
    set profit_calculator 0                      ;;;just in case
    set inventory 0                              ;;; will leave inventory_space be for a while
  ]
end 

;;_______________________________________________________;;
;;;;;;;;;;; For evaluation model performance ;;;;;;;;;;;;;
;;_______________________________________________________;;

to calculate_autocorrelation
  let mean_annual_prices mean annual_prices

  let annual_prices_for_n but-last annual_prices
  let lagged_annual_prices but-first annual_prices

  let numerator 0
  let denominator 0
  set autocorrelation 0

  if not empty? annual_prices_for_n  [
    (foreach annual_prices_for_n lagged_annual_prices [ [t l] ->
      let i 0
      set i (t - mean_annual_prices) * ( l - mean_annual_prices)
      set numerator numerator + i
      ])
    foreach annual_prices [ t ->
      let i (t - mean_annual_prices) ^ 2
      set denominator denominator + i
    ]
    set autocorrelation (numerator / denominator)
  ]
end 

to calculate_kurtosis
  let mean_annual_prices mean annual_prices
  set kurtosis 0
  let numerator 0
  let denominator 0
  if length annual_prices > 1 [
    let variance_annual_price variance annual_prices
    foreach annual_prices [ p ->
      let i 0
      set i ( p - mean_annual_prices ) ^ 4
      set numerator numerator + i
    ]
    set denominator ( ( variance_annual_price ) ^ 2 ) * (length annual_prices - 1)
    set kurtosis ( numerator / denominator) - 3
  ]
  ;print kurtosis
end 

to calculate_skewness
  let mean_annual_prices mean annual_prices
  set skewness 0
  let numerator 0
  let denominator 0
  if length annual_prices > 1 [
    let variance_annual_price variance annual_prices
    foreach annual_prices [ p ->
      let i 0
      set i ( p - mean_annual_prices ) ^ 3
      set numerator numerator + i
    ]
    set denominator ( (variance_annual_price) ^ (1.5) ) * (length annual_prices - 1)
    set skewness (numerator / denominator)
  ]
  ;print skewness
end 

to-report compute_MSE_skewness
  let s skewness
  let target 0.87
  let MSE_for_skewness ( target - s ) ^ 2
  report MSE_for_skewness
end 

to go_until
  ifelse periods < 301 [
    go]
  [stop]
end 

There is only one version of this model, created almost 2 years ago by Per Hung Yap .

Attached files

File Type Description Last updated
neural network for regression 2.nlogo extension Please download this and put in the same folder as the main folder. almost 2 years ago, by Per Hung Yap Download
neural network for regression ranged 2.nlogo extension Please download this and put in the same folder as the main folder. almost 2 years ago, by Per Hung Yap Download

This model does not have any ancestors.

This model does not have any descendants.