前置:企业成本、定价与竞争 · 收入、财富与不平等 · 国内生产总值与国民收入 · 利率、储蓄与投资
一个经济体总产出增加 20%,人们是不是都更富裕了?如果人口和工时也增加 20%,每人和每小时产出可能完全没变。长期增长的起点,是先固定比较口径,再追踪资本、技术和组织怎样提高持续生产能力。
本篇先计算劳动生产率,再让两个方案从相同资本起点经历多期变化。最后区分一次水平提高与持续增长,并回到分配、环境和测量。所有数字为教学设定,交互中的“期”不是对任何真实经济体年份的预测。
总量、每人和每小时各回答什么
| 情形 | 实际产出 | 人口 | 总工时 | 每人产出 | 每小时产出 |
| 起点 | 1000 | 100 | 500 | 10 | 2 |
| 人口与投入一起扩大 | 1200 | 120 | 600 | 10 | 2 |
| 相同人口与工时,产出提高 | 1200 | 100 | 500 | 12 | 2.4 |
第二行情形的总量增长没有提高这两个平均指标,第三行才都提高 20%。劳动生产率是产出相对工时的比率,不是员工勤奋程度的直接测量;更好的机器、组织、技能和技术都能影响它。
还应先扣除价格变化。若名义收入增加只是同样产品标价上涨,不能称作实际生产能力同幅提高。跨地区比较要进一步处理购买力、工时与统计范围。
一种商品既能消费,也能变成资本
建立一个简化经济:人口固定,所有人相同,一种合成商品既可消费也可投资;一单位投资使下一期多一单位资本。每人资本为 k,每人每期产出为 y=A√k,A 汇总模型中给定的生产率条件。每期资本折旧 10%,投资率为 s。
资本的变化是:
当期产出 y = A√k
投资 = s×y
消费 = (1−s)×y
下一期资本 = 0.9×当期资本 + 投资
先设 A=2、s=25%、k=25,则 y=10,投资 2.5 恰好补足折旧 2.5,消费为 7.5。下一期 k 仍为 25,这叫稳态。它不是没有生产活动,而是每期的更新投资恰好维持资本。
资本边际收益递减的含义,可以比较 k=4→9 时产出从 4 到 6,与 k=9→25 时产出从 6 到 10:资本越多,继续增加同样一单位资本带来的额外产出越小。注意不是说总产出会因资本增加而下降。
前一区间每增加一单位资本的平均新增产出为 2/5=0.4,后一区间为 4/16=0.25。这里比较的是单位资本带来的产出,不能只比较总增量 2 和 4。
同一起点提高投资率,先失去什么
现在只把投资率从 25% 提高到 40%,资本仍从 25 出发、A 仍为 2。变更当期产出还是 10,但投资从 2.5 到 4,消费从 7.5 降为 6,先减少 1.5。资本不会因为宣布更高投资率就立刻跳到新的长期水平。
下一期资本为 0.9×25+4=26.5,产出约 10.296,消费约 6.177;资本逐步积累,未来产出和消费才增加。
| 变更后的期数 | 每人资本 | 每人产出 | 每人消费 |
| 0 | 25.000 | 10.000 | 6.000 |
| 1 | 26.500 | 10.296 | 6.177 |
| 2 | 27.968 | 10.577 | 6.346 |
| 正稳态极限 | 64.000 | 16.000 | 9.600 |
表的最后一行是极限,不是第 3 期。直接拿旧稳态消费 7.5 与新稳态 9.6 比较,会漏掉先降低消费的过渡代价;从同一起点画时间路径,才能看到谁在什么时候付成本。
正在呈现知识画面
改变条件,核对结果共同起点 k=25;原方案 A=2、投资率25%、消费7.5。改变参数后逐期更新 k下一期=0.9k+投资。图显示60期过渡,下方另列正稳态。提高投资率会先减少消费。
{"id":"economics-26","title":"改变条件,核对结果","summary":"共同起点 k=25;原方案 A=2、投资率25%、消费7.5。改变参数后逐期更新 k下一期=0.9k+投资。图显示60期过渡,下方另列正稳态。提高投资率会先减少消费。","height":750,"html":"<div class=\"controls\"><label for=\"save\"><span data-i18n=\"save\"></span><output id=\"out-save\" for=\"save\"></output><input id=\"save\" type=\"range\" min=\"10\" max=\"50\" step=\"5\" value=\"25\"></label><label for=\"tech\"><span data-i18n=\"tech\"></span><output id=\"out-tech\" for=\"tech\"></output><input id=\"tech\" type=\"range\" min=\"1\" max=\"3\" step=\"0.25\" value=\"2\"></label></div><button id=\"reset\" type=\"button\" data-i18n=\"reset\"></button><div id=\"graphic\"></div><div id=\"results\" class=\"results\" role=\"status\" aria-live=\"polite\" data-i18n-label=\"result\"></div><p class=\"scope\" data-i18n=\"scope\"></p>","css":"body{padding:20px}h2{font-size:19px;margin:0 0 14px}.controls{display:grid;gap:16px}label{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px;font-size:15px}select,input{grid-column:1/-1;width:100%;min-width:0;font:inherit}select{padding:10px;background:var(--paper);color:var(--ink);border:1px solid var(--rule);border-radius:6px;white-space:normal}input{accent-color:var(--accent)}button{min-height:44px;margin:16px 0;font:inherit}.plot{display:block;width:100%;max-width:560px;height:auto;margin:auto}.plot text{fill:var(--ink);font-size:14px}.legend{display:flex;gap:12px;flex-wrap:wrap;margin:8px 0;font-size:14px}.legend i{display:inline-block;width:16px;height:3px;margin-right:5px;vertical-align:middle}.results{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-top:16px}.metric{border:1px solid var(--rule);padding:10px;border-radius:6px;min-width:0}.metric span{display:block;font-size:14px;min-height:3.5em;overflow-wrap:anywhere}.metric strong{font-size:22px;font-weight:600}.barrow{margin:14px 0;font-size:15px}.barlabel{display:flex;justify-content:space-between;gap:10px}.bar{height:16px;background:var(--surface);margin-top:5px}.bar i{display:block;height:100%;background:var(--accent)}.stack{display:flex;height:35px;margin:15px 0}.stack span{display:flex;align-items:center;justify-content:center;color:var(--paper);font-size:13px}.scope{font-size:14px;color:var(--muted);margin:14px 0 0;line-height:1.65}@media(max-width:380px){body{padding:14px 10px}.results{gap:6px}.metric{padding:8px}.metric strong{font-size:19px}}.accounts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.account{border:1px solid var(--rule);border-radius:8px;padding:12px;min-width:0}.account h3{font-size:16px;margin:0 0 12px}.account dl{margin:0}.account dt{font-size:13px;overflow-wrap:anywhere}.account dd{margin:2px 0 12px;font-variant-numeric:tabular-nums}.account .changed{font-weight:700;color:var(--accent)}.area-legend{font-size:14px;line-height:1.7}.area-legend span{display:block}.area-legend i{display:inline-block;width:12px;height:12px;margin-right:6px}@media(max-width:480px){.accounts{grid-template-columns:1fr}}","js":"const N=26,DEFAULTS={\"save\": 25, \"tech\": 2};\n/* Pure, deterministic teaching models. Values are synthetic, not estimates. */\nfunction economy(n,p){\n if(n===6){const q=p.remaining,P0=10,P1=12,Q0=100;return{metrics:{oldRevenue:P0*Q0,newRevenue:P1*q,retainedGain:(P1-P0)*q,lostRevenue:P0*(Q0-q),elasticity:Math.abs(((q-Q0)/((q+Q0)/2))/((P1-P0)/((P1+P0)/2)))},revenueAreas:{remaining:q,oldPrice:P0,newPrice:P1,oldQuantity:Q0}};}\n if(n===5){const shift=p.scenario===1?20:0,supply=p.scenario===2?-20:0,P=(100+shift-supply)/20,Q=20+supply+10*P;return{metrics:{price:P,quantity:Q},plot:{xmax:140,ymax:14,x:'quantity',y:'price',lines:[{key:'demand',points:[[0,(120+shift)/10],[120+shift,0]]},{key:'supply',points:[[Math.max(0,20+supply),0],[140,(120-supply)/10]]},{key:'base',points:[[0,5],[140,5]],dash:true}],dot:[Q,P]}};}\n if(n===8){const b=p.response,bs=10,t=p.tax,Pb=5+bs*t/(b+bs),Ps=5-b*t/(b+bs),Q=70-b*bs*t/(b+bs);return{metrics:{buyer:Pb,seller:Ps,quantity:Q,revenue:t*Q,loss:.5*t*(70-Q)},plot:{xmax:100,ymax:20,x:'quantity',y:'price',areas:[{key:'revenue',points:[[0,Ps],[Q,Ps],[Q,Pb],[0,Pb]]},{key:'loss',points:[[Q,Ps],[Q,Pb],[70,5]]}],lines:[{key:'demand',points:[[0,5+70/b],[Math.min(100,70+5*b),Math.max(0,5+(70-100)/b)]]},{key:'supply',points:[[20,0],[100,8]]},{key:'base',points:[[0,5],[100,5]],dash:true},{key:'wedge',points:[[Q,Ps],[Q,Pb]]}],dot:[Q,Pb]}};}\n if(n===18){let index=100+p.weight*p.rise/100;return{metrics:{index,inflation:index-100},bars:[{key:'base',v:100},{key:'new',v:index}],max:180};}\n if(n===19){let E=60,U=10,N=30;if(p.scenario===1){E+=5;U-=5;}if(p.scenario===2){U-=5;N+=5;}if(p.scenario===3){U+=5;N-=5;}return{metrics:{employment:E,unemployment:U,participation:100*(E+U)/100,urate:100*U/(E+U),erate:E},stack:[E,U,N],stackKeys:['employment','unemployment','outside']};}\n if(n===20){const step=p.scenario;let reserves=100,loan=0,deposit=80,equity=20,br=0,bd=0;if(step!==0){loan=60;deposit=140;}if(step===2){reserves-=60;deposit-=60;br=60;bd=60;}if(step===3){loan=40;deposit=120;}const vals={reserves,loan,deposit,equity,bankBreserves:br,bankBdeposits:bd,borrowerDeposit:step===2?0:loan,borrowerGoods:step===2?60:0,borrowerDebt:loan,merchantDeposit:bd,merchantGoods:step===2?0:60};const prev=step>1?economy(20,{scenario:1}).accounts:economy20initial();return{metrics:{reserves,loan,deposit,equity,bankBreserves:br,bankBdeposits:bd,assets:reserves+loan,liabilities:deposit+equity},accounts:vals,ledger:[['bankA',['reserves','loan','deposit','equity']],['bankB',['bankBreserves','bankBdeposits']],['borrower',['borrowerDeposit','borrowerGoods','borrowerDebt']],['merchant',['merchantDeposit','merchantGoods']]].map(([title,keys])=>({title,items:keys.map(key=>({key,value:vals[key],delta:vals[key]-prev[key]}))}))};}\n if(n===22){const c=p.consume,shock=p.shock,rounds=Array.from({length:8},(_,k)=>shock*c**k);return{metrics:{total:shock/(1-c),shown:rounds.reduce((a,b)=>a+b,0),multiplier:1/(1-c)},bars:rounds.map((v,k)=>({label:String(k+1),v})),max:100,rounds};}\n if(n===25){const e=p.rate;return{metrics:{importBill:10*e,exportBill:70/e,debtBill:100*e},bills:true};}\n if(n===26){const A=p.tech,s=p.save/100,d=.1,k=(s*A/d)**2,y=A*Math.sqrt(k),trajectory=[];let current=25;for(let t=0;t<=60;t++){const output=A*Math.sqrt(current),investment=s*output,depreciation=d*current;trajectory.push({t,k:current,y:output,consumption:(1-s)*output,investment,depreciation});current+=investment-depreciation;}return{metrics:{capital:k,output:y,consumption:(1-s)*y},trajectory,plot:{xmax:60,ymax:Math.max(10,...trajectory.map(a=>a.y))*1.1,x:'period',y:'perPersonFlow',lines:[{key:'baselineConsumption',points:[[0,7.5],[60,7.5]],dash:true},{key:'outputPath',points:trajectory.map(a=>[a.t,a.y])},{key:'consumptionPath',points:trajectory.map(a=>[a.t,a.consumption])}]}};}\n throw Error('Unknown lesson');\n}\nfunction economy20initial(){return{reserves:100,loan:0,deposit:80,equity:20,bankBreserves:0,bankBdeposits:0,borrowerDeposit:0,borrowerGoods:0,borrowerDebt:0,merchantDeposit:0,merchantGoods:60};}\nif(typeof module!=='undefined')module.exports={economy};\n\nfunction renderTeachingView(r,el){\n if(r.ledger){\n el.innerHTML='<div class=\"accounts\">'+r.ledger.map(a=>'<section class=\"account\"><h3>'+escape(viz.t(a.title))+'</h3><dl>'+a.items.map(v=>`<dt>${escape(viz.t(v.key))}</dt><dd class=\"${v.delta?'changed':''}\">${viz.number(v.value)} (${v.delta>0?'+':''}${viz.number(v.delta)})</dd>`).join('')+'</dl></section>').join('')+'</div><p class=\"scope\">'+escape(viz.t('delta'))+'</p>';\n $('#results').hidden=true;\n }\n if(r.revenueAreas){const a=r.revenueAreas,x=q=>45+q*2.65,y=p=>213-p*14,q=a.remaining;\n let s=`<svg class=\"plot\" viewBox=\"0 0 360 270\" role=\"img\" aria-label=\"${escape(viz.t('figure'))}\"><path d=\"M45 28V213H322\" fill=\"none\" stroke=\"var(--rule)\"/>`;\n const rect=(x0,x1,p0,p1,c)=>`<rect x=\"${x(x0)}\" y=\"${y(p1)}\" width=\"${(x1-x0)*2.65}\" height=\"${(p1-p0)*14}\" fill=\"${c}\" fill-opacity=\".48\" stroke=\"${c}\"/>`;\n s+=rect(0,q,0,10,'#5277ab')+rect(0,q,10,12,'#247756')+rect(q,100,0,10,'#b56838');\n for(const p of[0,10,12])s+=`<text x=\"37\" y=\"${y(p)+4}\" text-anchor=\"end\">${p}</text>`;\n for(const v of[0,50,100])s+=`<text x=\"${x(v)}\" y=\"235\" text-anchor=\"middle\">${v}</text>`;\n s+=`<text x=\"45\" y=\"20\">${escape(viz.t('price'))}</text><text x=\"310\" y=\"261\" text-anchor=\"end\">${escape(viz.t('quantity'))}</text></svg>`;\n el.innerHTML=s+'<div class=\"area-legend\">'+[['retainedBase','#5277ab'],['retainedGain','#247756'],['lostRevenue','#b56838']].map(([k,c])=>`<span><i style=\"background:${c}\"></i>${escape(viz.t(k))}</span>`).join('')+'</div>';\n }\n}\n\nconst $=s=>document.querySelector(s),col=['var(--accent)','var(--second)','#7581ae','#b36b47'];\nconst escape=s=>String(s).replace(/[&<>\"']/g,c=>({'&':'&','<':'<','>':'>','\"':'"',\"'\":'''}[c]));\nfunction render(){\n let p={};for(const k of Object.keys(DEFAULTS)){p[k]=Number($('#'+k).value);let o=$('#out-'+k);if(o)o.textContent=viz.number(p[k]);}\n const r=economy(N,p);document.body.dataset.result=JSON.stringify(r.metrics);document.body.dataset.params=JSON.stringify(p);\n $('#results').innerHTML=Object.entries(r.metrics).map(([k,v])=>`<div class=\"metric\"><span>${escape(viz.t(k))}</span><strong data-metric=\"${k}\">${viz.number(v,2)}</strong></div>`).join('');\n const el=$('#graphic');el.replaceChildren();\n if(r.plot){const a=r.plot,x=q=>48+q/a.xmax*278,y=v=>205-v/a.ymax*164;\n let svg=`<svg class=\"plot\" viewBox=\"0 0 360 258\" role=\"img\" aria-label=\"${escape(viz.t('figure'))}\"><path d=\"M48 30V205H333\" fill=\"none\" stroke=\"var(--rule)\"/>`;\n for(const q of [0,a.xmax/2,a.xmax])svg+=`<text x=\"${x(q)}\" y=\"226\" text-anchor=\"middle\">${viz.number(q,1)}</text>`;\n for(const v of [0,a.ymax/2,a.ymax])svg+=`<text x=\"39\" y=\"${y(v)+4}\" text-anchor=\"end\">${viz.number(v,1)}</text>`;\n svg+=`<text x=\"48\" y=\"20\">${escape(viz.t(a.y))}</text><text x=\"326\" y=\"251\" text-anchor=\"end\">${escape(viz.t(a.x))}</text>`;\n (a.areas||[]).forEach((region,j)=>{svg+=`<polygon points=\"${region.points.map(([xx,yy])=>x(xx)+','+y(yy)).join(' ')}\" fill=\"${j===0?'#4c8c9d':'#bd7446'}\" fill-opacity=\".30\"/>`;});\n a.lines.forEach((l,j)=>{svg+=`<polyline fill=\"none\" stroke=\"${col[j]}\" stroke-width=\"${l.key==='wedge'?5:2.5}\" ${l.dash?'stroke-dasharray=\"5 4\"':''} points=\"${l.points.map(([xx,yy])=>x(xx)+','+y(yy)).join(' ')}\"/>`;});\n if(a.dot)svg+=`<circle cx=\"${x(a.dot[0])}\" cy=\"${y(a.dot[1])}\" r=\"5\" fill=\"var(--ink)\"/>`;\n el.innerHTML=svg+'</svg><div class=\"legend\">'+a.lines.map((l,j)=>`<span><i style=\"background:${col[j]}\"></i>${escape(viz.t(l.key))}</span>`).join('')+(a.areas||[]).map((a,j)=>`<span><i style=\"height:10px;background:${j===0?'#4c8c9d':'#bd7446'}\"></i>${escape(viz.t(a.key))}</span>`).join('')+'</div>';\n }else if(r.bars){el.innerHTML=r.bars.map(b=>`<div class=\"barrow\"><div class=\"barlabel\"><span>${escape(b.key?viz.t(b.key):viz.t('round')+' '+b.label)}</span><strong>${viz.number(b.v)}</strong></div><div class=\"bar\"><i style=\"width:${Math.abs(b.v)/Math.max(r.max,...r.bars.map(a=>Math.abs(a.v)))*100}%\"></i></div></div>`).join('')+(N===22?`<p class=\"scope\">${escape(viz.t('negative'))}</p>`:'');\n }else if(r.stack){el.innerHTML='<div class=\"stack\">'+r.stack.map((v,j)=>`<span style=\"width:${v}%;background:${col[j]}\">${v}</span>`).join('')+'</div><div class=\"legend\">'+r.stackKeys.map((k,j)=>`<span><i style=\"background:${col[j]}\"></i>${escape(viz.t(k))}</span>`).join('')+'</div>';}\nrenderTeachingView(r,el);\n}\nfor(const k of Object.keys(DEFAULTS))$('#'+k).addEventListener('input',render);\n$('#reset').addEventListener('click',()=>{for(const[k,v]of Object.entries(DEFAULTS))$('#'+k).value=v;render();});render();\n","audio":false,"strings":{"baselineConsumption":"原方案消费 7.5","capital":"每人资本 k","consumption":"稳态每人消费","consumptionPath":"新方案消费","depreciation":"折旧","figure":"当前参数下的模型图;准确值见下方结果。","flow":"每期投资与折旧","investment":"投资","output":"稳态每人产出","outputPath":"新方案产出","perPersonFlow":"每人每期产出或消费","period":"变更后的期数 t","reset":"恢复基准","result":"计算结果","save":"投资率 / %","scope":"共同起点 k=25;原方案 A=2、投资率25%、消费7.5。改变参数后逐期更新 k下一期=0.9k+投资。图显示60期过渡,下方另列正稳态。提高投资率会先减少消费。","tech":"生产率系数 A"}}
先保持 A=2,把投资率从 25 改为 40。灰色基准是原方案每期消费 7.5,新消费起初在它下方,随后可能超过。图只画 60 期,数值卡片另列正稳态;有限时段内尚未接近极限,不意味着稳态算式错了。
再把投资率调回 25,单独改变 A,观察当期产出也会变化。这与只改变储蓄份额的初期效果不同。每次仅改一个条件,更容易辨认变化来自哪里。
稳态怎么算,为什么不是永久增长
正稳态满足 sA√k=0.1k,所以 k=(sA/0.1)²。s=0.4、A=2 时 k=64、y=16;s=0.25、A=2 时 k=25、y=10。还有 k=0 的数学边界点,但本课路径从正资本出发,不把它当作目标稳态。
较高投资率使资本和产出在过渡期增长,接近新稳态后,净投资趋近零,人均产出增长率也趋近零。它提高长期水平,没有在固定技术、固定人口的模型里创造永久正增长率。
把 A 从 2 一次提高到 2.5,会提高同一资本下的产出,并触发新的资本调整;只要 A 此后固定,最终仍趋向另一稳态。若要解释持续技术进步,需要让生产率条件随时间变化,并说明它如何形成,而不是把一次参数调整当成每年都会再发生的进步。
投资越多,消费是否永远越高
在这个模型的正稳态,产出为 sA²/0.1,消费为 (1−s)sA²/0.1。提高 s 一方面增加未来产出,另一方面留下更少比例用于消费;两种作用不会永远同向。
当 A=2 时,s=25% 的稳态消费为 7.5,40% 为 9.6,50% 为 10。仅在这组特殊假设下,s=50% 最大化稳态每人消费;这不直接给出现实最优投资率,因为还没有计入过渡期消费、代际权重、风险、人口和不同资本类型。
一个“长期数字更高”的方案也可能让当前资源紧张的家庭承担难以接受的代价。评价需要把时间与分配放回,而不是只挑最后一行最大值。
从 A 回到真实生产机制
教育、健康、研发、组织、基础设施和制度都可能影响生产能力。A 只是模型里没有逐项展开因素的汇总,不是直接测得的“发明数量”,也不能把所有无法解释的增长都当作某一种技术的功劳。
观察到高收入地区拥有某种制度,尚未证明制度单独造成高收入:历史、地理、反向因果和共同原因都可能参与。评估一种改进,需要具体机制、可比较对象、时间和实施证据。
资本本身也有质量与组合差异。闲置机器不必然形成有效生产能力;增加设备却缺少技能、能源或可靠供应,实际结果可能偏离单一 k 的模型。把一个重要互补条件加入案例,通常比继续堆一个更大的资本数字更有解释力。
课程最后的迁移任务
一座城市实际 GDP 增长 20%,人口增长 10%,工时增长 20%。计算人均和每小时产出变化,并说明还缺哪些信息才能评价居民生活。
展开推理
人均产出增长为 1.20/1.10−1≈9.09%,每小时产出变化为 1.20/1.20−1=0。还要看收入分配、物价口径、公共服务、环境、健康和闲暇;总量或人均改善不证明每位居民同样改善。这里已经假设 GDP 是实际量,不能再把同一通胀调整重复扣除。
有人看见提高投资率后的正稳态 y=16,就说“从明年起每期都比前一期多生产 6,且当前没人付代价”。请用本课和前面课程纠正这句话。
展开推理
16 是新稳态水平,旧水平为 10;6 是两种长期水平的差,不是永久每期增量。路径从 k=25 开始,当期 y 仍为 10,消费先由 7.5 降到 6,投资占用了当前可消费资源。以后能否实现模型路径取决于投资形成有效资本、技术与人口等条件。还应追问谁承担消费减少、收益怎样分配,以及真实数据能否支持参数。能把约束、跨期取舍、核算、分配和证据连起来,才算完成这条入门主线。
资料与延伸阅读
以下资料用于核对概念与统计口径;本文数字、算例和图形为原创教学设定。
OpenStax · Labor Productivity and Economic Growth