Skip to content

About

No description, website, or topics provided.

Resources

Stars

7 stars

Watchers

0 watching

Forks

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

Genetic Algorithm — Oligopoly Cournot Competition Simulation

A Python implementation of a Genetic Algorithm (GA) that models evolutionary firm behavior in a Cournot oligopoly market. Firms evolve their production quantities over 1,000 generations and the simulation tests whether decentralized evolutionary learning converges to the theoretical Nash Equilibrium.


Table of Contents


Overview

This project applies a Genetic Algorithm to simulate an oligopolistic market with 24 firms (Cournot competition). Each firm is represented by a 10-bit binary chromosome that encodes its production quantity. Over 1,000 iterations, firms evolve through selection, crossover, and mutation. The goal is to observe whether the population converges to the Cournot-Nash Equilibrium—the production level that no firm has an incentive to deviate from.

Three scenarios are run to analyse the sensitivity of the GA to its operator rates:

Scenario Change
Benchmark Default crossover and mutation rates
High Crossover Crossover rate increased by +0.250
High Mutation Mutation rate increased by +0.00250

Repository Structure

GeneticAlgorithm/
├── geneticAlgorithm.py   # Main simulation code
├── pyproject.toml        # Python project configuration
├── results/              # Generated output plots
│   ├── results_Benchmark.png
│   ├── results_High_Crossover.png
│   └── results_High_Mutation.png
└── README.md

Algorithm Details

Market Model

The simulation uses a linear inverse demand function:

price = alpha - total_Q

where alpha = 1023 is the demand intercept and total_Q is the sum of all firms' outputs. Each firm's profit is:

profit = (price × q_i) - (c × q_i)

where c = 0 is the marginal cost and q_i is firm i's individual output.

Theoretical Cournot-Nash Equilibrium (closed-form solution for n firms):

Q_nash_total  = n / (n + 1) × (alpha - c)  =  24/25 × 1023  ≈  979.44
q_nash_indiv  = Q_nash_total / n            ≈  40.81 per firm

Genetic Encoding

Each firm is represented by a 10-bit binary chromosome. The chromosome is decoded to a production quantity by:

q_i = alpha × (x_it / 2^l)

where x_it is the integer value of the binary string (0 to 1023) and l = 10 is the chromosome length. This maps every chromosome to a quantity in the range [0, alpha].

GA Pipeline

Each generation executes the following four steps:

  1. Selection — Roulette Wheel
    Fitness is equal to profit. Firms with higher profit have a proportionally larger probability of being selected into the mating pool. Negative fitness values are shifted to ensure all probabilities are positive.

  2. Crossover — Single-Point
    Two parents produce two children by swapping tails at a random cut-point k ∈ [1, l-1]. Applied with probability p_cross.

  3. Mutation — Bit-Flip
    Each bit in a child's chromosome is independently flipped with probability p_mut.

  4. Replacement — Elitist Election
    Each child competes against its corresponding parent. The child replaces the parent only if it would earn a higher hypothetical profit when evaluated against the current behaviour of all other firms. This ensures the population never degrades.


Parameters

Parameter Default Description
n 24 Number of firms (population size)
alpha 1023 Demand intercept
c 0 Marginal cost
l 10 Chromosome length in bits
T 1000 Number of generations
Y 1 ID tuning parameter (second-to-last digit)
Z 3 ID tuning parameter (last digit)
p_cross_bench 0.200 + 0.01·Y + 0.001·Z Benchmark crossover probability ≈ 0.213
p_mut_bench 0.00200 + 0.0001·Y + 0.00001·Z Benchmark mutation probability ≈ 0.00203

Scenarios

Scenario p_cross p_mut
Benchmark p_cross_bench p_mut_bench
High Crossover p_cross_bench + 0.250 p_mut_bench
High Mutation p_cross_bench p_mut_bench + 0.00250

Installation

Requirements: Python 3.11 or higher.

Install dependencies:

pip install numpy matplotlib

Usage

python geneticAlgorithm.py

This will run all three scenarios sequentially, print a summary to the console, and save one plot per scenario to the results/ directory.


Expected Output

Console output for each scenario:

--- Running Scenario: Benchmark ---
p_cross: 0.21300, p_mut: 0.00203
Simulation completed!
Final Total Q: <value>
Target Nash Total Q: 979.44
Final Variance: <value>
Saved plot to results/results_Benchmark.png

Saved plots (one per scenario):

Each PNG contains two side-by-side charts:

  • Left — Industry Output Convergence: Total market quantity Q per iteration vs. the theoretical Nash Equilibrium (dashed red line).
  • Right — Population Variance: Variance of individual firm outputs per iteration, showing how much diversity remains in the population.

Results

The results/ directory contains pre-generated plots for each scenario. Below is a summary of what each plot illustrates:

File Description
results_Benchmark.png Baseline convergence with default operator rates
results_High_Crossover.png Effect of significantly increasing the crossover probability
results_High_Mutation.png Effect of significantly increasing the mutation probability

These plots allow direct visual comparison of how different GA operator settings affect the speed and stability of convergence to the Nash Equilibrium.

About

No description, website, or topics provided.

Resources

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages