Este notebook es el complemento práctico, en código R, del documento teórico “Teoría y Ejercicios Resueltos: Regulación Económica”. Cada ejemplo y cada ejercicio propuesto en dicho documento se resuelve aquí paso a paso en RStudio, mostrando cómo traducir una fórmula económica a instrucciones de R, de modo que el estudiante aprenda simultáneamente la teoría y la programación.
La estructura sigue las cuatro unidades del documento original: monopolio natural, regulación de tarifas, discriminación de precios, y prácticas anticompetitivas en modelos de oligopolio.
Con demanda \(P=100-Q\) y costos \(C(Q)=400+50Q\), se calculan la cantidad y el precio bajo tres esquemas de regulación: monopolio no regulado, tarifación a costo marginal, y tarifación a costo medio.
# Parametros del modelo
a <- 100 # intercepto de la demanda: P = a - Q
c <- 50 # costo marginal constante
F <- 400 # costo fijo
# --- Monopolio no regulado: IMg = CMg ---
# Demanda P = a - Q => Ingreso total IT = P*Q = (a-Q)*Q = aQ - Q^2
# Ingreso marginal IMg = a - 2Q (derivada de IT respecto a Q)
# Se iguala IMg = CMg y se despeja Q
Q_m <- (a - c) / 2
P_m <- a - Q_m
beneficio_m <- P_m * Q_m - (F + c * Q_m)
cat("Monopolio no regulado:\n")
## Monopolio no regulado:
cat(" Q_m =", Q_m, " P_m =", P_m, " beneficio =", beneficio_m, "\n\n")
## Q_m = 25 P_m = 75 beneficio = 225
# --- Tarificación a costo marginal: P = CMg ---
Q_cmg <- a - c # despejando Q de: c = a - Q
P_cmg <- c
beneficio_cmg <- P_cmg * Q_cmg - (F + c * Q_cmg)
subsidio <- -beneficio_cmg
cat("Tarificación a costo marginal:\n")
## Tarificación a costo marginal:
cat(" Q =", Q_cmg, " P =", P_cmg, " beneficio =", beneficio_cmg,
" subsidio requerido =", subsidio, "\n\n")
## Q = 50 P = 50 beneficio = -400 subsidio requerido = 400
# --- Tarificación a costo medio: P = CMe(Q) = F/Q + c ---
# Se resuelve la ecuación cuadrática: a - Q = F/Q + c => Q^2 - (a-c)Q + F = 0
coef_b <- -(a - c)
coef_c <- F
raices <- polyroot(c(coef_c, coef_b, 1)) # orden: término independiente, lineal, cuadrático
raices_reales <- Re(raices)
cat("Raíces de la ecuación cuadrática (tarificación CMe):", sort(raices_reales), "\n")
## Raíces de la ecuación cuadrática (tarificación CMe): 10 40
Q_cme <- max(raices_reales) # la solución económicamente relevante es la de mayor Q
P_cme <- a - Q_cme
cat("Tarificación a costo medio (intersección de mayor Q):\n")
## Tarificación a costo medio (intersección de mayor Q):
cat(" Q =", round(Q_cme, 2), " P =", round(P_cme, 2), "\n")
## Q = 40 P = 60
El resultado confirma lo obtenido a mano: monopolio en (25, 75) con beneficio 225, tarifación a costo marginal en (50, 50) con subsidio requerido de 400, y tarifación a costo medio en (40, 60) con beneficio nulo.
Con demanda \(P=120-Q\) y costos \(C(Q)=800+60Q\), calcule en R los tres esquemas de tarifación (monopolio no regulado, tarifación a costo marginal y tarifación a costo medio), reutilizando la misma lógica del ejemplo anterior.
# Espacio para el desarrollo del alumno
Escriba una función en R llamada
costo_fragmentado(F, c, Q, n) que calcule el costo total de
repartir una producción Q entre n empresas
idénticas, cada una con costos F + c*(Q/n). Compare el
resultado de dicha función, para n = 1, 2, 3, 4, 5, contra
el costo de una sola empresa C(Q) = F + c*Q, y verifique
que el costo fragmentado crece linealmente con n.
# Espacio para el desarrollo del alumno
# --- Regulacion por tasa de retorno ---
RB <- 10000000 # base tarifaria
r <- 0.08 # tasa de retorno permitida
OpEx <- 1200000 # costos operativos
D <- 500000 # depreciacion
Q <- 50000 # unidades vendidas
RR <- OpEx + D + r * RB
tarifa <- RR / Q
cat("Requerimiento de ingresos (RR) =", RR, "\n")
## Requerimiento de ingresos (RR) = 2500000
cat("Tarifa unitaria =", tarifa, "\n\n")
## Tarifa unitaria = 50
# --- Regulacion por precio tope (Price Cap, esquema RPI-X) ---
P0 <- 100
RPI <- 0.03
X <- 0.015
factor_ajuste <- 1 + RPI - X
P1 <- P0 * factor_ajuste
cat("Factor de ajuste anual =", factor_ajuste, "\n")
## Factor de ajuste anual = 1.015
cat("Precio del siguiente periodo P1 =", P1, "\n")
## Precio del siguiente periodo P1 = 101.5
Una empresa de agua potable reporta \(RB=\text{S/}\,8\,000\,000\), \(r=10\,\%\), \(OpEx=\text{S/}\,900\,000\) y \(D=\text{S/}\,300\,000\), con \(Q=40\,000\) unidades vendidas. Calcule en R el requerimiento de ingresos y la tarifa unitaria.
# Espacio para el desarrollo del alumno
Una empresa regulada bajo precio tope tiene \(P_0=\text{S/}\,80\), con \(RPI=4\,\%\) y \(X=2\,\%\) constantes cada año. Calcule en R
el precio máximo permitido para los años 1, 2 y 3, utilizando un bucle
for que aplique el factor de ajuste año tras año.
# Espacio para el desarrollo del alumno
Una empresa vende en dos mercados con demandas \(P_1=100-Q_1\) y \(P_2=80-2Q_2\), y costo marginal constante \(CMg=20\). Se calcula la cantidad y el precio óptimos en cada mercado, los excedentes del consumidor y del productor, y se verifica el índice de Lerner con la elasticidad de cada mercado.
CMg <- 20
# --- Mercado 1: P1 = 100 - Q1 ---
# IMg1 = 100 - 2*Q1 (derivada del ingreso total (100-Q1)*Q1)
# Se iguala IMg1 = CMg y se despeja Q1
a1 <- 100; b1 <- 1
Q1 <- (a1 - CMg) / (2 * b1)
P1 <- a1 - b1 * Q1
# --- Mercado 2: P2 = 80 - 2*Q2 ---
a2 <- 80; b2 <- 2
Q2 <- (a2 - CMg) / (2 * b2)
P2 <- a2 - b2 * Q2
cat("Mercado 1: Q1 =", Q1, " P1 =", P1, "\n")
## Mercado 1: Q1 = 40 P1 = 60
cat("Mercado 2: Q2 =", Q2, " P2 =", P2, "\n\n")
## Mercado 2: Q2 = 15 P2 = 50
# --- Excedente del consumidor: area bajo la demanda menos el gasto total ---
# Para una demanda lineal P = a - b*Q, el area bajo la curva hasta Q* es: a*Q* - b*Q*^2/2
area_bajo_demanda_1 <- a1 * Q1 - b1 * Q1^2 / 2
CS1 <- area_bajo_demanda_1 - P1 * Q1
area_bajo_demanda_2 <- a2 * Q2 - b2 * Q2^2 / 2
CS2 <- area_bajo_demanda_2 - P2 * Q2
# --- Excedente del productor: (Precio - Costo marginal) * Cantidad ---
PS1 <- (P1 - CMg) * Q1
PS2 <- (P2 - CMg) * Q2
cat("Excedente del consumidor: CS1 =", CS1, " CS2 =", CS2, "\n")
## Excedente del consumidor: CS1 = 800 CS2 = 225
cat("Excedente del productor: PS1 =", PS1, " PS2 =", PS2, "\n\n")
## Excedente del productor: PS1 = 1600 PS2 = 450
# --- Verificacion del indice de Lerner: (P-CMg)/P = 1/elasticidad ---
# Mercado 1: Q1 = a1 - b1*P1 => dQ1/dP1 = -b1 = -1
elasticidad_1 <- b1 * (P1 / Q1)
lerner_1 <- (P1 - CMg) / P1
# Mercado 2: Q2 = (a2-P2)/b2 => dQ2/dP2 = -1/b2
elasticidad_2 <- (1 / b2) * (P2 / Q2)
lerner_2 <- (P2 - CMg) / P2
cat("Mercado 1: elasticidad =", elasticidad_1, " indice de Lerner =", round(lerner_1, 4),
" 1/elasticidad =", round(1 / elasticidad_1, 4), "\n")
## Mercado 1: elasticidad = 1.5 indice de Lerner = 0.6667 1/elasticidad = 0.6667
cat("Mercado 2: elasticidad =", round(elasticidad_2, 4), " indice de Lerner =", lerner_2,
" 1/elasticidad =", round(1 / elasticidad_2, 4), "\n")
## Mercado 2: elasticidad = 1.6667 indice de Lerner = 0.6 1/elasticidad = 0.6
Como el mercado 1 tiene una demanda más inelástica (elasticidad 1.5 frente a 1.667), la empresa cobra allí un margen proporcionalmente mayor, confirmando el teorema del índice de Lerner.
Una empresa discrimina precios en dos mercados con demandas \(P_1=90-Q_1\) y \(P_2=60-3Q_2\), y costo marginal \(CMg=30\). Calcule en R \(Q_1,P_1,Q_2,P_2\), los excedentes del consumidor y del productor en cada mercado, y verifique el índice de Lerner con la elasticidad de cada mercado, reutilizando la lógica del ejemplo anterior.
# Espacio para el desarrollo del alumno
Con demanda \(P=100-Q_1-Q_2\) y costo marginal \(CMg=10\) para ambas empresas, se calcula el equilibrio de Cournot-Nash, el resultado bajo cártel, el beneficio de desviarse del acuerdo, y el factor de descuento crítico \(\delta^{*}\) necesario para sostener la colusión.
a <- 100
cmg <- 10
# --- Equilibrio de Cournot-Nash simétrico ---
# Formula derivada analiticamente: Qi_nash = (a-c)/3
Q_nash <- (a - cmg) / 3
P_nash <- a - 2 * Q_nash
pi_nash <- (P_nash - cmg) * Q_nash
cat("Cournot-Nash: Q por empresa =", Q_nash, " P =", P_nash, " beneficio por empresa =", pi_nash, "\n\n")
## Cournot-Nash: Q por empresa = 30 P = 40 beneficio por empresa = 900
# --- Cartel: cada empresa produce la mitad de la cantidad de monopolio ---
# Formula: Qi_cartel = (a-c)/4 (monopolio conjunto Q_total=(a-c)/2, dividido entre 2 empresas)
Q_cartel <- (a - cmg) / 4
P_cartel <- a - 2 * Q_cartel
pi_cartel <- (P_cartel - cmg) * Q_cartel
cat("Cartel: Q por empresa =", Q_cartel, " P =", P_cartel, " beneficio por empresa =", pi_cartel, "\n\n")
## Cartel: Q por empresa = 22.5 P = 55 beneficio por empresa = 1012.5
# --- Desviación óptima: dado que el rival mantiene Q_cartel, se maximiza el beneficio propio ---
# pi_dev(Q1) = (a - Q1 - Q_cartel - c)*Q1 ; FOC: a - 2*Q1 - Q_cartel - c = 0
Q_dev <- (a - cmg - Q_cartel) / 2
pi_dev <- (a - Q_dev - Q_cartel - cmg) * Q_dev
cat("Desviación óptima: Q =", Q_dev, " beneficio de desviarse =", pi_dev, "\n\n")
## Desviación óptima: Q = 33.75 beneficio de desviarse = 1139.062
# --- Factor de descuento crítico ---
delta_critico <- (pi_dev - pi_cartel) / (pi_dev - pi_nash)
cat("Factor de descuento crítico delta* =", delta_critico, "\n")
## Factor de descuento crítico delta* = 0.5294118
cat("Fraccion exacta 9/17 =", 9/17, "\n")
## Fraccion exacta 9/17 = 0.5294118
El resultado confirma que \(\delta^{*}=9/17\approx 0.529\), exactamente el valor que predice la teoría para cualquier duopolio de Cournot simétrico con demanda lineal, sin importar los parámetros de demanda o costo.
Para facilitar la resolución del ejercicio propuesto, se construye
una función que automatiza todo el procedimiento anterior a partir de
los parámetros a (intercepto de demanda) y c
(costo marginal).
analizar_cournot <- function(a, c) {
Q_nash <- (a - c) / 3
P_nash <- a - 2 * Q_nash
pi_nash <- (P_nash - c) * Q_nash
Q_cartel <- (a - c) / 4
P_cartel <- a - 2 * Q_cartel
pi_cartel <- (P_cartel - c) * Q_cartel
Q_dev <- (a - c - Q_cartel) / 2
pi_dev <- (a - Q_dev - Q_cartel - c) * Q_dev
delta_critico <- (pi_dev - pi_cartel) / (pi_dev - pi_nash)
resultado <- data.frame(
Escenario = c("Cournot-Nash", "Cartel", "Desviacion"),
Cantidad = c(Q_nash, Q_cartel, Q_dev),
Beneficio = c(pi_nash, pi_cartel, pi_dev)
)
list(tabla = resultado, delta_critico = delta_critico)
}
# Se reproduce el ejemplo anterior como prueba de la función
resultado_ejemplo <- analizar_cournot(a = 100, c = 10)
resultado_ejemplo$tabla
resultado_ejemplo$delta_critico
## [1] 0.5294118
Las funciones de reacción de cada empresa, despejadas en el plano \((Q_1,Q_2)\), son \(Q_2=90-2Q_1\) (reacción de la empresa 1) y \(Q_2=45-Q_1/2\) (reacción de la empresa 2). El equilibrio de Cournot-Nash es el punto donde ambas rectas se cruzan.
Q1_vals <- seq(0, 90, by = 1)
# Reacción de la empresa 1: Q2 = 90 - 2*Q1 (solo válida para Q1 entre 0 y 45)
reaccion_1 <- ifelse(Q1_vals <= 45, 90 - 2 * Q1_vals, NA)
# Reacción de la empresa 2: Q2 = 45 - Q1/2
reaccion_2 <- 45 - Q1_vals / 2
# Frontera de colusion (cartel): Q1 + Q2 = 45
frontera_cartel <- ifelse(Q1_vals <= 45, 45 - Q1_vals, NA)
plot(Q1_vals, reaccion_1, type = "l", col = "blue", lwd = 2,
xlim = c(0, 90), ylim = c(0, 90),
xlab = "Cantidad de la empresa 1 (Q1)", ylab = "Cantidad de la empresa 2 (Q2)",
main = "Funciones de reacción del duopolio de Cournot")
lines(Q1_vals, reaccion_2, col = "red", lwd = 2)
lines(Q1_vals, frontera_cartel, col = "darkgreen", lwd = 2, lty = 2)
points(30, 30, pch = 19, col = "black", cex = 1.4)
text(30, 30, labels = "Nash (30,30)", pos = 4, cex = 0.8)
points(22.5, 22.5, pch = 19, col = "gray40", cex = 1.4)
text(22.5, 22.5, labels = "Cartel (22.5,22.5)", pos = 1, cex = 0.8)
legend("topright",
legend = c("Reacción empresa 1", "Reacción empresa 2", "Frontera de colusión"),
col = c("blue", "red", "darkgreen"), lty = c(1, 1, 2), lwd = 2, bty = "n", cex = 0.8)
El punto negro confirma el equilibrio de Cournot-Nash (30,30) exactamente donde se cruzan ambas rectas de reacción, mientras que el punto gris (cártel) se ubica sobre la frontera de colusión, más cerca del origen.
Con los mismos parámetros del ejemplo de Cournot (\(P=100-Q\), \(CMg=10\)), bajo competencia a la Bertrand el único equilibrio de Nash es \(P_1=P_2=CMg\), ya que cualquier precio por encima del costo marginal invita a que el rival lo subvalúe ligeramente y capture todo el mercado.
a <- 100
cmg <- 10
# Bertrand: el equilibrio siempre es P = CMg, sin importar el número de rivales (mientras haya al menos 2)
P_bertrand <- cmg
Q_bertrand <- a - P_bertrand
beneficio_bertrand <- 0 # por definicion, P=CMg implica beneficio economico nulo
cat("Bertrand: P =", P_bertrand, " Q total =", Q_bertrand, " beneficio =", beneficio_bertrand, "\n\n")
## Bertrand: P = 10 Q total = 90 beneficio = 0
# Tabla comparativa de los tres regimenes (usando los resultados ya calculados de Cournot y cartel)
comparacion_regimenes <- data.frame(
Regimen = c("Cártel (Monopolio)", "Cournot", "Bertrand"),
Precio = c(a - 2 * (a - cmg) / 4, a - 2 * (a - cmg) / 3, P_bertrand),
Cantidad_total = c(2 * (a - cmg) / 4, 2 * (a - cmg) / 3, Q_bertrand)
)
comparacion_regimenes
barplot(
rbind(comparacion_regimenes$Precio, comparacion_regimenes$Cantidad_total),
beside = TRUE,
names.arg = comparacion_regimenes$Regimen,
col = c("indianred", "steelblue"),
ylim = c(0, 100),
ylab = "Precio (soles) / Cantidad total (unidades)",
main = "Comparación de regímenes de competencia"
)
legend("topright", legend = c("Precio de mercado", "Cantidad total"),
fill = c("indianred", "steelblue"), bty = "n", cex = 0.8)
A medida que aumenta la intensidad competitiva (de cártel a Cournot a Bertrand), el gráfico muestra cómo el precio cae y la cantidad total se expande, hasta alcanzar en Bertrand el resultado de competencia perfecta: la paradoja de Bertrand.
Para un duopolio de Cournot con demanda \(P=90-Q_1-Q_2\) y \(CMg=6\), utilice la función
analizar_cournot() creada anteriormente para calcular el
equilibrio de Cournot-Nash, el resultado bajo cártel, la desviación
óptima y el factor de descuento crítico. Compruebe que \(\delta^{*}\) coincide nuevamente con \(9/17\).
# Espacio para el desarrollo del alumno
A continuación se resuelve, en R, cada uno de los ejercicios propuestos a lo largo del notebook.
a <- 120
c <- 60
F <- 800
Q_m <- (a - c) / 2
P_m <- a - Q_m
beneficio_m <- P_m * Q_m - (F + c * Q_m)
cat("Monopolio: Q =", Q_m, " P =", P_m, " beneficio =", beneficio_m, "\n")
## Monopolio: Q = 30 P = 90 beneficio = 100
Q_cmg <- a - c
subsidio <- F
cat("Tarificación CMg: Q =", Q_cmg, " P =", c, " subsidio =", subsidio, "\n")
## Tarificación CMg: Q = 60 P = 60 subsidio = 800
raices <- polyroot(c(F, -(a - c), 1))
Q_cme <- max(Re(raices))
P_cme <- a - Q_cme
cat("Tarificación CMe: Q =", round(Q_cme, 2), " P =", round(P_cme, 2), "\n")
## Tarificación CMe: Q = 40 P = 80
costo_fragmentado <- function(F, c, Q, n) {
n * (F + c * (Q / n))
}
F <- 400
c <- 50
Q <- 100
for (n in 1:5) {
costo_n <- costo_fragmentado(F, c, Q, n)
cat("n =", n, " costo total fragmentado =", costo_n, "\n")
}
## n = 1 costo total fragmentado = 5400
## n = 2 costo total fragmentado = 5800
## n = 3 costo total fragmentado = 6200
## n = 4 costo total fragmentado = 6600
## n = 5 costo total fragmentado = 7000
cat("\nComparacion con formula general n*F + c*Q:\n")
##
## Comparacion con formula general n*F + c*Q:
for (n in 1:5) {
cat("n =", n, " n*F + c*Q =", n * F + c * Q, "\n")
}
## n = 1 n*F + c*Q = 5400
## n = 2 n*F + c*Q = 5800
## n = 3 n*F + c*Q = 6200
## n = 4 n*F + c*Q = 6600
## n = 5 n*F + c*Q = 7000
Como se observa, el costo total crece exactamente en incrementos de
F (400) por cada empresa adicional, confirmando que la
ineficiencia de fragmentar la producción aumenta linealmente con
n.
RB <- 8000000
r <- 0.10
OpEx <- 900000
D <- 300000
Q <- 40000
RR <- OpEx + D + r * RB
tarifa <- RR / Q
cat("RR =", RR, "\n")
## RR = 2e+06
cat("Tarifa unitaria =", tarifa, "\n")
## Tarifa unitaria = 50
P0 <- 80
RPI <- 0.04
X <- 0.02
factor_ajuste <- 1 + RPI - X
P <- P0
for (anio in 1:3) {
P <- P * factor_ajuste
cat("Precio en el anio", anio, "=", round(P, 4), "\n")
}
## Precio en el anio 1 = 81.6
## Precio en el anio 2 = 83.232
## Precio en el anio 3 = 84.8966
CMg <- 30
a1 <- 90; b1 <- 1
Q1 <- (a1 - CMg) / (2 * b1)
P1 <- a1 - b1 * Q1
a2 <- 60; b2 <- 3
Q2 <- (a2 - CMg) / (2 * b2)
P2 <- a2 - b2 * Q2
cat("Mercado 1: Q1 =", Q1, " P1 =", P1, "\n")
## Mercado 1: Q1 = 30 P1 = 60
cat("Mercado 2: Q2 =", Q2, " P2 =", P2, "\n\n")
## Mercado 2: Q2 = 5 P2 = 45
CS1 <- (a1 * Q1 - b1 * Q1^2 / 2) - P1 * Q1
CS2 <- (a2 * Q2 - b2 * Q2^2 / 2) - P2 * Q2
PS1 <- (P1 - CMg) * Q1
PS2 <- (P2 - CMg) * Q2
cat("CS1 =", CS1, " CS2 =", CS2, "\n")
## CS1 = 450 CS2 = 37.5
cat("PS1 =", PS1, " PS2 =", PS2, "\n\n")
## PS1 = 900 PS2 = 75
elasticidad_1 <- b1 * (P1 / Q1)
lerner_1 <- (P1 - CMg) / P1
elasticidad_2 <- (1 / b2) * (P2 / Q2)
lerner_2 <- (P2 - CMg) / P2
cat("Mercado 1: elasticidad =", elasticidad_1, " Lerner =", lerner_1, " 1/elasticidad =", round(1/elasticidad_1,4), "\n")
## Mercado 1: elasticidad = 2 Lerner = 0.5 1/elasticidad = 0.5
cat("Mercado 2: elasticidad =", elasticidad_2, " Lerner =", round(lerner_2, 4), " 1/elasticidad =", round(1/elasticidad_2,4), "\n")
## Mercado 2: elasticidad = 3 Lerner = 0.3333 1/elasticidad = 0.3333
resultado_propuesto <- analizar_cournot(a = 90, c = 6)
resultado_propuesto$tabla
resultado_propuesto$delta_critico
## [1] 0.5294118
cat("\nComparacion con 9/17 =", 9/17, "\n")
##
## Comparacion con 9/17 = 0.5294118
El factor de descuento crítico vuelve a ser exactamente \(9/17\approx 0.529\), confirmando que este valor es independiente de los parámetros de demanda y costo utilizados.
Este notebook demostró que cada resultado del documento teórico de
Regulación Económica puede reproducirse en R traduciendo directamente
las fórmulas algebraicas a código, ya sea de forma manual o mediante
funciones reutilizables como analizar_cournot(). Se
recomienda que los estudiantes trabajen primero el desarrollo matemático
de cada ejercicio propuesto en su cuaderno, y utilicen después el código
de R únicamente para verificar su propio resultado.