Matlab | 古诺模型求解及画图代码

Matlab | 古诺模型求解及画图代码

古诺模型

以仅含有两个企业的古诺模型为例,该问题可叙述为:

市场上只有两家企业( 双寡头垄断 ),它们生产销售完全相同的产品,共同面临一条线性的市场需求曲线,各自 决策 能够给自己带来 最大利润 最优产量。

关于古诺模型的更多细节可查看课本或知乎,本文直接给出如下 算例 来展现如何求解。

算例

若市场需求函数为 p = a - b(q1 + q2) ,企业1和2的生产成本函数分别为 c1*q1 c2*q2^2 。求 古诺均衡 ,并 计算利润。

求解思路如下:

  • 构建企业1和2的 利润函数 :价格×产量-成本;
  • 同时对企业1和2的产量 求导 ,令其=0;
  • 联立 两方程,求解 最优q1和q2
  • 将最优q1和q2表达式 代入 利润函数,得到 最优利润

以上四步的数学表达式和Matlab代码如下。

1. 构建企业1、2的利润函数

对应的Matlab代码为:

syms a b q1 q2 c1 c2 % 定义参数/变量
Pi1 = (a - b*(q1 + q2))*q1 - c1*q1;
Pi2 = (a - b*(q1 + q2))*q2 - c2*q2^2;

可见,Matlab代码并不复杂,几乎是照抄公式,只不过所有括号均需要用 小括号 ,这个一定注意。

2. 同时对q1和q2求导,令其=0

对应的Matlab代码为:

equ1 = diff(Pi1, q1);
equ2 = diff(Pi2, q2);

Matlab的求导函数为 diff() diff(Pi1, q1) 的含义为:对利润函数Pi1中的q1变量求一阶导;求出来的算式在这里给起了个名字equ1,该名字好记就行(需符合 命名规范 )。

3. 联立方程,求解最优q1、q2

对应的Matlab代码为(一行足矣):

[Op_q1,Op_q2] = solve(equ1, equ2, q1,q2);

Matlab的解方程函数为 solve() solve(equ1, equ2, q1, q2) 的含义为:联立两方程equ1=0和equ2=0(注:代码中=0可以 省略 ),求解两未知数q1和q2。将求得的最优q1和q2的值分别命名为 Op_q1 Op_q2

对比 手算最优值 ,用Matlab解方程只需要 一行代码 即可,大大节省科研时间。

4. 将最优q1、q2带入利润表达式

若手算,鉴于最优q1和q2表达式的 繁琐 ,带入过程可想而知地 繁琐

可若采用Matlab计算,也仅需要 一行代码

Pi1 = subs(Pi1,{q1,q2}, {Op_q1,Op_q2});
Pi2 = subs(Pi2,{q1,q2}, {Op_q1,Op_q2});

Matlab的替代函数为 subs() subs(Pi1, {q1, q2}, {Op_q1, Op_q2} 的含义为:将 利润函数 Pi1中的q1和q2分别替换为Op_q1和Op_q2的值。

通常, 此时Pi1和Pi2的表达式会非常复杂 ,需借助Matlab的化简函数。常见的有simplify、collect、expand、factor、subexpr、pretty等。

实际上, simplify、collect和pretty 便可满足我们的绝大部分需求。

pretty(Pi1)
pretty(Pi2)

此时,Matlab会返回化简好后的表达式:

即使已经非常简单,但我们还是希望能有更为直观的表现形式。此时 pretty()函数 便派上用场。

pretty(simplify(Pi1))
pretty(simplify(Pi2))

此时,会得到如下呈现形式:

该形式易于抄写,非常直观。

更为方便的是,若 不想将公式手打入Word或Latex中 ,也可以调用Matlab中的latex()命令,将得到的结果复制粘贴到Word或Latex中。

latex(simplify(Pi1))
latex(simplify(Pi2))

以粘贴入Word为例,分以下4步:

至此, 没动一次笔 ,便得到最优产量和利润表达式;同时,实现将表达式准确输入至Word中。

只要是 基于古诺思想的数学模型 ,均可 自动化实现以上求解 。无非就是在第一步的时候,把利润函数改成 自己的研究问题 即可。

画图

可进行的数值分析有:

  • 各企业最优产量(Op_q1和Op_q2)与各参数(a/b/c1/c2)关系图;
  • 比较两企业最优产量的大小,计算市场占有率;
  • 各企业最优利润与各参数关系;
  • 比较两企业利润大小;
  • 考察利润相同下,两个参数间的变化关系等;

这里,仅以第四点为例, 考察c2变化对两企业利润的影响

此时,设a = 100, b = 1, c1 = 15。同时设c2取值范围为0到1,间隔0.03,即 c2 = [0: 0.03: 1]

注意:每一个c2都对应一个Pi1和一个Pi2,为计算所有c2对应的Pi1和Pi2,写一个 循环 即可。

clear
a = 100; b = 1; c1 = 15;
c2 = [0: 0.03: 1];
for i = 1: length(c2)
    Pi1(i) = (a*b + 2*a*c2(i) - 2*b*c1 - 2*c1*c2(i))^2/(b*(3*b + 4*c2(i))^2);
    Pi2(i) = ((a + c1)^2*(b + c2(i)))/(3*b + 4*c2(i))^2;