从间接平差到程序:一个水准网最小二乘解算案例
自动部署 / deploy (push) Successful in 4m50s

This commit is contained in:
biss committed 2026-08-27 21:48:49 +08:00
1 parent 28e4effa83
commit 3a9936811a
1 file changed
+203
@@ -0,0 +1,203 @@
---
title: 从间接平差到程序:一个水准网最小二乘解算案例
categories:
- 学习
- 测量平差
tags:
- 测量平差
- 最小二乘
- C#
- 矩阵
summary: >-
以一个含两个已知点、三个未知点和七条观测边的水准网为例,梳理间接平差的观测方程、法方程、精度评定与程序实现边界,并给出可复算的系数矩阵和计算结果。
date: 2026-08-27 21:00:00
abbrlink: e67166f3
---
记录一下课程设计。
## 问题:已知两点,求三个未知点
设已知点为 $A$、$B$,未知点为 $P_1$、$P_2$、$P_3$。已知高程分别为:
$$
H_A=5.016\ \mathrm{m},\qquad H_B=6.016\ \mathrm{m}
$$
观测得到七条高差及对应路线长度。路线越长,观测通常越不稳定,因此这里采用与距离成反比的权:
$$
p_i=\frac{1}{s_i}
$$
其中 $s_i$ 的单位为 km,$p_i$ 为第 $i$ 条观测的权。
| 边号 | 起点 | 终点 | 观测高差 / m | 距离 / km | 权 |
| --- | --- | --- | ---: | ---: | ---: |
| 1 | A | $P_1$ | 1.359000 | 1.1 | 0.909091 |
| 2 | A | $P_2$ | 2.009000 | 1.7 | 0.588235 |
| 3 | B | $P_1$ | 0.363000 | 2.3 | 0.434783 |
| 4 | B | $P_2$ | 1.012000 | 2.7 | 0.370370 |
| 5 | $P_1$ | $P_2$ | 0.657000 | 2.4 | 0.416667 |
| 6 | $P_1$ | $P_3$ | 0.238000 | 1.4 | 0.714286 |
| 7 | $P_3$ | B | -0.595000 | 2.6 | 0.384615 |
单独沿任一路线推高程,会因观测误差得到彼此不完全一致的答案;平差的任务就是在全部观测共同约束下,找到一组最合理的未知高程。
## 从观测方程到法方程
一般地,设观测值为 $L_i$,观测值改正数为 $v_i$,待定参数为 $X_j$,则平差后的观测值满足:
$$
L_i+v_i=f_i(X_1,X_2,\ldots,X_t)
$$
对非线性问题,可在近似值 $X_j^0$ 附近展开:
$$
X_j=X_j^0+\hat{x}_j
$$
忽略二阶及以上小量后,得到线性化观测方程。写成矩阵形式就是:
$$
V=BX-l
$$
这里 $V$ 是观测改正数向量,$B$ 是系数矩阵,$X$ 是参数改正数向量,$l$ 是常数项向量。
间接平差要求加权改正数平方和最小:
$$
V^TPV=\min
$$
将 $V=BX-l$ 代入并对 $X$ 求极值,可得:
$$
B^TPBX=B^TPl
$$
记
$$
N_{BB}=B^TPB,\qquad W=B^TPl
$$
则法方程与参数改正数分别为:
$$
N_{BB}X=W
$$
$$
X=N_{BB}^{-1}W=(B^TPB)^{-1}B^TPl
$$
在这个案例中,未知参数的顺序取为 $(P_1,P_2,P_3)$,对应的系数矩阵为:
$$
B=
\begin{bmatrix}
1&0&0\\
0&1&0\\
1&0&0\\
0&1&0\\
-1&1&0\\
-1&0&1\\
0&0&-1
\end{bmatrix}
$$
每一行只表达一条观测边对未知点高程的影响。例如,第五条边从 $P_1$ 指向 $P_2$,所以该行是 $(-1,1,0)$;第七条边从 $P_3$ 指向已知点 $B$,因而只保留 $P_3$ 的系数 $-1$。
## 解算后还能得到什么
求出 $X$ 后,程序还应继续完成结果回代,而不是只停在一个参数向量:
$$
\hat{X}=X^0+X
$$
$$
V=BX-l
$$
$$
\hat{L}=L+V
$$
这三步分别给出未知点平差值、观测改正数和观测值平差值。对于本例,最终高程为:
$$
\begin{aligned}
H_{P_1}&=6.37475734\ \mathrm{m}\\
H_{P_2}&=7.02785520\ \mathrm{m}\\
H_{P_3}&=6.61214227\ \mathrm{m}
\end{aligned}
$$
对应的改正数很小:
| 边号 | 改正数 $v$ / m | 平差后高差 / m |
| --- | ---: | ---: |
| 1 | -0.000243 | 1.358757 |
| 2 | 0.002855 | 2.011855 |
| 3 | -0.004243 | 0.358757 |
| 4 | -0.000145 | 1.011855 |
| 5 | -0.003902 | 0.653098 |
| 6 | -0.000615 | 0.237385 |
| 7 | -0.001142 | -0.596142 |
精度评定也必须伴随结果一起输出。若观测数为 $n$、未知参数数为 $t$,则多余观测数为:
$$
r=n-t
$$
单位权中误差为:
$$
\hat{\sigma}_0=\sqrt{\frac{V^TPV}{n-t}}
$$
未知参数的协因数阵与方差阵为:
$$
Q_{\hat{X}\hat{X}}=(B^TPB)^{-1}
$$
$$
D_{\hat{X}\hat{X}}=\hat{\sigma}_0^2Q_{\hat{X}\hat{X}}
$$
本例计算出的单位权中误差约为 $0.002225\ \mathrm{m}$。它不是某一个点的误差,而是这套观测在单位权意义下的整体精度指标。
## 程序实现:让流程可操作,而不只是可计算
将平差公式写成程序时,我把责任分开,而不是把所有逻辑堆在窗体事件里:
| 模块 | 责任 |
| --- | --- |
| `KnownPoint`、`Observation` | 保存已知点、观测边与距离等输入数据 |
| `DataCheck` | 检查空点名、重复点名、高差格式、正距离、与已知点的连通性、观测数量等 |
| `MatrixOperations` | 用二维数组实现加减乘、转置和求逆 |
| `LeastSquares` | 生成 $B$、$P$、$l$,解法方程并回代计算 |
| `DataStore` | 暂存已导入或手动录入的数据 |
| `Report` | 用 `StringBuilder` 组织平差报告,供预览或导出 |
| `LogService` | 记录导入、检查、计算与输出过程 |
整个交互流程可以概括为:
```text
导入/手动输入 → 数据检查 → 保存数据 → 平差计算 → 查看结果 → 输出报告
↑
检查失败则提示并返回输入
```
这里数据检查并非附属功能。若水准网中存在孤立点、观测边没有连到已知点,或者距离为零,后续矩阵即使“算出结果”也没有测量意义。因此,先验证网络可用性,再进入最小二乘计算,是程序层面对应理论前提的一道关口。
## 小结
这个案例把水准网间接平差压缩成了一条清晰的链路:观测数据决定权阵与常数项,网络拓扑决定系数矩阵,最小二乘条件导出法方程,回代和精度评定则让结果从“一个答案”变成可解释的测量成果。
对我来说,自己实现矩阵运算和法方程求解的价值不在于替代现成库,而在于真正看清 $B^TPB$、$B^TPl$ 和观测改正数是如何从一条条水准路线中生长出来的。