Book Example: Economic equilibria#
Description: economic model using complementarity conditions from Chapter 19 AMPL book
Tags: ampl-only, ampl-book, finance, complementarity-problem
Notebook author: Marcos Dominguez Velad <marcos@ampl.com>
Model author: N/A
# Install dependencies
%pip install -q amplpy
# Google Colab & Kaggle integration
from amplpy import AMPL, ampl_notebook
ampl = ampl_notebook(
modules=["coin", "gurobi"], # modules to install
license_uuid="default", # license to use
) # instantiate AMPL object and register magics
Economic equilibria#
This model is based on the models showed in the Chapter 19 of the AMPL book, related to complementarity problems.
Classic model#
The following model does not use complementarity conditions.
Sets and parameters:
Products
PROD
anddemand[i]
for each producti
.Activities
ACT
andcost[j]
for each activityj
.Amount of product
i
produced by activityj
,io[i,j]
.
Decision variables
Level[j]
: levels of production activities (for each activityj
).Objective: minimize total production cost,
So the AMPL formulation is implemented as:
%%writefile econmin.mod
set PROD; # products
set ACT; # activities
param cost {ACT} > 0; # cost per unit of each activity
param demand {PROD} >= 0; # units of demand for each product
param io {PROD,ACT} >= 0; # units of each product from
# 1 unit of each activity
var Level {j in ACT} >= 0;
minimize Total_Cost: sum {j in ACT} cost[j] * Level[j];
subject to Demand {i in PROD}:
sum {j in ACT} io[i,j] * Level[j] >= demand[i];
Overwriting econmin.mod
%%writefile econ.dat
data;
param: ACT: cost :=
P1 2450
P1a 1290
P2 1850
P2a 3700
P2b 2150
P3 2200
P3c 2370
P4 2170 ;
param: PROD: demand :=
AA1 70000
AC1 80000
BC1 90000
BC2 70000
NA2 400000
NA3 800000 ;
param io (tr):
AA1 AC1 BC1 BC2 NA2 NA3 :=
P1 60 20 10 15 938 295
P1a 8 0 20 20 1180 770
P2 8 10 15 10 945 440
P2a 40 40 35 10 278 430
P2b 15 35 15 15 1182 315
P3 70 30 15 15 896 400
P3c 25 40 30 30 1029 370
P4 60 20 15 10 1397 450 ;
Overwriting econ.dat
%%ampl_eval
model econmin.mod;
data econ.dat;
option solver cbc;
solve;
display Level;
display Demand.dual;
CBC 2.10.5CBC 2.10.5 optimal, objective 6808640.553
3 iterations
Level [*] :=
P1 0
P1a 1555.3
P2 0
P2a 0
P2b 0
P3 147.465
P3c 1889.4
P4 0
;
Demand.dual [*] :=
AA1 16.7051
AC1 5.44585
BC1 57.818
BC2 0
NA2 0
NA3 0
;
Complementarity model#
Consider the new variables Price[i]
for each product, and solve the problem to find an equilibrium instead of an optimum solution. The equilibrium is subject to two conditions:
First, for each product, total output must meet demand and price must be nonnegative, and in addition there must be a complementarity between these relationships, where production exceeds demand the price must be zero, or equivalently, if the price is positive, the production must equal the demand.
subject to Pri_Compl {i in PROD}:
Price[i] >= 0 complements
sum {j in ACT} io[i,j] * Level[j] >= demand[i];
Second, for each activity
j
, the value of resulting producti
isPrice[i]*io[i,j]
, so activityj
would produce a total value of
When equilibrium happens, the previous value must not exceed the activity’s cost per unit cost[j]
. Moreover, there is a complementarity between this relationship and the level of activity j
, where cost exceeds total value the activity must be zero, or, where the activity cost is positive then the total value must be equal to the cost. This can be expressed as:
subject to Lev_Compl {j in ACT}:
Level[j] >= 0 complements
sum {i in PROD} Price[i] * io[i,j] <= cost[j];
%%writefile econ.mod
set PROD; # products
set ACT; # activities
param cost {ACT} > 0; # cost per unit of each activity
param demand {PROD} >= 0; # units of demand for each product
param io {PROD,ACT} >= 0; # units of each product from
# 1 unit of each activity
var Price {i in PROD};
var Level {j in ACT};
subject to Pri_Compl {i in PROD}:
Price[i] >= 0 complements
sum {j in ACT} io[i,j] * Level[j] >= demand[i];
subject to Lev_Compl {j in ACT}:
Level[j] >= 0 complements
sum {i in PROD} Price[i] * io[i,j] <= cost[j];
Overwriting econ.mod
Remark: the model is square, as there are \(n+m\) variables and \(n+m\) constraints (\(n\) number of products and \(m\) number of activities). Some solvers can take advantage of this to use different solving techniques.
Finally, let’s see that the equilibrium model gives also the optimal solution for the first classic formulation.
%%ampl_eval
reset;
model econ.mod;
data econ.dat;
option solver gurobi;
solve;
# Show total cost
display sum {j in ACT} cost[j] * Level[j];
display Level;
Gurobi 10.0.0:Gurobi 10.0.0: optimal solution
0 simplex iterations
Objective = find a feasible point.
sum{j in ACT} cost[j]*Level[j] = 6808640
Level [*] :=
P1 0
P1a 1555.3
P2 0
P2a 0
P2b 0
P3 147.465
P3c 1889.4
P4 0
;