{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "c92da12e",
   "metadata": {},
   "source": [
    "# 动态定价 — 收益管理\n",
    "\n",
    "对应案例: [动态定价](/docs/case-studies/operations/dynamic-pricing-case/)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20874b3f",
   "metadata": {},
   "source": [
    "## 1. 需求函数 & 库存"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "da99f617",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np, matplotlib.pyplot as plt\n",
    "np.random.seed(42)\n",
    "capacity=100; T=100\n",
    "prices=np.linspace(20,100,T)\n",
    "demand_per_period=lambda p:max(0,15-0.15*p+np.random.normal(0,1))\n",
    "inventory=capacity; revenue=0; history=[]\n",
    "for t in range(T):\n",
    "    if inventory<=0: break\n",
    "    p=prices[t]\n",
    "    d=max(0,int(min(demand_per_period(p),inventory)))\n",
    "    inventory-=d; revenue+=d*p\n",
    "    history.append({'t':t,'price':p,'demand':d,'inventory':inventory,'revenue':revenue})\n",
    "df=pd.DataFrame(history) if 'pd' in dir() else __import__('pandas').DataFrame(history)\n",
    "print(f'Final: revenue=${revenue:.0f}, remaining={inventory}, utilization={(capacity-inventory)/capacity:.0%}')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "98a2ff73",
   "metadata": {},
   "source": [
    "## 2. 可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8295898a",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "df=pd.DataFrame(history)\n",
    "fig,(ax1,ax2)=plt.subplots(2,1,figsize=(12,8))\n",
    "ax1.plot(df['t'],df['price'],label='Price',color='#2196F3')\n",
    "ax1_=ax1.twinx(); ax1_.bar(df['t'],df['demand'],alpha=0.3,label='Sales',color='#4CAF50')\n",
    "ax1.set_ylabel('Price'); ax1_.set_ylabel('Sales')\n",
    "ax1.legend(loc=2); ax1_.legend(loc=1); ax1.set_title('Dynamic Pricing Strategy')\n",
    "ax2.plot(df['t'],df['inventory'],label='Inventory',color='#FF9800')\n",
    "ax2.fill_between(df['t'],0,df['inventory'],alpha=0.2,color='#FF9800')\n",
    "ax2.set_xlabel('Time'); ax2.set_ylabel('Inventory')\n",
    "ax2.legend(); ax2.set_title('Inventory Depletion')\n",
    "plt.tight_layout(); plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ce1c7647",
   "metadata": {},
   "source": [
    "## 3. 收入对比 (固定 vs 动态)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3e6ba0a7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Fixed pricing baseline\n",
    "np.random.seed(42)\n",
    "fixed_p=50; inv_f=capacity; rev_f=0\n",
    "for _ in range(T):\n",
    "    if inv_f<=0: break\n",
    "    d=min(max(0,int(15-0.15*fixed_p+np.random.normal(0,1))),inv_f)\n",
    "    inv_f-=d; rev_f+=d*fixed_p\n",
    "print(f'Fixed  (p=$50): revenue=${rev_f:.0f}, utilization={(capacity-inv_f)/capacity:.0%}')\n",
    "print(f'Dynamic:        revenue=${revenue:.0f}, utilization={(capacity-inventory)/capacity:.0%}')\n",
    "print(f'Lift: ${revenue-rev_f:.0f} ({(revenue/rev_f-1)*100:+.1f}%)')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2678925",
   "metadata": {},
   "source": [
    "---\n",
    "*更多分析见 [案例文档](/docs/case-studies/operations/dynamic-pricing-case/)*"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.10.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
