Ambidexterity Strategy Explorer

Ambidexterity Strategy Explorer preview image

2 collaborators

Default-person Steven Kimbrough (Author)
Christine Chou (Team member)

Tags

game theory 

Tagged by Steven Kimbrough almost 4 years ago

organizational ambidexterity 

Tagged by Steven Kimbrough almost 4 years ago

strategic decision making 

Tagged by Steven Kimbrough almost 4 years ago

Visible to everyone | Changeable by the author
Model was written in NetLogo 5.2.0 • Viewed 440 times • Downloaded 23 times • Run 0 times
Download the 'Ambidexterity Strategy Explorer' modelDownload this modelEmbed this model

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


QUICK START

Running the model is very simple.

1. In the StoredInterfaceCases chooser, pick "Base Calibration Case". This chooser is in the upper left-hand corner of the Interface tab.
2. Click the SetInterfaceCaseValues button. This button is just underneath the DefaultValues chooser
3. In the InstantiateCases chooser, pick "From the Interface tab". This chooser is just underneath the World (retangular black area, on which firms and customers may appear.
4. Optionally, change one or more of the model's parameters, which are controllable by the remaining green widgets on the Interface tab.
5. Click the SetupAndGo button to run the model. This button is just underneath the SetDefaultValues button.

NumberOfReplications will now be executed, each of length EpisodesPerRun episodes. (Both NumberOfReplications and EpisodesPerRun are set by sliders on the Interface tab.)

By default, Logging? is off (it won't work for the applet version). When it is on, three output files are created:

(i) AmbidexterityRunsOutput.txt is in comma-separated format, with column headers. It contains the main data produced by the runs conducted. It is reset each time the SetupAndGo button is clicked. You may load AmbidexterityRunsOutput.txt this file into Excel (with Data | Get External Data | Import Text File ...) or into any standard statistical package, such as R (http://www.r-project.org/ ).

(ii) AmbidexterityProducerLogFile.txt is a text file that prints out for every producer the values of all of its attributes upon initialization. The order of the producers is random.

(iii) AmbidexterityCustomerLogFile.txt is a text file that prints out for a randomly-chosen customer the values of all of itsattributes upon initialization.

All three files are keyed by the value of the NetLogo program reporter date-and-time, which is called at the beginning of the code executed by clicking on SetupAndGo. AmbidexterityRunsOutput.txt contains the main data for the run. The other two files contain further information about the setup for the run.

WHAT IS IT?

The purpose of this section is to list and briefly explain the program variables in AmbidexterityStrategyExplorer.nlogo, as they appear on the Interface tab. We note that the Interface tab is designed for setting up runs in which there are 1 or 2 suppliers, and that the program can handle an arbitrary number of suppliers. In our Results section, for example, we report on tournaments in which seven suppliers are present. What this implies should be evident to the reader: The program's internal variables are distinct from these user interface variables. At initialization, the internal variables will typically be set to values from the Interface variables, or to other values specified by the programmer. Nevertheless, understanding the Interface variables is instrumental for appreciating how the program works.

 EpisodesPerRun

Play unfolds discretely, in episodes, during which customers buy product, consider switching suppliers, and suppliers consider investing in product development. A run consists of a number of episodes, specified by EpisodesPerRun.

 NumberOfReplications

Because the model is stochastic, results will vary from run to run and it is necessary to collect data from many runs and aggregate it. NumberOfReplications sets the number of runs, each of length EpisodesPerRun, that are to be conducted.

 EarningsOnHand

The initial amount of capital the firm has at the start of a run. This capital is available for R&D project investment, if the firm wants to use it for that purpose.

 RetainedEarningsMultiplier

Agents in this model are not allowed to finance product development, whether incremental or radical, by borrorowing, issuing stocks, or issuing bonds. They must use retained earnings to pay for their R&D projects. Further, we assume that an investment can be made (in a given episode) only if its cost times RetainedEarningsMultiplier is less than its retained earnings on hand.

 BoltzmanFactor

The the program procedure ProbabilitySupplierFocal and the discussion in the main body of the paper. The lower the BoltzmanFactor, the more likely customers will switch suppliers if the incumbent is less preferred on the factor measured (e.g., price) than the alternative.

 SwitchingPolicy

This option determines what factor a customer will measure in deciding whether to stay with its focal supplier or switch. Again, see the ProbabilitySupplierFocal procedure. In all of the runs reported here SwitchingPolicy is "Boltzman on value / price". That is, the customer looks at the ratio of product 0 value to price for its suppliers, and switches under a Boltzman distribution.

 AmbidexterityCostMultiplier

As noted above, an investment is made only if its cost times RetainedEarningsMultiplier is less than the retained earnings. If, in addition, the strategy to hand is an ambidextrous one, then an investment is made in a given project only if its costs times RetainedEarningsMultiplier times AmbidexterityCostMultiplier is less than the retained earnings.

 PerturbancePercent

If Perturbing? is on, then a list of variables identified in CreateAndInitializeCustomers and SetGlobalParameters are randomly perturbed from their initialization values at the start of each run. PerturbancePercent set the amount of perturbance. If, for example, it is 0.10, or 10%, then each variable to be perturbed is set to a new value that is uniformly drawn from plus and minus 10% of its initialization value. (This is subject to maintaining values above 0. Also, rounding is done for integer variables.)

 LocusOfIncrementalInprovement

The Interface has two variables, one for supplier 0 and one for supplier 1. Regardless of the number of suppliers, each has a value for this variable. If it is set to Cost, then if the supplier has a successful incremental investment, the cost of production of product 0 is reduced. If it is set to Value, then the value of the product is increased.

IncrementalProjectCostIncrement

If a supplier invests in an incremental project and is successful and has chosen the Cost option for LocusOfIncrementalInprovement, then the supplier's production cost for product 0 is reduced as follows:

    if (LocusOfIncrementalImprovement = "Cost")
         [set unitCost0 (unitCost0 * (1 - (IncrementalProjectCostIncrement / 100.0)))]


IncrementalProjectValueIncrement

If a supplier invests in an incremenal project and is successful and has chosen the Value option for LocusOfIncrementalInprovement, then the supplier´┐Żs product 0 is increased in value as follows:

    if (LocusOfIncrementalImprovement = "Value")
         [set value0 (value0 + IncrementalProjectValueIncrement)]


 IncrementalInvestmentCost

Just what it says. This is what a supplier must pay up front to initiate an incremental R&D project.

 ProbSuccessIncrementalInvestment

The probability that an incremental R&D project will be successful in finding a product improvement.

 MaturationEpisodesIncrementalInvestment

The time, measured in episodes, to complete an incremental R&D project. 

 IncrementalLimit

The maximum number of incremental projects a supplier may invest in during a given run.

 MaxSimultaneousProjects

The maximum number of incremental projects a supplier may have underway at any given time.

 RadicalInvestmentCost

This is what a supplier must pay up front to initiate a radical (exploratory) R&D project.

 ProbSuccessRadicalInvestment

The probability that a radical R&D project will be successful in finding a radical new product (for which the customers have latent demand).

 MaturationEpisodesRadicalInvestment

The time, measured in episodes, to complete a radical R&D project.

 RadicalLimit

The maximum number of radical projects a supplier may invest in during a given run.

 RadicalProductionLimit

The maximum production per period (episode) possible for product 1 by a supplier, presuming the supplier has discovered the new product.

 InitialDemand0, InitialDemand1

The amounts of product 0 and 1 that each customer would like to purchase in each episode.

 SequentialIncrementalEpochLength, SequentialRadicalEpochLength

For the supplier following the "Sequential Ambidexterity" strategy, the lengths of its incremental and radical epochs, in number of episodes.

From the code itself:

;;;;;;;;;;;; Initial production values ;;;;;;;;;;;;;;;;;;;;
  set P0P1IP 0 ; Producer 0 Product 1 Initial Production
  set P1P1IP 0 ; Producer 1 Product 1 Initial Production
  set P0P1IV 50 ; Producer 0 Product 1 Initial Value
  set P1P1IV 50 ; Producer 1 Product 1 Initial Value
  set P0P1IPrice 50 ; Producer 0 Product 1 Initial Price
  set P1P1IPrice 50 ; Producer 1 Product 1 Initial Price
  set P0P1UC 40 ; Producer 0 Product 1 Unit Cost
  set P1P1UC 40 ; Producer 1 Product 1 Unit Cost    

Internally, the suppliers represent P0P1IP and P1P1IP with product1production.

 NumberOfCustomers

The number of customers in a run. The default value is 120 for a two-supplier setup.

 Epsilon

The probability in a particular episode that a customer will first try its secondary supplier first.

 Producer0Product0InitialProduction, Producer1Product0InitialProduction

The per-episode production levels of product 0 for suppliers 0 and 1. Internally, the suppliers represent these in the variable product0production.

 Producer0InitialPrice0, Producer1InitialPrice0

The price for product 0 charged by supplier 0/1 at the beginning of the run.

 Producer0Product0InitialValue, Producer1Product0InitialValue

The value of product 0 to the customers, for products from supplier 0/1 at the beginning of the run.

 InitialProduct0Producer0UnitCost, InitialProduct0Producer1UnitCost

The unit cost of production of product 0 at the beginning of the run for supplier 0/1.

 CustomerEpochLengthLow, CustomerEpochLengthHigh

Each customer has an EpochLength, set at initialization of the run and drawn uniformly from [CustomerEpochLengthLow, CustomerEpochLengthHigh]. An epoch expires after EpochLength episodes. At this time the customer reconsiders which shall be its primary supplier and randomly picks a secondary supplier.

HOW IT WORKS

  1. The industry consists of 2 or more supplier firms (the number of firms is set by the user). Each produces and sells product 0 to the market.
  2. Time unfolds discretely. Each tick of the clock is called an episode of activity.
  3. There are NumCustomers customers in the market for product 0. Each customer has an inherent demand for product 0, which it seeks to satisfy during each episode of activity. The inherent demand for product 0, common to all customers, is governed by the parameter InitialDemand0, which itself is set by a slider on the Interface tab (in the default case of initialization from the Interface tab; users may initialize variables under program control as well). The default value is 5. Each customer has an inherent demand for product 1, which it also seeks to satisfy during each episode. It is governed (in the default case) by the parameter InitialDemand1, which itself may be set by a slider on the Interface tab and also has a default value of 5.
  4. Unit prices for product 0 are constant. The products have a quality index, which may change over time. Vendors may compete on quality and/or reduction of cost of manufacture.
  5. Each customer focuses on one of the producers as its primary vendor, using an "epsilon greedy" policy (Sutton and Barto, 1998). During any given episode a customer seeks with probability (1 - epsilon) to fulfill its requirements for product 0 from its focal supplier. If the focal supplier has sufficient quantity on hand, the transaction is made; otherwise the customer attempts to purchase unfulfilled need for product 0 from another supplier, chosen randomly. With probability ? the customer first attempts to purchase its supply of product 0 from the non-focal vendor. After each transaction each customer records the supplier(s) and product qualities it experienced.
  6. Each supplier has a unit cost of manufacture and a price for its product 0. Profits (and losses) are accumulated after transactions occur.
  7. Each customer reconsiders its focal supplier after a number of episodes have occurred, called the EpochLength for the customer. At the end of its epoch, a customer will probabilistically refocus on a supplier based on which of the suppliers has provided it higher quality on average. (See Kimbrough and Murphy (2009, "Learning to collude tacitly on production levels by oligopolistic agents", Computational Economics, vol. 33, no. 1, pages 47-80) for a full discussion of a related learning model, using epochs. We use a parameterized Boltzman distribution to determine the relevant probabilities, in effect the widely-used soft-max distribution (Sutton and Barto, 1998, Reinforcement Learning: An Introduction, MIT Press).)
  8. Each customer also has a latent demand for product 1, which is not offered on the market at the inception of the simulation. If any vendor offers product 1, the market proceeds in a manner structurally identical to that for product 0.
  9. Vendors also organize their time (episodes, ticks of the clock) into epochs. At the end of its epoch a vendor considers whether to invest in R&D and if so, whether to invest in incremental innovation or in radical innovation. That is, whether to invest in cost or quality improvements in product 0 or in discovering an unknown new product (which we know as product 1). Each investment has a cost, a probability of success, and an incubation period (in number of episodes or ticks). The vendor must pay for the R&D from accumulated profits when the decision is made. Accumulated profits cannot go negative.
  10. There is a "complexity cost" incurred when investing in both an incremental innovation and a radical innovation. This is in addition to the base cost of each investment. Multiple investments of the same type are permitted without incurring the complexity cost. (The program variable is AmbidexterityCostMultiplier, by default set at 1.5.)
  11. At the end of an investment's incubation period success or failure is probabilistically realized. In the case of success with an incremental innovation the result is an improvement in the quality index of product 0 and/or a reduction in the cost of manufacture, depending on the policy of the firm. In the case of success with a radical innovation the result is that the vendor may sell product 1 and realize profits, which by default are set quite high.
  12. To prepare (initialize) a run, the system parameters are set. See Figure 1 for the default values. See the Appendix for description of the main program variables.
  13. In each episode (see the Go procedure in the source code), each of the producers replenishes its supplies of products 0 and 1.
    Then each customer:
    (a) Resets its demands for products 0 and 1.
    (b) Determines its FirstSupplier for the episode, using epsilon-greedy: with probability 1-? the customer uses its FocalSupplier as its FirstSupplier and its OtherSupplier as its SecondSupplier, and with probability?, vice versa.
    (c) Attempts to fill its demand for product 0 from its FirstSupplier and then (if the supplier is exhausted) from its SecondSupplier. In doing so, when it acquires a unit of supply, the customer updates two accumulators: the count of purchased product from the supplier, and the total value received from the supplier during the epoch.
    (d) Attempts to fill its demand for product 1 from its FirstSupplier and then (if the supplier is exhausted) from its SecondSupplier .
  14. To postpare an episode (that is, to undertake processing after completing an episode):
    (a) Producers realize any gains from trade, decide whether to make investments in development projects, and conclude any projects that have completed.
    (b) If the episode concludes an epoch for the customer, the customer reconsiders its FocalSupplier, based on quantity and price performance for product 0. Once the FocalSupplier for the next epoch has been chosen, the customer randomly picks its OtherSupplier for the next epoch. (See the procedure CustomerPostPareEpisode.)

HOW TO USE IT

See the QUICK START section above. Once you are in control of the basics, as described there, explore by setting new values on the Interface widgets, and by picking other options in the StoredInterfaceCases and InstantiateCases choosers.

LOGGING

With Logging? on, the program outputs three files: AmbidexterityRunsOutput.txt, AmbidexterityProducerLogFile.txt, AmbidexterityCustomerLogFile.txt. This does not work with the applet version, of course.

BUTTONS

 RunFromAFile

Reads the file AmbidexterityInputs.txt and executes it line by line. See the RUNNING FROM AN INPUT FILE section below.

 Setup and GoNReplicationsMonteCarlo

This works, but it's actually much easier just to set Perturbing? to on and proceed as usual with

 SetupAndGo.


 Setup and GoFactorial

See the GoFactorial procedure. The user may modify this procedure to direct runs for a factorial design of an experiment. Can be used with Perturbing? on. Obviously, you'll want to have Logging? on.

RUNNING FROM AN INPUT FILE

The program accepts an input file in the current directory, named "AmbidexterityInputs.txt". Below is an example of a correct input file. The first two setups are careful to set values for all of the parameters (global variables) set in widgets on the Interface tab. The third setup relies on these variables being properly set, and simply changes a couple of values.

; Comment lines can be added to make the file readable.
set Logging? true
set NumberOfCustomers 150
Setup
GoNReplications
; Done with first iteration
; Starting second iteration
set RunID date-and-time
set NumberOfCustomers 200
GoNReplications
; Starting third iteration
set RunID date-and-time
set DaProbe (random-float 1) * 20
set NumberOfCustomers round (190 + DaProbe)
GoNReplications
; Starting fourth iteration
set RunID date-and-time
GoNReplicationsMonteCarlo
print (word "All done from file!")

To run from a file, put a properly-defined "AmbidexterityInputs.txt" file in the same directory as the NetLogo IDS-experiments.nlogo file, and click the "RunFromFile" button on the Interface tab. The program will produce the usual output files, assuming Logging? is set to true. Recall: the output files are in comma-separated format, with headers, and can be read by Excel, R, and other statistical analysis programs.

RSTATISTICALPROGRAM

> getwd()
[1] "/Users/kimbrough/svnstar/top/code/NetLogo"
> NoInvMaxIncrInv <- read.table("AmbidexterityRunsOutput.txt",header=T,sep=',')
> summary(NoInvMaxIncrInv)

To set the working directory:

> setwd('svnstar/')

To see what is in the directory:

> dir()

HOW TO CITE

If you mention this model in a publication, we ask that you include these citations for the model itself and for the NetLogo software:

  • Chou, Christine, and Kimbrough, Steven O., Ambidexterity Strategy Explorer. (2015) File: AmbidexterityStrategyExplorer.nlogo.

  • Wilensky, U. (1999). NetLogo. http://ccl.northwestern.edu/netlogo/. Center for Connected Learning and Computer-Based Modeling, Northwestern University, Evanston, IL.

COPYRIGHT AND LICENSE

CC BY-NC-SA 3.0

This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

Commercial licenses are also available. To inquire about commercial licenses, please contact Uri Wilensky at uri@northwestern.edu.

This model was created as part of the project: CONNECTED MATHEMATICS: MAKING SENSE OF COMPLEX PHENOMENA THROUGH BUILDING OBJECT-BASED PARALLEL MODELS (OBPML). The project gratefully acknowledges the support of the National Science Foundation (Applications of Advanced Technologies Program) -- grant numbers RED #9552950 and REC #9632612.

This model was converted to NetLogo as part of the projects: PARTICIPATORY SIMULATIONS: NETWORK-BASED DESIGN FOR SYSTEMS LEARNING IN CLASSROOMS and/or INTEGRATED SIMULATION AND MODELING ENVIRONMENT. The project gratefully acknowledges the support of the National Science Foundation (REPP & ROLE programs) -- grant numbers REC #9814682 and REC-0126227. Converted from StarLogoT to NetLogo, 2001.

Comments and Questions

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

Click to Run Model

globals [daVersion ; For displaying the version info from the CVS repository
         myEpsilon ; myEpsilon is simply a small floating point number to handle numerical
                   ; comparisons
         replicationsCompleted ; a counter to hold the number of replications completed of a given experiment
         episodeRunCounter ; a counter to hold the number of episodes completed
         ;producer0Color producer1Color
         versionID ; Holds the Subversion ID string.
         ;retainedEarnings0 ; holds retained earnings of firm 0 across replications
         ;retainedEarnings1 ; holds retained earnings of firm 1 across replications
         NumProducers ; The internal variable; NumberOfProducers is only  for the Interface tab
         

         ProducerWhos ; The who values of the producers; assumed to begin at 0 and go to NumProducers - 1
         RunID ; set once with date-and-time
         StringToPrint ; a global variable to be used as a string
         DaProbe ; variable used for Monte Carlo sensitivity studies
         ;;;;;; For Monte Carlo Sensitivity Analysis: ;;;;;;
         NumCustomers-Fixed ; The fixed value of NumCustomers; used for perturbing in sensitivity analysis
         NumCustomers-Used ; The internal variable; NumberOfCustomers is only  for the Interface tab
         Demand0-Fixed Demand0-Used   
         Demand1-Fixed Demand1-Used      
         RetainedEarningsMultiplier-Fixed RetainedEarningsMultiplier-Used
         BoltzmanFactor-Fixed BoltzmanFactor-Used
         AmbidexterityCostMultiplier-Fixed AmbidexterityCostMultiplier-Used
         Producer0Product0InitialProduction-Fixed Producer0Product0InitialProduction-Used
         Producer1Product0InitialProduction-Fixed Producer1Product0InitialProduction-Used
         ProbSuccessIncrementalInvestment-Fixed ProbSuccessIncrementalInvestment-Used
         ProbSuccessRadicalInvestment-Fixed ProbSuccessRadicalInvestment-Used
]

breed [producers producer]
breed [customers customer]

producers-own [; First product 0:
               supply0 ; the count of product 0 on hand and available for sale
               price0 ; the unit price of product 0
               value0 ; the unit value to the customer of product 0
               unitCost0 ; the cost of producing one product 0
               netSales0 ; sum of (price - unitCost) for sales made of product 0 during an episode
               countSales0 ; number of sales units for product 0 during the run
               countSuccessfulIncrementalProjects ; the a total count of incremental projects that were successful during the run
               product0production ; the amount of product 0 that a producer produces in 1 episode (period)
               ; Next product 1:
               supply1 ; the count of product 0 on hand and available for sale
               price1 ; the unit price of product 1
               value1 ; the unit value to the customer of product 1
               unitCost1 ; the cost of producing one product 1
               netSales1 ; sum of (price - unitCost) for sales made of product 1 during an episode
               product1production ; the amount of product 1 that a producer produces in 1 episode (period)
               LocusOfIncrementalImprovement ; where the improvement comes, in value or cost or both
               incrementalProjMaturation ; a list of maturation times (ticks) for incremental projects
               radicalProjMaturation ; a list of maturation times (ticks) for radical projects
               
               strategy ; the strategy being followed by the firm, from StrategyFirmX on the Interface
               retainedEarnings ; netsales minus investment costs
               
               countOfIncrementalInvestments ; the number of incremental investments the producer firm has made
               countOfRadicalInvestments ; the number of radical investments the producer firm has made
               countOfSuccessfulRadicalInvestments ; the number of successful radical investments the producer firm has made
               
               totalSales0 totalSales1 ; accumulation of per period netSales0 and netSales1
               endIncrementalMode ; For a producer that has a sequential strategy the ticks value at which incremental mode ends, or -1
               endRadicalMode ; For a producer that has a sequential strategy the ticks value at which radical exploration mode ends, or -1
               ]
customers-own [FocalSupplier ; Should be on the list of ProducerWhos
               OtherSupplier ; The idea is that at any given time a customer has a primary and a secondard supply.
               ; The OtherSupplier is randomly at the beginning of each epoch (or episode)
               ; First, product 0 
               Demand0 ; the count of product 0 units demanded by a given customer per episode (period)
               PurchasedProduct0Producer0 PurchasedProduct0Producer1 ; the number of units purchased during
                     ; an epoch from producer 0 (focal) /1 (other)
               Value0Producer0 Value0Producer1 ; the accumulation of the value of the units purchased during
                     ; an epoch from producer 0 (focal) /1 (other)
               ; Next, product 1
               Demand1 ; the count of product 0 units demanded by a given customer per episode (period)
               PurchasedProduct1Producer0 PurchasedProduct1Producer1 ; the number of units purchased during
                     ; an epoch from producer 0 (focal) /1 (other)
               Value1Producer0 Value1Producer1 ; the accumulation of the value of the units purchased during
                     ; an epoch from producer 0 (focal) /1 (other)
               EpochLength ; The number of episodes tried for a focal supplier choice, before reconsidering
              ]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetupAndGo ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to SetupAndGo
;; (for this model to work with NetLogo's new plotting features,
  ;; __clear-all-and-reset-ticks should be replaced with clear-all at
  ;; the beginning of your setup procedure and reset-ticks at the end
  ;; of the procedure.)
  __clear-all-and-reset-ticks ; Clear everything, reset variables, reset plots, etc.
; Determine the random seed to use and print out the first random-float:
if (RecordMovie?)
  [movie-start "out.mov"
   movie-grab-interface
  ]
ifelse (RandomNumberSeed = "System Clock")
   [random-seed new-seed]
   [random-seed RandomNumberSeed]
;print (word "The first (0,1) random float is " random-float 1)   
set daVersion "$Id: AmbidexterityStrategyExplorer.nlogo 3035 2012-07-16 16:11:17Z sok $"
set myEpsilon 0.000001
SetupARun ; I'm calling this here to get parameter values for creating the file header.
  ; Notice that it is called again below, in the while [ReplicationsCompleted < NumberOfReplications] loop.
;;;;;;;;;;;;;;;;; If we are logging, ... ;;;;;;;;;;;;;
if (logging?) [
 set RunID date-and-time
 CreateRunsOutFileHeader
  if (file-exists? "AmbidexterityCustomerLogFile.txt")
     [file-close
      file-delete "AmbidexterityCustomerLogFile.txt"]
  if (file-exists? "AmbidexterityProducerLogFile.txt")
     [file-close
      file-delete "AmbidexterityProducerLogFile.txt"]
 CreateProducerLogFile
 CreateCustomerLogFile
     ]    
  ;;;; Now do a run of NumberOfReplications replications: ;;;;;
  set ReplicationsCompleted 0  
  while [ReplicationsCompleted < NumberOfReplications]
   [SetupARun
    if (RecordMovie?)
    [movie-grab-interface]
    GoNEpisodes
    set replicationsCompleted (replicationsCompleted + 1)
    if (Logging?)[
     RecordRunOutput
     ]
   ]
   if (RecordMovie?)
   [movie-close]
end  ; of SetupAndGo

to Setup
  ; Copied from the beginning of SetupAndGo
;; (for this model to work with NetLogo's new plotting features,
  ;; __clear-all-and-reset-ticks should be replaced with clear-all at
  ;; the beginning of your setup procedure and reset-ticks at the end
  ;; of the procedure.)
  __clear-all-and-reset-ticks ; Clear everything, reset variables, reset plots, etc.
; Determine the random seed to use and print out the first random-float:
ifelse (RandomNumberSeed = "System Clock")
   [random-seed new-seed]
   [random-seed RandomNumberSeed]
;print (word "The first (0,1) random float is " random-float 1)   
set daVersion "$Id: AmbidexterityStrategyExplorer.nlogo 3035 2012-07-16 16:11:17Z sok $"
set myEpsilon 0.000001
SetupARun ; I'm calling this here to get parameter values for creating the file header.
  ; Notice that it is called again below, in the while [ReplicationsCompleted < NumberOfReplications] loop.
;;;;;;;;;;;;;;;;; If we are logging, ... ;;;;;;;;;;;;;
if (logging?) [
 set RunID date-and-time
 CreateRunsOutFileHeader
  if (file-exists? "AmbidexterityCustomerLogFile.txt")
     [file-close
      file-delete "AmbidexterityCustomerLogFile.txt"]
  if (file-exists? "AmbidexterityProducerLogFile.txt")
     [file-close
      file-delete "AmbidexterityProducerLogFile.txt"]
 ;CreateProducerLogFile
 ;CreateCustomerLogFile
     ]    
end  ; of Setup

to GoNReplications
  ; Copied from SetupAndGo
    if (logging?) [
      set RunID date-and-time
      ;CreateRunsOutFileHeader
      CreateProducerLogFile
      CreateCustomerLogFile
     ]    
  set ReplicationsCompleted 0  
  while [ReplicationsCompleted < NumberOfReplications]
   [SetupARun
    GoNEpisodes
    set replicationsCompleted (replicationsCompleted + 1)
    if (Logging?)[
     RecordRunOutput
     ]
   ]  
end 

to GoNReplicationsMonteCarlo
  ; Copied from SetupAndGo
    if (logging?) [
      set RunID date-and-time
      ;CreateRunsOutFileHeader
      CreateProducerLogFile
      CreateCustomerLogFile
     ]    
  set ReplicationsCompleted 0  
  while [ReplicationsCompleted < NumberOfReplications]
   [MonteCarlo
    SetupARun
    GoNEpisodes
    set replicationsCompleted (replicationsCompleted + 1)
    if (Logging?)[
     RecordRunOutput
     ]
   ]  
end 

to MonteCarlo
  set DaProbe (random-float 1) * 20
  set NumberOfCustomers round (190 + DaProbe)
end 

to GoFactorial
    if (logging?) [
      set RunID date-and-time
      CreateProducerLogFile
      CreateCustomerLogFile
     ]    
foreach (list 200 220 230) [
  let DaFirst ?
foreach (list 6500 7000 7500) [
  let DaSecond ?
  set ReplicationsCompleted 0  
  while [ReplicationsCompleted < NumberOfReplications]
   [SetupARun
    set NumCustomers-Used DaFirst
    set RadicalInvestmentCost DaSecond
    GoNEpisodes
    set replicationsCompleted (replicationsCompleted + 1)
    if (Logging?)[
     RecordRunOutput
     ]
   ]    
] ; end of foreach 2
] ; each of foreach 1
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetupARun ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to SetupARun
reset-ticks
set daVersion "$Id: AmbidexterityStrategyExplorer.nlogo 3035 2012-07-16 16:11:17Z sok $"
;set producer0Color red
;set producer1Color  blue
; We can't use clear-all (ca) and clear everything, reset variables, reset plots, etc.
; because we want to conduct multiple runs and we want Setup to set things up for a 
; singe run. So we
clear-all-plots
clear-output
clear-turtles
; We could use the built-in tick function and ticks reporter:
set episodeRunCounter 0 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SetGlobalParameters
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Create and initialize the producers
CreateAndInitializeProducers
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;; Now create and initialize the customers
CreateAndInitializeCustomers
end  ; of SetupARun
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GoNEpisodes ;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to GoNEpisodes
;      if (Perturbing?) [
;        PerturbParameters
;      ]
while [episodeRunCounter < episodesPerRun]
[if (RecordMovie?)
    [movie-grab-interface]
  Go
 set episodeRunCounter (episodeRunCounter + 1) ; since we've completed an episode
 ]
;print (word "Finished. episodeRunCounter = " episodeRunCounter)
if (RecordMovie?)
    [movie-grab-interface]
end 

to Go
tick
ask producers [set supply0 product0production
               set supply1 product1production
  ] ; At the start of each episode, producers update their supply on hand
ask customers
  [let firstSupplier -100 ; local variables declared
   let secondSupplier -101
   set demand0 Demand0-Used ; InitialDemand0 ; reset demand for the new episode
   set demand1 InitialDemand1 ;
   ifelse (random-float 1 < epsilon)
     [set firstSupplier otherSupplier
      set secondSupplier focalSupplier]
     [set firstSupplier focalSupplier
      set secondSupplier otherSupplier]
   ;print (word "In Go, firstSupplier=" firstSupplier)
   ; Declare presentSupplier
   let presentSupplier FocalSupplier ; or anything. 
     ; This is just to declare the variable.

 ; Attempts to fill its demand for product 0 from its firstSupplier. 
 ; and then (if the supplier is exhausted) from its secondSupplier.
 foreach (list firstSupplier secondSupplier)
  [set presentSupplier ?    
   while [([supply0] of producer presentSupplier > 0) and demand0 > 0]
   ;if ([supply0] of producer presentSupplier > 0)
   [; increment purchase
   ifelse (presentSupplier = FocalSupplier)
     [set purchasedProduct0Producer0 (purchasedProduct0Producer0 + 1)
      set value0Producer0 (value0Producer0 + [value0] of producer FocalSupplier)]
     [set purchasedProduct0Producer1 (purchasedProduct0Producer1 + 1)
      set value0Producer1 (value0Producer1 + [value0] of producer OtherSupplier)]    
   ; decrement supply
   ask producer presentSupplier [set supply0 (supply0 - 1)]
   ; decrement demand
   set demand0 (demand0 - 1)
   ; increment netSales
   ask producer presentSupplier [set netSales0 (netSales0 + (price0 - unitCost0))
     set countSales0 (countSales0 + 1)]
   ] ; end of while ....  
   ] ; end of foreach
 ;;;;;;;;;;;;;;;;;;;;;;;; Demand for Product 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Attempts to fill its demand for product 1 from its {\tt firstSupplier}  
 ; and then (if the supplier is exhausted) from its {\tt secondSupplier} .
 foreach (list firstSupplier secondSupplier)
  [set presentSupplier ? 
   while [([supply1] of producer presentSupplier > 0) and demand1 > 0]
   [; increment purchase
   ifelse (presentSupplier = 0)
     [set purchasedProduct1Producer0 (purchasedProduct1Producer0 + 1)
      set value1Producer0 (value1Producer0 + [value1] of producer 0)]
     [set purchasedProduct1Producer1 (purchasedProduct1Producer1 + 1)
      set value1Producer1 (value1Producer1 + [value1] of producer 1)]
   ; decrement supply
   ask producer presentSupplier [set supply1 (supply1 - 1)]
   ; decrement demand
   set demand1 (demand1 - 1)
   ; increment netSales
   let unitProfit ([price1] of producer presentSupplier - [unitCost1] of producer presentSupplier)
   ask producer presentSupplier [set netSales1 (netSales1 + (price1 - unitCost1))]
   ] ; end of while ....
   ] ; end of foreach [firstSupplier secondSupplier]
  ] ; end of ask customers
  
  PlotFocalSuppliers
  PlotRetainedEarnings
  ; PlotProduct0Values
  ask customers [CustomerPostPareEpisode]
  ask producers [ProducerPostPareEpisode]
end  ; of Go

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;  CustomerPostPareEpisode   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to CustomerPostPareEpisode
 ; Reset demand
 set demand0 Demand0-Used ; InitialDemand0
 set demand1 InitialDemand1
 ;print (word "demand0=" demand0 " demand1=" demand1")
 ; Have we completed an epoch for this turtle? 
 ; If so, reconsider focalSupplier and reset accummulators to 0. 
 ; If not, simply continue.
 if (ticks mod epochLength = 0)
  [;print "Starting new epoch in CustomerPostPareEpisode"
    let daProb0 ProbabilitySupplierFocal(value0Producer0)(purchasedProduct0Producer0)(value0Producer1)(purchasedProduct0Producer1) 
   ; value0Producer0 is the value received for product 0 from the focal supplier, called 0
   ;print (word "daProb0=" daProb0)
   if (daProb0 < 0)
    [print "Product is exhausted. Stop the simulation."
     ;stop
     ]
   ifelse (random-float 1 < daProb0)
   [; (Keep FocalSupplier, draw a new OtherSupplier)
    set OtherSupplier one-of remove-item FocalSupplier ProducerWhos
   ]
   [set FocalSupplier OtherSupplier
    set color [color] of producer FocalSupplier
    set OtherSupplier one-of remove-item FocalSupplier ProducerWhos
    ] 
   set value0Producer0 0
   set purchasedProduct0Producer0 0
   set value0Producer1 0
   set purchasedProduct0Producer1 0
   set value1Producer0 0
   set purchasedProduct1Producer0 0
   set value1Producer1 0
   set purchasedProduct1Producer1 0
  ] ; end of if (ticks mod epochLength = 0)
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;  ProducerPostPareEpisode   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to ProducerPostPareEpisode
;if (is-producer? self) [
 set retainedEarnings (retainedEarnings + netSales0)
 set retainedEarnings (retainedEarnings + netSales1)
 set totalSales0 (totalSales0 + netSales0)
 set totalSales1 (totalSales1 + netSales1)
 set netSales0 0
 set netSales1 0
 if (strategy = "Max Incremental Investment" and (RetainedEarningsMultiplier-Used * IncrementalInvestmentCost < retainedEarnings) and length incrementalProjMaturation < MaxSimultaneousProjects)
  [set incrementalProjMaturation lput (ticks + MaturationEpisodesIncrementalInvestment) incrementalProjMaturation
   set retainedEarnings (retainedEarnings - IncrementalInvestmentCost)
   set countOfIncrementalInvestments (countOfIncrementalInvestments + 1)
  ]
 if (strategy = "Max Incremental Investment Limited" and 
   (RetainedEarningsMultiplier-Used * IncrementalInvestmentCost < retainedEarnings) and 
   length incrementalProjMaturation < MaxSimultaneousProjects
     and countOfIncrementalInvestments < IncrementalLimit)
  [set incrementalProjMaturation lput (ticks + MaturationEpisodesIncrementalInvestment) 
         incrementalProjMaturation
   set retainedEarnings (retainedEarnings - IncrementalInvestmentCost)
   set countOfIncrementalInvestments (countOfIncrementalInvestments + 1)
  ]
  ; "Competitive Incremental Investment"
 let p1 ([value0] of producer 0 / [price0] of producer 0)
 let p2 ([value0] of producer 1 / [price0] of producer 1)
 let competitiveInvest " "
 ifelse ([who] of self = 0)
  [ifelse (p1 > p2)
   [set competitiveInvest false]
   [set competitiveInvest true]]
  [ifelse (p1 > p2)
   [set competitiveInvest true]
   [set competitiveInvest false]
  ]
 if (strategy = "Competitive Incremental Investment" and (RetainedEarningsMultiplier-Used * IncrementalInvestmentCost < retainedEarnings) and length incrementalProjMaturation < MaxSimultaneousProjects
     and competitiveInvest)
  [set incrementalProjMaturation lput (ticks + MaturationEpisodesIncrementalInvestment) incrementalProjMaturation
   set retainedEarnings (retainedEarnings - IncrementalInvestmentCost)
   set countOfIncrementalInvestments (countOfIncrementalInvestments + 1)
  ]  
 if (strategy = "Max Radical Investment" and 
     (RetainedEarningsMultiplier-Used * RadicalInvestmentCost < retainedEarnings) and 
      countOfSuccessfulRadicalInvestments < 1)
  [set radicalProjMaturation lput (ticks + MaturationEpisodesRadicalInvestment) radicalProjMaturation
   set retainedEarnings (retainedEarnings - RadicalInvestmentCost)
   set countOfRadicalInvestments (countOfRadicalInvestments + 1)
  ] 
  
  
  if (strategy = "Max Radical Investment Limited" and 
     (RetainedEarningsMultiplier-Used * RadicalInvestmentCost < retainedEarnings) and 
      countOfSuccessfulRadicalInvestments < 1 and 
      countOfRadicalInvestments <= RadicalLimit)
  [set radicalProjMaturation lput (ticks + MaturationEpisodesRadicalInvestment) 
      radicalProjMaturation
   set retainedEarnings (retainedEarnings - RadicalInvestmentCost)
   set countOfRadicalInvestments (countOfRadicalInvestments + 1)
  ] 
 if (strategy = "Max Incremental Limited & Radical Investment Limited" and
    ((RadicalInvestmentCost) * AmbidexterityCostMultiplier-Used * 
      RetainedEarningsMultiplier-Used < retainedEarnings) 
    and countOfSuccessfulRadicalInvestments < 1  and 
    countOfRadicalInvestments <= RadicalLimit)
  [set radicalProjMaturation lput (ticks + MaturationEpisodesRadicalInvestment) 
       radicalProjMaturation
   set retainedEarnings (retainedEarnings - 
     (RadicalInvestmentCost * AmbidexterityCostMultiplier-Used))
   set countOfRadicalInvestments (countOfRadicalInvestments + 1)
  ] 
 if (strategy = "Max Incremental Limited & Radical Investment Limited" and 
   (RetainedEarningsMultiplier-Used * (IncrementalInvestmentCost) * 
     AmbidexterityCostMultiplier-Used < retainedEarnings) 
    and countOfIncrementalInvestments < IncrementalLimit) 
  [set incrementalProjMaturation lput (ticks + MaturationEpisodesIncrementalInvestment) 
    incrementalProjMaturation
   set retainedEarnings (retainedEarnings - (IncrementalInvestmentCost * 
       AmbidexterityCostMultiplier-Used))
   set countOfIncrementalInvestments (countOfIncrementalInvestments + 1)
  ] 
  
  if (strategy = "Sequential Ambidexterity"  and 
    ticks <= endIncrementalMode ; Behave as Max Incremental Investment Limited
     and (RetainedEarningsMultiplier-Used * IncrementalInvestmentCost < retainedEarnings) 
     and length incrementalProjMaturation < MaxSimultaneousProjects
     and countOfIncrementalInvestments < IncrementalLimit)
  [set incrementalProjMaturation lput (ticks + MaturationEpisodesIncrementalInvestment) 
       incrementalProjMaturation
   set retainedEarnings (retainedEarnings - IncrementalInvestmentCost)
   set countOfIncrementalInvestments (countOfIncrementalInvestments + 1)
  ]
  if (strategy = "Sequential Ambidexterity"  and 
    ticks <= endRadicalMode  ; Behave as Max Radical Investment Limited
     and (RetainedEarningsMultiplier-Used * RadicalInvestmentCost < retainedEarnings) and 
      countOfSuccessfulRadicalInvestments < 1 and countOfRadicalInvestments <= RadicalLimit)
  [set radicalProjMaturation lput (ticks + MaturationEpisodesRadicalInvestment) 
       radicalProjMaturation
   set retainedEarnings (retainedEarnings - RadicalInvestmentCost)
   set countOfRadicalInvestments (countOfRadicalInvestments + 1)
  ]  
  
  ; Now postpare any boundary changes:
  if (endIncrementalMode = ticks)
    [set endRadicalMode (ticks + SequentialRadicalEpochLength)
     set endIncrementalMode -1]
  if (endRadicalMode = ticks)
    [set endIncrementalMode (ticks + SequentialIncrementalEpochLength)
     set endRadicalMode -1]
     
  ; Process any matured incremental investments:
  if (not empty? incrementalProjMaturation and ticks = first incrementalProjMaturation)
  [set incrementalProjMaturation but-first incrementalProjMaturation
   if (random-float 1 <= ProbSuccessIncrementalInvestment-Used)
    [set countSuccessfulIncrementalProjects (countSuccessfulIncrementalProjects + 1)
      if (LocusOfIncrementalImprovement = "Value")
      [set value0 (value0 + IncrementalProjectValueIncrement)]
     if (LocusOfIncrementalImprovement = "Cost")
      [;set unitCost0 (unitCost0 * (1 - (IncrementalProjectCostIncrement / 100.0)))
        set unitCost0 (unitCost0 - IncrementalProjectCostIncrement)
        ]
     if (LocusOfIncrementalImprovement = "Cost and Value")
      [set unitCost0 (unitCost0 * (1 - (IncrementalProjectCostIncrement / 100.0)))
       set value0 (value0 + IncrementalProjectValueIncrement)]
     if (LocusOfIncrementalImprovement = "Cost and Price")
      [set unitCost0 (unitCost0 * (1 - (IncrementalProjectCostIncrement / 100.0)))
       set price0 (price0 * (1 - (IncrementalProjectCostIncrement / 150.0)))]
    ]
    ] ; end of if (not empty? incrementalProjMaturation ...
    
  if (not empty? radicalProjMaturation and ticks = first radicalProjMaturation)
  [set radicalProjMaturation but-first radicalProjMaturation
   if (random-float 1 <= ProbSuccessRadicalInvestment-Used)
    [set countOfSuccessfulRadicalInvestments (countOfSuccessfulRadicalInvestments + 1)
    set product1production RadicalProductionLimit]
    ]    
end  ; end of to ProducerPostPareEpisode

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;  ProbabilitySupplierFocal  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to-report ProbabilitySupplierFocal [valueP0 purchasedP0 valueP1 purchasedP1]
  ; Returns the probability of going with the focal supplier, 0
; 1 + to prevent division by 0
let daRatioS0 (valueP0 / (1 + (purchasedP0 * [price0] of producer 0)))
let daRatioS1 (valueP1 / (1 + (purchasedP1 * [price0] of producer 0)))
if (daRatioS0 = 0 and daRatioS1 = 0)
  [report -1]

; One option is to make switching an absolute thing.
; Go with the best value per buck supplier of product 0:
let p0 ([value0] of producer FocalSupplier / [price0] of producer FocalSupplier)
let p1 ([value0] of producer OtherSupplier / [price0] of producer OtherSupplier)
if (SwitchingPolicy = "Absolute on value0 / price0")
 [ifelse (p0 > p1)
  [report 1]
  [report 0]
 ]
; Here, below, is the option used in the default setting.
; daProb is the probability of focusing on supplier 0.
; From above, p0 is the value/price ratio for producer 0
; of product 0, p1 is the value/price ratio for producer 1
; of product 0. The code, above, to create these values was:
; let p0 ([value0] of producer 0 / [price0] of producer 0)
; let p1 ([value0] of producer 1 / [price0] of producer 1)
if (SwitchingPolicy = "Boltzman on value / price")
  [let daProb (1 + exp(-1 * (p0 - p1) * 10 / BoltzmanFactor-Used)) ^ -1
   report daProb]

if (SwitchingPolicy = "Boltzman on purchased value / price")
  [let daRawRatio (daRatioS0 / (daRatioS0 + daRatioS1))
   let daProb (1 + exp(-1 * (daRawRatio - 0.5) * BoltzmanFactor-Used)) ^ -1
   report daProb]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;  PlotFocalSuppliers  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to PlotFocalSuppliers
  set-current-plot "Focal Suppliers"
  foreach ProducerWhos [
   let DaGuy (min (list ? 6) )
   set-current-plot-pen (word "producer" DaGuy)
   plot-pen-down
   plot count customers with [focalsupplier = DaGuy]
  ]
end  ; of to PlotFocalSuppliers

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;  PlotRetainedEarnings  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to PlotRetainedEarnings
  set-current-plot "Retained Earnings"
  foreach ProducerWhos [
   let DaGuy (min (list ? 6) )
   set-current-plot-pen (word "producer" DaGuy)
   plot-pen-down
   plot [retainedEarnings] of producer  DaGuy
  ]
end  ; of to PlotRetainedEarnings

to PlotProduct0Values
  set-current-plot "Producer Product 0 Values"
  set-current-plot-pen "producer0"
  plot-pen-down
  plot [value0] of producer 0
  set-current-plot-pen "producer1"
  plot-pen-down
  plot [value0] of producer 1
end  ; of to PlotProduct0Values

to SetInterfaceCaseValues ; SetDefaultValues
  ;;;;;;;;;; Run parameters ;;;;;;;;;;;;;;;;;;;;
  set NumberOfReplications 100 ; The number of times the
  ; basic program is executed per fixed setting of the 
  ; parameters. The default number for serious experiments is
  ; 100.
  set RandomNumberSeed "System Clock" ; Use this value to seed
  ; the (pseudo)random number generator for the run.
  set Logging? false ; Turn logging of data on or off.
  set EpisodesPerRun 250 ; The number of episodes or ticks per run.
  ; Parameter values are fixed during a run, but there may be many
  ; replications (above) and during each replication there may be
  ; many runs as the parameter values are varied.
  ;set RunType "Fixed Parameters"
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;;;;;;;;; Model parameters. Initialization & setup ;;;;;;;;;;;;;;;;;;
  ;set InitialProbOfProducer0Focus 0.5  ; Customers at initialization
  ; have a focus on either producer firm 0 or firm 1. This is the probability a
  ; customer at initialization has a focus on firm 0.
  set AmbidexterityCostMultiplier 1.5 ; Investment costs are multiplied by
  ; this value for ambidextrous firms, that is firms
  set InitialDemand0 5 ; Starting demand per agent for product 0
  set InitialDemand1 5 ; Starting demand per agent for product 1
  set epsilon 0.05 ; During each episode (tick), each customer first approaches
  ; its focal supplier with probability (1-epsilon) and its other supplier with
  ; probability epsilon.  
  set CustomerEpochLengthLow 20 ; Customers have epoch lengths, measured in
  set CustomerEpochLengthHigh 50 ; episodes (or ticks), that vary uniformly 
  ; between CustomerEpochLengthLow and CustomerEpochLengthHigh
  set NumberOfCustomers 120 ; The number of customer agents  
  set SwitchingPolicy "Boltzman on value / price" ; See to-report ProbabilitySupplier0. ...
  set BoltzmanFactor 6.0 ; At the end of a customer's epoch it reconsiders its focal
  ; supplier. In doing so, it considers what values it received at what prices from
  ; its (two) suppliers. These parameters determine the probability of choosing the
  ; performing better or worse supplier.
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ; Now parameters for incremental investments:
  set ProbSuccessIncrementalInvestment 0.20 ; Probability that an incremental 
  ; investment yields success
  set IncrementalInvestmentCost 700 ; Cost of an incremental investment
  set MaturationEpisodesIncrementalInvestment 20 ; Number of periods (episodes)
  ; for an incremental investment project to finish, at which time it is 
  ; either successful, with probability ProbSuccessIncrementalInvestment,
  ; or it fails.
  set MaxSimultaneousProjects 5 ; The maximum number of simultaneous 
  ; incremental projects that may be undertaken by a firm.
  set IncrementalLimit 6 ; The maximum total number of 
  ; increment projects that may be undertaken by a firm.
  set IncrementalProjectValueIncrement 2 ; When an incremental
  ; investment project is successful, the amount by which the
  ; value of its product 0 is incremented.
  set IncrementalProjectCostIncrement 2 ; When an incremental
  ; investment project is successful, the amount by which the
  ; cost of its product 0 is decremented.
  ; Below:
  ; Firms may use incremental improvements to reduce costs
  ; or to increase values of their products. By default
  ; they reduce costs when incremental projects are successful.
  set LocusOfIncrementalImprovementFirm0 "Cost" 
  set LocusOfIncrementalImprovementFirm1 "Cost"
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  set RetainedEarningsMultiplier 3 ; An investment project may 
  ; be undertaken only if its cost times RetainedEarningsMultiplier
  ; is less than or equal to its retained earnings.
  ;;;;;;;;;;;; Now parameters for radical investments:;;;;;;;
  set RadicalLimit 20 ; The maximum number of radical projects that
  ; a firm may invest in
  set RadicalInvestmentCost 7000 ; The investment cost for one
  ; radical project
  set ProbSuccessRadicalInvestment 0.05 ; The probability that
  ; a radical investment project yields success
  set MaturationEpisodesRadicalInvestment 30 ; Number of periods (episodes)
  ; for a radical investment project to finish, at which time it is 
  ; either successful, with probability ProbSuccessRadicalInvestment,
  ; or it fails.
  set RadicalProductionLimit 500 ; The number of units of 
  ; product 1 a firm may product in one period (episode), given
  ; that it has made a successful investment in a radical project
  ; and so has made the discovery.
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;;;;;;;;;;; Sequential Ambidexterity strategy parameters ;;
  set SequentialIncrementalEpochLength 50
  set SequentialRadicalEpochLength 50
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;;;;;;;;;;; Initial production values ;;;;;;;;;;;;;;;;;;;;
  set P0P1IP 0 ; Producer 0 Product 1 Initial Production
  set P1P1IP 0 ; Producer 1 Product 1 Initial Production
  set P0P1IV 50 ; Producer 0 Product 1 Initial Value
  set P1P1IV 50 ; Producer 1 Product 1 Initial Value
  set P0P1IPrice 50 ; Producer 0 Product 1 Initial Price
  set P1P1IPrice 50 ; Producer 1 Product 1 Initial Price
  set P0P1UC 40 ; Producer 0 Product 1 Unit Cost
  set P1P1UC 40 ; Producer 1 Product 1 Unit Cost
  
 if (StoredInterfaceCases = "Base Case")
  [set Producer0Product0InitialProduction 1000
  set Producer1Product0InitialProduction  1000
  set InitialProduct0Producer0UnitCost 49
  set InitialProduct0Producer1UnitCost 49
  set Producer0InitialPrice0 50
  set Producer1InitialPrice0 50
  set Producer0Product0InitialValue 50
  set Producer1Product0InitialValue 50
  set StrategyFirm0 "No Investment"
  set StrategyFirm1 "No Investment"


  ] ; end of if (DefaultValues = "Base Case")
;;;;;;;;;;;;;;;;;;;;;;;;;; Base Calibration Case ;;;;;;;;;;;;;;;
 if (StoredInterfaceCases = "Base Calibration Case")
  [set EpisodesPerRun 780
    set NumberOfReplications 50
  set EarningsOnHand 60000
  set Producer0Product0InitialProduction 1000
  set Producer1Product0InitialProduction  1000
  set InitialProduct0Producer0UnitCost 49
  set InitialProduct0Producer1UnitCost 49
  set Producer0InitialPrice0 50
  set Producer1InitialPrice0 50
  set Producer0Product0InitialValue 50
  set Producer1Product0InitialValue 50
  set StrategyFirm0 "No Investment"
  set StrategyFirm1 "No Investment"
  ; Now parameters for incremental investments:
  set ProbSuccessIncrementalInvestment 0.85 ; Probability that an incremental 
  ; investment yields success
  set IncrementalInvestmentCost 15000 ; Cost of an incremental investment
  set MaturationEpisodesIncrementalInvestment 46 ; Number of periods (episodes)
  ; for an incremental investment project to finish, at which time it is 
  ; either successful, with probability ProbSuccessIncrementalInvestment,
  ; or it fails.
  set MaxSimultaneousProjects 5 ; The maximum number of simultaneous 
  ; incremental projects that may be undertaken by a firm.
  set IncrementalLimit 6 ; The maximum total number of 
  ; increment projects that may be undertaken by a firm.
  set IncrementalProjectValueIncrement 2 ; When an incremental
  ; investment project is successful, the amount by which the
  ; value of its product 0 is incremented.
  set IncrementalProjectCostIncrement 1.0 ; When an incremental
  ; investment project is successful, the amount by which the
  ; cost of its product 0 is decremented.
  ; Below:
  ; Firms may use incremental improvements to reduce costs
  ; or to increase values of their products. By default
  ; they reduce costs when incremental projects are successful.
  set LocusOfIncrementalImprovementFirm0 "Cost" 
  set LocusOfIncrementalImprovementFirm1 "Cost"
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  set RetainedEarningsMultiplier 1 ; An investment project may 
  ; be undertaken only if its cost times RetainedEarningsMultiplier
  ; is less than or equal to its retained earnings.
  ;;;;;;;;;;;; Now parameters for radical investments:;;;;;;;
  set RadicalLimit 20 ; The maximum number of radical projects that
  ; a firm may invest in
  set RadicalInvestmentCost 50000 ; The investment cost for one
  ; radical project
  set ProbSuccessRadicalInvestment 0.08 ; The probability that
  ; a radical investment project yields success
  set MaturationEpisodesRadicalInvestment 104 ; Number of periods (episodes)
  ; for a radical investment project to finish, at which time it is 
  ; either successful, with probability ProbSuccessRadicalInvestment,
  ; or it fails.
  set RadicalProductionLimit 500 ; The number of units of 
  ; product 1 a firm may product in one period (episode), given
  ; that it has made a successful investment in a radical project
  ; and so has made the discovery.
  ] ; end of if (StoredInterfaceCases = "Base Calibration Case")
  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 if (StoredInterfaceCases = "Base Case, Scaled 1")
  [set Producer0Product0InitialProduction 4000
  set Producer1Product0InitialProduction  4000
  set InitialProduct0Producer0UnitCost 49
  set InitialProduct0Producer1UnitCost 49
  set Producer0InitialPrice0 50
  set Producer1InitialPrice0 50
  set Producer0Product0InitialValue 50
  set Producer1Product0InitialValue 50
  set StrategyFirm0 "No Investment"
  set StrategyFirm1 "No Investment"
  set InitialDemand0 20 ; Starting demand per agent for product 0
  set InitialDemand1 10 ; Starting demand per agent for product 1
  ] ; end of if (DefaultValues = "Base Case, Scaled 1")
end 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;; CreateAndInitializeProducers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to CreateAndInitializeProducers
  if (InstantiateCases = "From the Interface tab" and NumberOfProducers = 2) [
   create-producers NumberOfProducers
   set NumProducers NumberOfProducers ; for Internal purposes
   ask producer 0 
     [setxy random-pxcor random-pycor ;ycor 12
      set color (10 * [who] of self) + 5 ;
      set supply0 Producer0Product0InitialProduction-Used
      set price0 Producer0InitialPrice0
      set unitCost0 InitialProduct0Producer0UnitCost
      set product0production Producer0Product0InitialProduction-Used
      set value0 Producer0Product0InitialValue 
      set supply1 0
      set price1 P0P1IPrice
      set unitCost1 P0P1UC
      set product1production P1P1IP
      set value1 P0P1IV
      set LocusOfIncrementalImprovement LocusOfIncrementalImprovementFirm0
     ]
   ask producer 1 
     [setxy random-pxcor random-pycor ;set ycor -9 
      set color (10 * [who] of self) + 5 ;producer1Color ;45
      set supply0 Producer1Product0InitialProduction-Used
      set price0 Producer1InitialPrice0
      set unitCost0 InitialProduct0Producer1UnitCost
      set product0production Producer1Product0InitialProduction-Used
      set value0 Producer1Product0InitialValue
      set supply1 0
      set price1 P1P1IPrice
      set unitCost1 P1P1UC
      set product1production P1P1IP
      set value1 P1P1IV
      set LocusOfIncrementalImprovement LocusOfIncrementalImprovementFirm1
     ]    
   ask producers 
     [set shape "house"
      set size 4
      set netsales0 0
      set incrementalProjMaturation []
      set radicalProjMaturation []
      set strategy runresult (word "StrategyFirm" [who] of self)
      set retainedEarnings EarningsOnHand
      set countOfIncrementalInvestments 0
      set countOfRadicalInvestments 0
      set countOfSuccessfulRadicalInvestments 0
      set totalSales0 0
      set totalSales1 0
      set endIncrementalMode -1 ; nothing scheduled
      set endRadicalMode -1 ; nothing scheduled
      if (strategy = "Sequential Ambidexterity")
        [set endIncrementalMode SequentialIncrementalEpochLength]
     ] ; end of ask producers
   ] ; end of if (InstantiateCases = "From the Interface tab" and NumberOfProducers = 2)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if (InstantiateCases = "Six Producer Case 1") [
   set NumProducers 6
   create-producers NumProducers
   ask producers 
     [setxy random-pxcor random-pycor ;ycor 12
      set color (10 * [who] of self) + 5 ;
      set supply0 Producer0Product0InitialProduction-Used
      set price0 Producer0InitialPrice0
      set unitCost0 InitialProduct0Producer0UnitCost
      set product0production Producer0Product0InitialProduction-Used
      set value0 Producer0Product0InitialValue 
      set supply1 0
      set price1 P0P1IPrice
      set unitCost1 P0P1UC
      set product1production P1P1IP
      set value1 P0P1IV
      set LocusOfIncrementalImprovement LocusOfIncrementalImprovementFirm0
      ;;;;;;;;;
      set shape "house"
      set size 4
      set netsales0 0
      set incrementalProjMaturation []
      set radicalProjMaturation []
      ;set strategy runresult (word "StrategyFirm" [who] of self)
      set retainedEarnings 0
      set countOfIncrementalInvestments 0
      set countOfRadicalInvestments 0
      set countOfSuccessfulRadicalInvestments 0
      set totalSales0 0
      set totalSales1 0
      set endIncrementalMode -1 ; nothing scheduled
      set endRadicalMode -1 ; nothing scheduled
      if (strategy = "Sequential Ambidexterity")
        [set endIncrementalMode SequentialIncrementalEpochLength]
     ]   
     ask producers [set Strategy "No Investment"]
     ask producer 1 [set Strategy "Max Incremental Investment Limited"]
     ask producer 2 [set Strategy "Max Incremental Limited & Radical Investment Limited"]
 
] ; end of if (InstantiateCases = "Three Producer Case 1")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if (InstantiateCases = "Base Case, All 7 Strategies") [
   ;print (word "Hello from Base Case, All 7 Strategies")
   set NumProducers 7   
   create-producers NumProducers
   ask producers 
     [setxy random-pxcor random-pycor ;ycor 12
      set color (10 * [who] of self) + 5 ;
      set supply0 Producer0Product0InitialProduction-Used
      set price0 Producer0InitialPrice0
      set unitCost0 InitialProduct0Producer0UnitCost
      set product0production Producer0Product0InitialProduction-Used
      set value0 Producer0Product0InitialValue 
      set supply1 0
      set price1 P0P1IPrice
      set unitCost1 P0P1UC
      set product1production P1P1IP
      set value1 P0P1IV
      set LocusOfIncrementalImprovement LocusOfIncrementalImprovementFirm0
      ;;;;;;;;;
      set shape "house"
      set size 4
      set netsales0 0
      set incrementalProjMaturation []
      set radicalProjMaturation []
      ;set strategy runresult (word "StrategyFirm" [who] of self)
      set retainedEarnings 0
      set countOfIncrementalInvestments 0
      set countOfRadicalInvestments 0
      set countOfSuccessfulRadicalInvestments 0
      set totalSales0 0
      set totalSales1 0
      set endIncrementalMode -1 ; nothing scheduled
      set endRadicalMode -1 ; nothing scheduled
;      if (strategy = "Sequential Ambidexterity")
;        [set endIncrementalMode SequentialIncrementalEpochLength]
     ]   
     set NumCustomers-Used round (count producers *  NumCustomers-Used / 2) ;60
     ask producers [set LocusOfIncrementalImprovement "Cost"]
     ; A:
     ask producer 0 [set Strategy "No Investment"]
     ; B:
     ask producer 1 [set Strategy "Max Incremental Investment Limited"
                     set LocusOfIncrementalImprovement "Value"]  
     ; C: 
     ask producer 2 [set Strategy "Max Incremental Investment Limited"
                     set LocusOfIncrementalImprovement "Cost"]
     ; D: 
     ask producer 3 [set Strategy "Max Radical Investment Limited"
                     set LocusOfIncrementalImprovement "Cost"]
     ; E:
     ask producer 4 [set Strategy "Max Incremental Limited & Radical Investment Limited"
                     set LocusOfIncrementalImprovement "Value"]
     ; F:
     ask producer 5 [set Strategy "Max Incremental Limited & Radical Investment Limited"
                     set LocusOfIncrementalImprovement "Cost"]
     ; G:
     ask producer 6 [set Strategy "Sequential Ambidexterity"
                     set LocusOfIncrementalImprovement "Cost"]
   
     ask producers [if (Strategy = "Sequential Ambidexterity")
        [set endIncrementalMode SequentialIncrementalEpochLength] ]
] ; end of if (InstantiateCases = "Base Case, All 7 Strategies")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if (InstantiateCases = "Base Case, Strategies C, F, G") [
   set NumProducers 3   
   create-producers NumProducers
   ask producers 
     [setxy random-pxcor random-pycor ;ycor 12
      set color (10 * [who] of self) + 5 ;
      set supply0 Producer0Product0InitialProduction-Used
      set price0 Producer0InitialPrice0
      set unitCost0 InitialProduct0Producer0UnitCost
      set product0production Producer0Product0InitialProduction-Used
      set value0 Producer0Product0InitialValue 
      set supply1 0
      set price1 P0P1IPrice
      set unitCost1 P0P1UC
      set product1production P1P1IP
      set value1 P0P1IV
      set LocusOfIncrementalImprovement LocusOfIncrementalImprovementFirm0
      ;;;;;;;;;
      set shape "house"
      set size 4
      set netsales0 0
      set incrementalProjMaturation []
      set radicalProjMaturation []
      ;set strategy runresult (word "StrategyFirm" [who] of self)
      set retainedEarnings 0
      set countOfIncrementalInvestments 0
      set countOfRadicalInvestments 0
      set countOfSuccessfulRadicalInvestments 0
      set totalSales0 0
      set totalSales1 0
      set endIncrementalMode -1 ; nothing scheduled
      set endRadicalMode -1 ; nothing scheduled
;      if (strategy = "Sequential Ambidexterity")
;        [set endIncrementalMode SequentialIncrementalEpochLength]
     ]   
     set NumberOfCustomers 60 * count producers
     ask producers [set LocusOfIncrementalImprovement "Cost"]
;     ; A:
;     ask producer 0 [set Strategy "No Investment"]
;     ; B:
;     ask producer 1 [set Strategy "Max Incremental Investment Limited"
;                     set LocusOfIncrementalImprovement "Value"]  
     ; C: 
     ask producer 0 [set Strategy "Max Incremental Investment Limited"
;                     set LocusOfIncrementalImprovement "Cost"]
;     ; D: 
;     ask producer 3 [set Strategy "Max Radical Investment Limited"
;                     set LocusOfIncrementalImprovement "Cost"]
;     ; E:
;     ask producer 4 [set Strategy "Max Incremental Limited & Radical Investment Limited"
;                     set LocusOfIncrementalImprovement "Value"]
     ; F:
     ask producer 1 [set Strategy "Max Incremental Limited & Radical Investment Limited"
                     set LocusOfIncrementalImprovement "Cost"]
     ; G:
     ask producer 2 [set Strategy "Sequential Ambidexterity"
                     set LocusOfIncrementalImprovement "Cost"]
   
     ask producers [if (Strategy = "Sequential Ambidexterity")
        [set endIncrementalMode SequentialIncrementalEpochLength] ]
     ] ; end of if (InstantiateCases = "Base Case, Strategies C, F, G")
]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if (InstantiateCases = "Base Calibration Case, All 7 Strategies") [
   ;print(word "yo!")
   set NumProducers 7   
   create-producers NumProducers
   ask producers 
     [setxy random-pxcor random-pycor ;ycor 12
      set color (10 * [who] of self) + 5 ;
      set supply0 Producer0Product0InitialProduction-Used
      set price0 Producer0InitialPrice0
      set unitCost0 InitialProduct0Producer0UnitCost
      set product0production Producer0Product0InitialProduction-Used
      set value0 Producer0Product0InitialValue 
      set supply1 0
      set price1 P0P1IPrice
      set unitCost1 P0P1UC
      set product1production P1P1IP
      set value1 P0P1IV
      set LocusOfIncrementalImprovement LocusOfIncrementalImprovementFirm0
      ;;;;;;;;;
      set shape "house"
      set size 4
      set netsales0 0
      set incrementalProjMaturation []
      set radicalProjMaturation []
      ;set strategy runresult (word "StrategyFirm" [who] of self)
      set retainedEarnings 0
      set countOfIncrementalInvestments 0
      set countOfRadicalInvestments 0
      set countOfSuccessfulRadicalInvestments 0
      set totalSales0 0
      set totalSales1 0
      set endIncrementalMode -1 ; nothing scheduled
      set endRadicalMode -1 ; nothing scheduled
;      if (strategy = "Sequential Ambidexterity")
;        [set endIncrementalMode SequentialIncrementalEpochLength]
     ]   
     ; Note: 2011-10-13: I think there's an error here! So I fixed it.
     set NumCustomers-Used count producers * 60 ;round (count producers *  NumCustomers-Used / 2) ;60
     ask producers [set LocusOfIncrementalImprovement "Cost"]
     ; A:
     ask producer 0 [set Strategy "No Investment"]
     ; B:
     ask producer 1 [set Strategy "Max Incremental Investment Limited"
                     set LocusOfIncrementalImprovement "Value"]  
     ; C: 
     ask producer 2 [set Strategy "Max Incremental Investment Limited"
                     set LocusOfIncrementalImprovement "Cost"]
     ; D: 
     ask producer 3 [set Strategy "Max Radical Investment Limited"
                     set LocusOfIncrementalImprovement "Cost"]
     ; E:
     ask producer 4 [set Strategy "Max Incremental Limited & Radical Investment Limited"
                     set LocusOfIncrementalImprovement "Value"]
     ; F:
     ask producer 5 [set Strategy "Max Incremental Limited & Radical Investment Limited"
                     set LocusOfIncrementalImprovement "Cost"]
     ; G:
     ask producer 6 [set Strategy "Sequential Ambidexterity"
                     set LocusOfIncrementalImprovement "Cost"]
   
     ask producers [if (Strategy = "Sequential Ambidexterity")
        [set endIncrementalMode SequentialIncrementalEpochLength] ]
] ; end of if (InstantiateCases = "Base Calibration Case, All 7 Strategies")     

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; "Base Case, Strategies C, F, G"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if (InstantiateCases = "Base Calibration Case, Strategies C, F, G") [
  ;print (word "yo! from Base Calibration Case, Strategies C, F, G")
   set NumProducers 3   
   create-producers NumProducers
   ask producers 
     [setxy random-pxcor random-pycor ;ycor 12
      set color (10 * [who] of self) + 5 ;
      set supply0 Producer0Product0InitialProduction-Used
      set price0 Producer0InitialPrice0
      set unitCost0 InitialProduct0Producer0UnitCost
      set product0production Producer0Product0InitialProduction-Used
      set value0 Producer0Product0InitialValue 
      set supply1 0
      set price1 P0P1IPrice
      set unitCost1 P0P1UC
      set product1production P1P1IP
      set value1 P0P1IV
      set LocusOfIncrementalImprovement LocusOfIncrementalImprovementFirm0
      ;;;;;;;;;
      set shape "house"
      set size 4
      set netsales0 0
      set incrementalProjMaturation []
      set radicalProjMaturation []
      ;set strategy runresult (word "StrategyFirm" [who] of self)
      set retainedEarnings 0
      set countOfIncrementalInvestments 0
      set countOfRadicalInvestments 0
      set countOfSuccessfulRadicalInvestments 0
      set totalSales0 0
      set totalSales1 0
      set endIncrementalMode -1 ; nothing scheduled
      set endRadicalMode -1 ; nothing scheduled
;      if (strategy = "Sequential Ambidexterity")
;        [set endIncrementalMode SequentialIncrementalEpochLength]
     ]   
     set NumberOfCustomers 60 * count producers
     ask producers [set LocusOfIncrementalImprovement "Cost"]
;     ; A:
;     ask producer 0 [set Strategy "No Investment"]
;     ; B:
;     ask producer 1 [set Strategy "Max Incremental Investment Limited"
;                     set LocusOfIncrementalImprovement "Value"]  
     ; C: 
     ask producer 0 [set Strategy "Max Incremental Investment Limited"
;                     set LocusOfIncrementalImprovement "Cost"]
;     ; D: 
;     ask producer 3 [set Strategy "Max Radical Investment Limited"
;                     set LocusOfIncrementalImprovement "Cost"]
;     ; E:
;     ask producer 4 [set Strategy "Max Incremental Limited & Radical Investment Limited"
;                     set LocusOfIncrementalImprovement "Value"]
     ; F:
     ask producer 1 [set Strategy "Max Incremental Limited & Radical Investment Limited"
                     set LocusOfIncrementalImprovement "Cost"]
     ; G:
     ask producer 2 [set Strategy "Sequential Ambidexterity"
                     set LocusOfIncrementalImprovement "Cost"]
   
     ask producers [if (Strategy = "Sequential Ambidexterity")
        [set endIncrementalMode SequentialIncrementalEpochLength] ]
     ] ; end of if (InstantiateCases = "Base Case, Strategies C, F, G")
]


;;;;;;;;;;;;;;;;;;;;;;;;;;;
  set ProducerWhos n-values NumProducers [?]
end  ; of to CreateAndInitializeProducers

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;; CreateAndInitializeCustomers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to CreateAndInitializeCustomers
;; We can specify them just from the Interface tab!
;     set NumCustomers-Fixed NumberOfCustomers
;     set NumCustomers NumCustomers-Fixed
;     if (Perturbing?) [
;         let Perturbance (random-float 2 * NumCustomers-Fixed * PerturbancePercent)
;         set NumCustomers (1 - PerturbancePercent) * NumCustomers-Fixed + Perturbance
;         set NumCustomers max (list 0 NumCustomers)
;         set NumCustomers round NumCustomers
;     ]

     set Demand0-Fixed InitialDemand0
     set Demand0-Used Demand0-Fixed
     set Demand1-Fixed InitialDemand1
     set Demand1-Used InitialDemand1
     if (Perturbing?) [
         let Perturbance (random-float 2 * Demand0-Fixed * PerturbancePercent)
         set Demand0-Used (1 - PerturbancePercent) * Demand0-Fixed + Perturbance
         set Demand0-Used max (list 0 Demand0-Used)
         set Demand0-Used round Demand0-Used

         set Perturbance (random-float 2 * Demand1-Fixed * PerturbancePercent)
         set Demand1-Used (1 - PerturbancePercent) * Demand1-Fixed + Perturbance
         set Demand1-Used max (list 0 Demand1-Used)
         set Demand1-Used round Demand1-Used   
     ]     
  
     create-customers NumCustomers-Used
     ; Get a list of the who's of the producers:
     let ProducerIDs n-values NumProducers [?]
     ask customers 
       [setxy random-pxcor random-pycor
        let MyGuy one-of ProducerIDs
        set color ([color] of producer MyGuy)
        set FocalSupplier MyGuy
        set OtherSupplier one-of remove-item MyGuy ProducerIDs
        set demand0 Demand0-Used ; InitialDemand0
        ;print (word "Demand0-Used=" demand0-used " Demand0=" demand0 " who=" who " ticks=" ticks)
        set purchasedProduct0Producer0 0
        set purchasedProduct0Producer1 0
        set value0Producer0 0 
        set value0Producer1 0
        set demand1 Demand1-Used ;InitialDemand1
        set purchasedProduct1Producer0 0
        set purchasedProduct1Producer1 0
        set value1Producer0 0 
        set value1Producer1 0
        set epochLength (random (CustomerEpochLengthHigh - CustomerEpochLengthLow)) + CustomerEpochLengthLow
       ]
;     ]  ; end of if (InstantiateCases = "From the Interface tab" and NumberOfProducers = 2)
end  ; of to CreateAndInitializeCustomers

to CreateProducerLogFile
;  if (file-exists? "AmbidexterityProducerLogFile.txt")
;     [file-close
;      file-delete "AmbidexterityProducerLogFile.txt"]
  file-open "AmbidexterityProducerLogFile.txt"
  file-print (word "**************************************")
  file-print (word  "RunID='" RunID "'")
  file-print (word "**************************************")
  ask producers [
    file-print (word "*********** Producer " who " *****************")
    file-print (word "Supply0=" Supply0 ", Price0=" Price0 ", Value0=" Value0 ", UnitCost0=" UnitCost0 ", NetSales0=" NetSales0 ", Product0Production=" Product0Production)
    file-print (word "Supply1=" Supply1 ", Price1=" Price1 ", Value1=" Value1 ", UnitCost1=" UnitCost1 ", NetSales1=" NetSales1 ", Product1Production=" Product1Production)
    file-print (word "LocusOfIncrementalImprovement=" LocusOfIncrementalImprovement ", IncrementalProjMaturation=" IncrementalProjMaturation ", RadicalProjMaturation=" radicalProjMaturation)
    file-print (word "Strategy=" Strategy ", RetainedEarnings=" RetainedEarnings)
    file-print (word "CountOfIncrementalInvestments=" CountOfIncrementalInvestments ", CountOfRadicalInvestments=" CountOfRadicalInvestments ", CountOfSuccessfulRadicalInvestments=" CountOfSuccessfulRadicalInvestments)
    file-print (word "TotalSales0=" TotalSales0 ", TotalSales1=" TotalSales1)
    file-print (word "EndIncrementalMode=" EndIncrementalMode ", EndRadicalMode=" EndRadicalMode)
  ]

  file-close
end 

to CreateCustomerLogFile
  ; Picks a random customer and prints out its attribute values.
;  if (file-exists? "AmbidexterityCustomerLogFile.txt")
;     [file-close
;      file-delete "AmbidexterityCustomerLogFile.txt"]
  file-open "AmbidexterityCustomerLogFile.txt"
  file-print (word "**************************************")
  file-print (word  "RunID='" RunID "'")
  file-print (word "**************************************")
  let DaGuy one-of customers
  ask  DaGuy [
    file-print (word "*********** Customer " who " *****************")
    file-print (word "FocalSupplier=" FocalSupplier ", OtherSupplier=" OtherSupplier)
    file-print (word "Demand0=" Demand0 ", PurchasedProduct0Producer0=" PurchasedProduct0Producer0 ", PurchasedProduct0Producer1=" PurchasedProduct0Producer1
        ", Value0Producer0=" Value0Producer0 ", Value0Producer1=" Value0Producer1)
    file-print (word "Demand1=" Demand1 ", PurchasedProduct1Producer0=" PurchasedProduct1Producer0 ", PurchasedProduct1Producer1=" PurchasedProduct1Producer1
        ", Value1Producer0=" Value1Producer0 ", Value1Producer1=" Value1Producer1)
    file-print (word "EpochLength=" EpochLength)
  ]
  file-close
end 

to CreateRunsOutFileHeader
  ; If we are logging, delete the current log file if it exists.
  if (file-exists? "AmbidexterityRunsOutput.txt")
   [file-close
    file-delete "AmbidexterityRunsOutput.txt"]
;  if (Logging?) [
  ; Open, by creating, the log file, runsOutput.txt 
  file-open "AmbidexterityRunsOutput.txt"
  
  let fileheader (word  "RunID"  ",")
  foreach ProducerWhos [
    set FileHeader (word FileHeader "RetainedEarningsProducer" ? ",")
  ]
  ;set fileHeader (word "retainedEarningsproducer0" "," "retainedEarningsproducer1")
  foreach ProducerWhos [
    set FileHeader (word FileHeader "CountOfRadicalInvestmentsProducer" ? ",")
  ]
  ;set fileHeader (word fileHeader "," "countOfRadicalInvestmentsproducer0" "," "countOfRadicalInvestmentsproducer1")
  foreach ProducerWhos [
    set FileHeader (word FileHeader "CountOfSuccessfulRadicalInvestmentsProducer" ? ",")
  ]
  ;set fileHeader (word fileHeader "," "countOfSuccessfulRadicalInvestmentsProducer0" "," "countOfSuccessfulRadicalInvestmentsProducer1")
  foreach ProducerWhos [
    set FileHeader (word FileHeader "CountOfIncrementalInvestmentsproducer" ? ",")
  ]
  ;set fileHeader (word fileHeader "," "countOfIncrementalInvestmentsproducer0" "," "countOfIncrementcalInvestmentsproducer1")
  set fileHeader (word fileHeader  "ReplicationNumber,EpisodesPerRun,RandomNumberSeed,RumberOfReplications,")
  foreach ProducerWhos [
    set FileHeader (word FileHeader "CustomerCountOfProducer" ? ",")
  ]
  ;set fileHeader (word fileHeader "," "replicationNumber,EpisodesPerRun,RandomNumberSeed,numberOfReplications,firm0customers,firm1customers")
  foreach ProducerWhos [
    set FileHeader (word FileHeader "StrategyOfProducer" ? ",")
  ]
  foreach ProducerWhos [
    set FileHeader (word FileHeader "LocusOfIncrementalImprovementOfProducer" ? ",")
  ]
  ;set fileHeader (word fileHeader ",StrategyFirm0,StrategyFirm1,LocusOfIncrementalImprovementFirm0,LocusOfIncrementalImprovementFirm1")
  foreach ProducerWhos [
    set FileHeader (word FileHeader "TotalSales1OfProducer" ? ",")
  ]
  set FileHeader (word FileHeader  "NumCustomers-Used,RetainedEarningsMultiplier-Used,BoltzmanFactor-Used,SwitchingPolicy,AmbidexterityCostMultiplier-Used")
  set FileHeader (word FileHeader ",IncrementalProjectCostIncrement,IncrementalProjectValueIncrement,IncrementalInvestmentCost")
  set FileHeader (word FileHeader ",ProbSuccessIncrementalInvestment-Used,MaturationEpisodesIncrementalInvestment,IncrementalLimit")
  set FileHeader (word FileHeader ",MaxSimultaneousProjects,RadicalInvestmentCost,ProbSuccessRadicalInvestment-Used,MaturationEpisodesRadicalInvestment")
  set FileHeader (word FileHeader ",P0P1UC,P1P1UC,P0P1IP,P1P1IP,P0P1IPrice,Demand0-Used,Demand1-Used,P0P1IV,P1P1IV,P1P1IPrice,RadicalLimit")
  set FileHeader (word FileHeader ",RadicalProductionLimit,SequentialIncrementalEpochLength,SequentialRadicalEpochLength,epsilon")
  
  file-print fileHeader
  file-close
;  ] ; end of if (Logging?)
end 

to RecordRunOutput
  file-open "AmbidexterityRunsOutput.txt"
  set StringToPrint (word "'" RunID "'")
  foreach ProducerWhos [
    set StringToPrint (word  StringToPrint "," [RetainedEarnings] of producer ? )
  ]    
    ; [retainedEarnings] of producer 0 "," [retainedEarnings] of producer 1)
  foreach ProducerWhos [
    set StringToPrint (word StringToPrint "," [CountOfRadicalInvestments] of producer ? )
  ] 
   ; set stringToPrint (word stringToPrint  [countOfRadicalInvestments] of producer 0 "," [countOfRadicalInvestments] of producer 1)
  foreach ProducerWhos [
    set StringToPrint (word StringToPrint "," [CountOfSuccessfulRadicalInvestments] of producer ? )
  ] 
  ;  set stringToPrint (word stringToPrint  [countOfSuccessfulRadicalInvestments] of producer 0 "," [countOfSuccessfulRadicalInvestments] of producer 1)
  foreach ProducerWhos [
    set StringToPrint (word StringToPrint "," [CountOfIncrementalInvestments] of producer ? )
  ] 
   ; set stringToPrint (word stringToPrint  [countOfIncrementalInvestments] of producer 0 "," [countOfIncrementalInvestments] of producer 1)
    set stringToPrint (word stringToPrint "," ReplicationsCompleted "," EpisodesPerRun "," RandomNumberSeed "," NumberOfReplications )
  foreach ProducerWhos [
    set StringToPrint (word StringToPrint "," count customers with [color = [color] of producer ?] )
  ] 
   ; set stringToPrint (word stringToPrint "," count customers with [color = [color] of producer 0] "," count customers with [color = [color] of producer 1])
  foreach ProducerWhos [
    set StringToPrint (word StringToPrint "," [Strategy] of producer ? )
  ]    
  foreach ProducerWhos [
    set StringToPrint (word StringToPrint "," [LocusOfIncrementalImprovement] of producer ? )
  ]    
  ;  set stringToPrint (word stringToPrint  StrategyFirm0 "," StrategyFirm1 "," LocusOfIncrementalImprovementFirm0 "," LocusOfIncrementalImprovementFirm1)
  foreach ProducerWhos [
    set StringToPrint (word StringToPrint "," [TotalSales1] of producer ?)
  ]  
  set StringToPrint (word StringToPrint "," NumCustomers-Used "," RetainedEarningsMultiplier-Used "," BoltzmanFactor-Used "," SwitchingPolicy "," AmbidexterityCostMultiplier-Used)   
  set StringToPrint (word StringToPrint "," IncrementalProjectCostIncrement "," IncrementalProjectValueIncrement "," IncrementalInvestmentCost)
  set StringToPrint (word StringToPrint "," ProbSuccessIncrementalInvestment-Used "," MaturationEpisodesIncrementalInvestment "," IncrementalLimit)
  set StringToPrint (word StringToPrint "," MaxSimultaneousProjects "," RadicalInvestmentCost "," ProbSuccessRadicalInvestment-Used "," MaturationEpisodesRadicalInvestment)
  set StringToPrint (word StringToPrint "," P0P1UC "," P1P1UC "," P0P1IP "," P1P1IP "," P0P1IPrice "," Demand0-Used "," Demand1-Used "," P0P1IV "," P1P1IV "," P1P1IPrice "," RadicalLimit)
  set StringToPrint (word StringToPrint "," RadicalProductionLimit "," SequentialIncrementalEpochLength "," SequentialRadicalEpochLength "," epsilon)  
  
  file-print StringToPrint
              
  ;;;;;; close the log file
  file-close   
end 

to RunFromFile
;; Delete the output files, if they exist.
;;if (file-exists? "output.txt")
;;  [file-delete "output.txt"]
;;if (file-exists? "output-summary.txt")
;;  [file-delete "output-summary.txt"]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Print header info for output file
;file-open "output.txt"
;;let daString (word "Row-player-policy,Column-player-policy,NumSessions,Exp-rounds-per-session,YA0,YA1,cA0,cA1,pA0,pA1,qA0,qA1,LA0,LA1," )
;let daString "" ;parameter-headers
;set daString (word daString "Session,Round,RowMove,ColMove,RowRoundPayoff,ColRoundPayoff,RowDirectLoss,RowIndirectLoss,ColDirectLoss,ColIndirectLoss")
; file-print daString
;file-close
;file-open "output-summary.txt"
;set daString (word  "TotalPayoffsOfA0,TotalPayoffsOfA1,")
;set daString (word daString "TotalPayoffsOfA0/TotalRoundsOfA0,TotalPayoffsOfA1/TotalRoundsOfA1,")
;set daString (word daString "MeanSession-payoffsOfA0,MeanSession-payoffsOfA1")
;file-print daString
;; output-print (word "TotalPayoffs of A0, TotalPayoffs of A1, TotalPayoffs of A0/ Total Rounds of A0, TotalPayoffs of A1 / TotalRounds of A1, mean session-payoffs of A0, mean session-payoffs of A1")
;;file-print daString
;file-close
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; open the input file and read its lines into a list
file-open "AmbidexterityInputs.txt"
let dalines []
while [not file-at-end?]
[let dummy file-read-line
 set dalines (lput dummy dalines)
 ]
 print (word "The number of lines is " length dalines)
file-close
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Execute each of the lines in the input file
foreach dalines [
run ? 
]
end 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;; Perturb Parameters ;;;;;;;;;;;;;;;;;;;;
;to PerturbParameters
;  ;;;;;; Customers ;;;;;;;;;;;;;;;;;;;;;;
;  ; NumCustomers
;  let Perturbance (random-float 2 * NumCustomers-Fixed * PerturbancePercent)
;  set NumCustomers (1 - PerturbancePercent) * NumCustomers-Fixed + Perturbance
;  set NumCustomers max (list 0 NumCustomers)
;  set NumCustomers round NumCustomers
;
;
;end

to SetGlobalParameters
; We can specify them just from the Interface tab!
     set NumCustomers-Fixed NumberOfCustomers
     set NumCustomers-Used NumCustomers-Fixed
     if (Perturbing?) [
         let Perturbance (random-float 2 * NumCustomers-Fixed * PerturbancePercent)
         set NumCustomers-Used (1 - PerturbancePercent) * NumCustomers-Fixed + Perturbance
         set NumCustomers-Used max (list 0 NumCustomers-Used)
         set NumCustomers-Used round NumCustomers-Used
     ]
     set RetainedEarningsMultiplier-Fixed RetainedEarningsMultiplier
     set RetainedEarningsMultiplier-Used RetainedEarningsMultiplier-Fixed
     if (Perturbing?) [
         let Perturbance (random-float 2 * RetainedEarningsMultiplier-Fixed * PerturbancePercent)
         set RetainedEarningsMultiplier-Used (1 - PerturbancePercent) * RetainedEarningsMultiplier-Fixed + Perturbance
         set RetainedEarningsMultiplier-Used max (list 0 RetainedEarningsMultiplier-Used)
     ]
   set BoltzmanFactor-Fixed BoltzmanFactor
   set BoltzmanFactor-Used BoltzmanFactor-Fixed
   if (Perturbing?) [
       let Perturbance (random-float 2 * BoltzmanFactor-Fixed * PerturbancePercent)
       set BoltzmanFactor-Used (1 - PerturbancePercent) * BoltzmanFactor-Fixed + Perturbance
       set BoltzmanFactor-Used max (list 0 BoltzmanFactor-Used)
   ]
   set AmbidexterityCostMultiplier-Fixed AmbidexterityCostMultiplier
   set AmbidexterityCostMultiplier-Used AmbidexterityCostMultiplier-Fixed
   if (Perturbing?) [
       let Perturbance (random-float 2 * AmbidexterityCostMultiplier-Fixed * PerturbancePercent)
       set AmbidexterityCostMultiplier-Used (1 - PerturbancePercent) * AmbidexterityCostMultiplier-Fixed + Perturbance
       set AmbidexterityCostMultiplier-Used max (list 0 AmbidexterityCostMultiplier-Used)
   ]
   set Producer0Product0InitialProduction-Fixed Producer0Product0InitialProduction
   set Producer0Product0InitialProduction-Used Producer0Product0InitialProduction-Fixed
   if (Perturbing?) [
       let Perturbance (random-float 2 * Producer0Product0InitialProduction-Fixed * PerturbancePercent)
       set Producer0Product0InitialProduction-Used (1 - PerturbancePercent) * Producer0Product0InitialProduction-Fixed + Perturbance
       set Producer0Product0InitialProduction-Used max (list 0 Producer0Product0InitialProduction-Used)
   ]
   set Producer1Product0InitialProduction-Fixed Producer1Product0InitialProduction
   set Producer1Product0InitialProduction-Used Producer1Product0InitialProduction-Fixed
   if (Perturbing?) [
       let Perturbance (random-float 2 * Producer1Product0InitialProduction-Fixed * PerturbancePercent)
       set Producer1Product0InitialProduction-Used (1 - PerturbancePercent) * Producer1Product0InitialProduction-Fixed + Perturbance
       set Producer1Product0InitialProduction-Used max (list 0 Producer1Product0InitialProduction-Used)
   ]   
   set ProbSuccessIncrementalInvestment-Fixed ProbSuccessIncrementalInvestment
   set ProbSuccessIncrementalInvestment-Used ProbSuccessIncrementalInvestment-Fixed
   if (Perturbing?) [
       let Perturbance (random-float 2 * ProbSuccessIncrementalInvestment-Fixed * PerturbancePercent)
       set ProbSuccessIncrementalInvestment-Used (1 - PerturbancePercent) * ProbSuccessIncrementalInvestment-Fixed + Perturbance
       set ProbSuccessIncrementalInvestment-Used max (list 0 ProbSuccessIncrementalInvestment-Used)
   ]   
   set ProbSuccessRadicalInvestment-Fixed ProbSuccessRadicalInvestment
   set ProbSuccessRadicalInvestment-Used ProbSuccessRadicalInvestment-Fixed
   if (Perturbing?) [
       let Perturbance (random-float 2 * ProbSuccessRadicalInvestment-Fixed * PerturbancePercent)
       set ProbSuccessRadicalInvestment-Used (1 - PerturbancePercent) * ProbSuccessRadicalInvestment-Fixed + Perturbance
       set ProbSuccessRadicalInvestment-Used max (list 0 ProbSuccessRadicalInvestment-Used)
   ]     
end 

to test
;  random-seed 1
;  print random-float 1
;  print random-float 1
;  print random-float 1
movie-start "out.mov"
   movie-grab-interface
   movie-close
end 

There is only one version of this model, created almost 4 years ago by Steven Kimbrough.

Attached files

File Type Description Last updated
Ambidexterity Strategy Explorer.png preview Preview for 'Ambidexterity Strategy Explorer' almost 4 years ago, by Steven Kimbrough Download

This model does not have any ancestors.

This model does not have any descendants.