演示如何用 SG-RAS(Stochastic Generalized RAS)思路 把一个原始不平衡的社会核算矩阵(SAM)快速调平。
代码特点
1. 支持负值与零值,无需预先“移负”或“开窗”;
2. 采用双比例(row scaling + column scaling)迭代即可收敛,逻辑与 Lenzen et al. (2007) GRAS 一致;
3. 变量维度、账户名称、收敛精度、最大迭代次数均可一键修改。
---
1 数据准备
把原始 未平衡 SAM(含 rowTotal / colTotal 控制值)放在同一个 Excel 文件 `samRaw.xlsx`,工作表名 `SAM`。
首行首列放账户代码,最后一行放 `rowTotal`,最后一列放 `colTotal`。
示例账户集合(可增减):
| 账户 | 含义 |
|------|--------------------|
| AGR | 农业 |
| IND | 工业 |
| SER | 服务业 |
| LAB | 劳动要素 |
| CAP | 资本要素 |
| HHD | 居民 |
| GOV | ZF |
| INV | 投资/储蓄 |
| ROW | 国外(Rest of World)|
---
2 完整 GAMS 代码
```gams
$title SG-RAS balancing of a Social Accounting Matrix (SAM)
*------------------------------------------------------------------
* 1. 读入原始矩阵与控制合计
*------------------------------------------------------------------
$call gdxxrw samRaw.xlsx par=samRaw rng=SAM!A1 rdim=1 cdim=1
$gdxin samRaw.gdx
$load samRaw
* 自动提取集合(账户)名
Set acc 'accounts' /system.suffix/
a(acc) 'accounts w/o totals'
i(acc) 'row accounts'
j(acc) 'column accounts';
Alias (a,a1);
* 去掉合计行列
a(acc) = yes$(not (sameas(acc,'rowTotal') or sameas(acc,'colTotal')));
i(a) = yes;
j(a) = yes;
Parameter
X0(i,j) 'initial unbalanced flows'
u(i) 'row control totals'
v(j) 'column control totals';
X0(i,j) = samRaw(i,j);
u(i) = samRaw('rowTotal',i);
v(j) = samRaw(j,'colTotal');
*------------------------------------------------------------------
* 2. 初始化
*------------------------------------------------------------------
Scalar
tol / 1e-8 /
maxIter / 5000 /
iter
maxDev;
Parameter
r(i) 'row multipliers'
s(j) 'column multipliers'
X(i,j) 'balanced SAM';
X(i,j) = X0(i,j);
r(i) = 1;
s(j) = 1;
*------------------------------------------------------------------
* 3. SG-RAS / GRAS 迭代
*------------------------------------------------------------------
iter = 0;
maxDev = 1;
while( (maxDev > tol) and (iter < maxIter),
iter = iter + 1;
* 3-a 行比例调整
r(i) = u(i) / sum(j, X(i,j));
X(i,j) = X(i,j) * r(i);
* 3-b 列比例调整
s(j) = v(j) / sum(i, X(i,j));
X(i,j) = X(i,j) * s(j);
* 3-c 计算最大偏差
maxDev = smax( (i,j), abs(X(i,j) - X0(i,j)) );
);
display "iterations used", iter;
display "max deviation from controls / original", maxDev;
*------------------------------------------------------------------
* 4. 结果导出
*------------------------------------------------------------------
execute_unload 'samBalanced.gdx', X, u, v, iter;
```
---
3 使用方法
1. 把文件存为 `samBalance.gms`,与 `samRaw.xlsx` 放在同一目录;
2. 安装 GAMS + 任意 NLP/MIP 求解器(本代码无需求解器,纯 GAMS 语句即可);
3. 运行:
```bash
gams samBalance.gms
```
4. 平衡后的矩阵 `X(i,j)` 保存在 `samBalanced.gdx`,可再用 `gdxxrw` 写回 Excel:
```gams
execute 'gdxxrw samBalanced.gdx par=X rng=balanced!A1';
```
---
4 常见问题与扩展
| 问题 | 解决思路 |
|---|---|
| 收敛慢 | 把 `tol` 放宽到 `1e-6` 或增加 `maxIter`;若仍慢,改用交叉熵 NLP 模型。 |
| 需要固定某些格 | 把对应 `X(i,j)` 设为常数,去掉其行/列的控制合计即可。 |
| 负值 | SG-RAS 天然允许负值,无需额外处理;若担心符号翻转,可在 `X0(i,j)` 加一常数平移后再减回。 |
参考文献
- Lenzen, M., Wood, R., & Wiedmann, T. (2007). *Uncertainty analysis for Multi-Region Input–Output models – A case study of the UK’s carbon footprint*. Economic Systems Research, 19(3), 293-310.
- 王韬, 马成, 林聪 (2012). SAM 平衡的 SG-RAS 与 SG-CE 方法. 《统计研究》第 12 期。


雷达卡






京公网安备 11010802022788号







