CODAS-组合距离评价法
CODAS(Combinative Distance-based Assessment,组合距离评价法)是一种基于负理想解距离的多指标综合评价方法。其核心思想是:先对原始指标矩阵进行标准化和加权,构造加权标准化矩阵;然后以各指标上的最小值作为负理想解,分别计算各方案到负理想解的…
CODAS-组合距离评价法
1. 方法概述
CODAS(Combinative Distance-based Assessment,组合距离评价法)是一种基于负理想解距离的多指标综合评价方法。其核心思想是:先对原始指标矩阵进行标准化和加权,构造加权标准化矩阵;然后以各指标上的最小值作为负理想解,分别计算各方案到负理想解的欧氏距离与曼哈顿距离;最后通过方案两两比较形成相对评价矩阵,并按综合得分进行排序。
就本项目的具体实现而言,CODAS 模块并非只支持“单一标准公式”,而是做了以下工程化扩展:
- 指标类型支持正向指标、负向指标与适度指标;
- 标准化方法支持
codas、min_max与z_score三种口径; - 权重既可以由熵权法自动计算,也可以由用户在独立页面中自定义;
- 结果页除整体 CODAS 结果外,还支持对部分指标子集再次计算并追加写入 Excel。
设共有 \(m\) 个方案、\(n\) 个参与评价的指标,原始决策矩阵记为
$$ X=(x_{ij})_{m\times n}, \quad i=1,2,\ldots,m, \quad j=1,2,\ldots,n \tag{1} $$
其中 \(x_{ij}\) 表示方案 \(A_i\) 在指标 \(C_j\) 上的原始观测值。
2. 输入结构、指标类型与预处理
2.1 输入文件结构
当前项目上传页 ui/upload_widget.py 要求输入文件满足如下结构:
- 第 1 列为方案名称(对象名称);
- 第 2 列及之后为指标列;
- 指标列必须是数值型,且不允许空值;
- 第 1 列方案名称不能重复;
- 上传页验证逻辑默认不接受常数列。
因此,在界面正常流程下,项目实际进入 CODAS 计算的是一个“首列为方案名、其余列为数值型指标”的标准矩阵。若研究者直接调用 core/codas_calculator.py,即使绕过界面验证,核心代码也仍会对数值列执行 to_numeric 转换,并在标准化阶段对异常情形做兜底处理。
2.2 指标类型
项目中的指标类型分为三类:
- 正向指标:值越大越优;
- 负向指标:值越小越优;
- 适度指标:存在给定目标值,越接近该目标值越优。
对于适度指标,程序并不是直接设计新的 CODAS 标准化公式,而是先将其转换为“偏离目标值的绝对偏差”,再把该偏差视作负向指标处理。设第 \(j\) 个适度指标的标准值为 \(s_j^\ast\),则转换后变量为
$$ d_{ij}=\left|x_{ij}-s_j^\ast\right| \tag{2} $$
式(2)越小,表示方案越接近目标值,因此在项目内部会被改写为负向指标参与后续标准化。
需要注意的是,当前 ui/indicators_widget.py 与 core/codas_calculator.py 都要求适度指标必须给出非零标准值;若缺失或为 0,程序会直接报错。
3. 标准化方法
3.1 CODAS 推荐比例归一化
当用户选择 codas 标准化时,项目采用 CODAS 中最常见的比例归一化形式。
对正向指标,有
$$ n_{ij}=\frac{x_{ij}}{\max_i x_{ij}} \tag{3} $$
对负向指标,有
$$ n_{ij}=\frac{\min_i x_{ij}}{x_{ij}} \tag{4} $$
若某指标原本是适度指标,则先按式(2)转换为偏差变量 \(d_{ij}\),再把 \(d_{ij}\) 代入式(4)进行归一化。
这一实现与 core/codas_calculator.py::_normalize 完全一致。需要补充说明的是:在代码层面,若负向指标存在 \(x_{ij}=0\) 的情况,程序会先把分母中的 0 替换为缺失值,再将无穷值与缺失值补成 0,因此结果中不会出现无穷大,但该列可能退化为接近 0 的数值列。
3.2 Max-Min 归一化
当用户选择 min_max 时,项目采用区间归一化。
对正向指标,有
$$ n_{ij}=\frac{x_{ij}-\min_i x_{ij}}{\max_i x_{ij}-\min_i x_{ij}} \tag{5} $$
对负向指标,有
$$ n_{ij}=\frac{\max_i x_{ij}-x_{ij}}{\max_i x_{ij}-\min_i x_{ij}} \tag{6} $$
若某列满足 \(\max_i x_{ij}=\min_i x_{ij}\),则核心代码会直接把该列标准化结果记为 0。虽然上传页通常会提前拦截常数列,但这一兜底逻辑仍然存在于 core/codas_calculator.py 中。
3.3 Z-score 后再映射到 \([0,1]\)
当用户选择 z_score 时,程序先按列做标准分数变换:
$$ z_{ij}=\frac{x_{ij}-\mu_j}{\sigma_j} \tag{7} $$
然后对 \(z_{ij}\) 再做一次 Min-Max 映射。对正向指标,有
$$ n_{ij}=\frac{z_{ij}-\min_i z_{ij}}{\max_i z_{ij}-\min_i z_{ij}} \tag{8} $$
对负向指标,则取方向翻转后的形式:
$$ n_{ij}=1-\frac{z_{ij}-\min_i z_{ij}}{\max_i z_{ij}-\min_i z_{ij}} \tag{9} $$
若某列标准差为 0,或 \(\max_i z_{ij}=\min_i z_{ij}\),项目同样会把该列标准化结果置为 0。
4. 权重确定
4.1 熵权法
若用户选择熵权法,项目直接基于标准化矩阵 \(N=(n_{ij})\) 计算权重。首先定义第 \(j\) 个指标在第 \(i\) 个方案上的比重为
$$ p_{ij}=\frac{n_{ij}}{\sum_{k=1}^{m}n_{kj}} \tag{10} $$
然后计算熵值
$$ e_j=-\frac{1}{\ln m}\sum_{i=1}^{m}p_{ij}\ln p_{ij} \tag{11} $$
差异系数定义为
$$ g_j=1-e_j \tag{12} $$
最终熵权为
$$ w_j=\frac{g_j}{\sum_{k=1}^{n}g_k} \tag{13} $$
项目在实现时还加入了两个兜底规则:
- 当方案数 \(m\le 1\) 时,直接返回等权;
- 当 \(\sum_j g_j=0\) 时,也退化为等权。
4.2 自定义权重
若用户选择自定义权重,则权重并不是直接在方法页中录入,而是跳转到独立页面 ui/weight_editor_widget.py 进行编辑。用户可以:
- 手工输入每个指标的权重;
- 触发“平均分配权重”;
- 在保存时若权重和不等于 1,则允许程序自动归一化到 1。
记用户录入的原始权重为 \(\hat{w}_j\),则项目实际参与计算时会再次做归一化处理:
$$ w_j=\frac{\hat{w}_j}{\sum_{k=1}^{n}\hat{w}_k} \tag{14} $$
在主窗体 ui/main_window.py 中,自定义权重会先按全体指标保存;而在 CODASCalculator.set_weights() 中,又会按当前选中的指标子集重新取值并归一化。因此,最终进入计算的 \(w_j\) 与当前实际参与 CODAS 的指标集合保持一致。
5. CODAS 核心计算过程
5.1 加权标准化矩阵与负理想解
在得到标准化矩阵 \(N=(n_{ij})\) 与权重向量 \(w=(w_1,\ldots,w_n)^\top\) 后,项目先计算加权标准化矩阵:
$$ v_{ij}=w_j n_{ij} \tag{15} $$
记
$$ V=(v_{ij})_{m\times n} \tag{16} $$
随后,以各列最小值构造负理想解:
$$ n_j^-=\min_{1\le i\le m} v_{ij} \tag{17} $$
这与 core/codas_calculator.py 中 neg_ideal = v.min(axis=0) 的实现一致。
5.2 欧氏距离与曼哈顿距离
设方案 \(A_i\) 对应的加权标准化向量为 \(v_i=(v_{i1},\ldots,v_{in})\),则其到负理想解的欧氏距离定义为
$$ E_i=\sqrt{\sum_{j=1}^{n}\left(v_{ij}-n_j^-\right)^2} \tag{18} $$
曼哈顿距离定义为
$$ T_i=\sum_{j=1}^{n}\left|v_{ij}-n_j^-\right| \tag{19} $$
项目结果中的 距离 工作表正是由式(18)与式(19)生成。
5.3 相对评价矩阵与综合得分
设阈值参数为 \(\tau\),其默认值为 \(0.02\),并由方法设置页中的 QDoubleSpinBox 录入。当前实现约定:当两个方案的欧氏距离差异足够显著时,才额外计入曼哈顿距离差异。因此,相对评价矩阵 \(H=(h_{ik})\) 的元素定义为
$$ h_{ik}= \begin{cases} \left(E_i-E_k\right)+\left(T_i-T_k\right), & \left|E_i-E_k\right|\ge \tau \\[4pt] E_i-E_k, & \left|E_i-E_k\right|<\tau \end{cases} \tag{20} $$
式(20)与核心代码中的
h[i, k] = de + dt if abs(de) >= tau else de
完全一致。
在此基础上,方案 \(A_i\) 的 CODAS 综合得分定义为
$$ S_i=\sum_{k=1}^{m}h_{ik} \tag{21} $$
最终按 \(S_i\) 从大到小排序,得到方案排名:
$$ \operatorname{Rank}(A_i)=\operatorname{rank}_{\downarrow}(S_i) \tag{22} $$
项目导出的 得分与排名 工作表包含 欧氏距离E、曼哈顿距离T、CODAS综合得分S 与 排名,即对应式(18)—式(22)。
6. 项目输出结构与扩展功能
6.1 Excel、图表与复现文件
本项目当前会把 CODAS 结果保存到 results/<算法名>分析结果_<时间戳>/ 目录下,并默认导出以下 Excel 工作表:
参数原始数据标准化矩阵指标权重加权矩阵负理想解距离得分与排名相对评价矩阵H熵权法(仅在使用熵权法时出现)图表清单
与此同时,程序还会生成三类图表:
codas_scores.png:CODAS 综合得分条形图;weights.png:指标权重条形图;distances.png:欧氏距离与曼哈顿距离散点图。
除图表外,结果目录中还会包含:
repro_inputs/input_snapshot.xlsx:本次计算使用的输入快照;repro_codas_<时间戳>.py:自动生成的复现实验脚本。
该复现实验脚本会记录所选指标、指标类型、适度指标标准值、权重方法、标准化方法、\(\tau\) 与期望输出结果,并重新调用 CODASCalculator 完成一次独立复算。
6.2 部分指标子集 CODAS
当前结果页 ui/results_widget.py 还支持“分层计算”或“部分指标 CODAS”功能。其实现方式是:
- 先完成一次整体 CODAS 计算并保存主结果文件;
- 在结果页勾选部分指标;
- 调用
calculate_partial_codas(indicators)仅对该指标子集重新计算; - 将子集结果追加写入最近一次结果 Excel,默认工作表前缀为
子集得分排名。
因此,本项目不仅能输出“全指标排序”,还可用于论文中的指标删减分析、局部稳健性分析或分层比较分析。
6.3 当前实现中的若干注意事项
- 上传页默认不允许常数列,但核心标准化函数仍保留“常数列置 0”的兜底逻辑;
- 旧版
utils/data_validator.py中的方法校验仍保留历史口径,但当前真实界面与核心计算器实际支持的是codas、min_max、z_score三种标准化方式; - 自定义权重的编辑页以“全指标集合”为对象,而实际计算时会按选中指标子集重新对齐和归一化。
这些细节都属于项目实现特征,论文中若要完整复现本软件结果,建议以 ui/main_window.py、ui/methods_widget.py 与 core/codas_calculator.py 的当前行为为准。
7. 论文写作模板
若本文采用本项目中的 CODAS 模块对方案进行多指标综合评价,可按如下方式描述:
首先构建原始决策矩阵,并依据指标属性将各指标划分为正向指标、负向指标和适度指标;其中适度指标先按目标值转换为绝对偏差形式。随后对指标矩阵进行标准化处理,并采用熵权法或专家给定权重确定指标权重,进而构造加权标准化矩阵。以各指标上的最小加权值作为负理想解,分别计算各方案到负理想解的欧氏距离与曼哈顿距离,并结合阈值参数 \(\tau\) 构造相对评价矩阵。最后对相对评价矩阵按行求和得到 CODAS 综合得分,并据此完成方案排序。
若本文使用的是本项目的扩展功能,还可进一步补充:
为检验指标体系变动对排序结果的影响,本文进一步在整体 CODAS 结果基础上,对若干指标子集重新计算 CODAS 综合得分,并将其与全指标结果进行对比分析。
8. 与代码实现的对应关系
表 1 CODAS 关键公式与项目实现对应关系
| 内容 | 数学表达 | 项目实现 |
|---|---|---|
| 原始决策矩阵 | 式(1) | ui/upload_widget.py、core/codas_calculator.py::_prepare_matrix |
| 适度指标偏差转换 | 式(2) | core/codas_calculator.py::_prepare_matrix |
| 三种标准化方式 | 式(3)—式(9) | core/codas_calculator.py::_normalize |
| 熵权法 | 式(10)—式(13) | core/codas_calculator.py::_entropy_weights |
| 自定义权重归一化 | 式(14) | ui/weight_editor_widget.py、core/codas_calculator.py::set_weights |
| 加权矩阵与负理想解 | 式(15)—式(17) | core/codas_calculator.py::calculate_codas |
| 欧氏距离与曼哈顿距离 | 式(18)—式(19) | core/codas_calculator.py::calculate_codas |
| 相对评价矩阵与综合得分 | 式(20)—式(22) | core/codas_calculator.py::calculate_codas |
| Excel、图表、复现脚本与子集追加 | 第 6 节 | core/codas_calculator.py::save_results、append_layer_results、ui/results_widget.py |
总体来看,本项目中的 CODAS 属于“保留经典负理想距离排序主线,同时扩展指标类型、标准化方式、权重来源与子集分析”的工程化实现。对论文写作而言,建议把式(15)—式(22)作为方法主体,再结合式(2)—式(14)说明当前软件在数据预处理与权重确定方面的具体口径。
9. 论文模板补充
9.1 方法描述模板
“本文采用 CODAS 方法对候选方案进行多指标综合评价。首先对原始决策矩阵进行指标类型处理与标准化,并结合熵权法或自定义权重构造加权标准化矩阵;随后以负理想解为参照,分别计算各方案到负理想解的欧氏距离和曼哈顿距离,并结合阈值参数 \(\tau\) 构造相对评价矩阵,最终依据综合得分完成排序。”
9.2 结果解释模板
结果部分可写为:结果表明,方案到负理想解的距离越大,说明其越远离劣解,从而综合表现越优。若欧氏距离差异已足够明显,则曼哈顿距离对最终排序的修正作用较弱;若欧氏距离差异接近阈值 \(\tau\),则曼哈顿距离的辅助判别作用会更明显。
9.3 表格标题模板
- 表 1 CODAS 参数与权重设置表
- 表 2 CODAS 欧氏距离、曼哈顿距离与综合得分结果表
- 表 3 CODAS 相对评价矩阵结果表
- 表 4 CODAS 子集指标重算结果表
9.4 图表题注模板
- 图 1 CODAS 指标权重分布图。
- 图 2 CODAS 综合得分排序图。
- 图 3 CODAS 子集指标评价结果对比图。
9.5 表格示例
表 1 CODAS 综合评价结果表示例
| 方案 | 欧氏距离 | 曼哈顿距离 | 综合得分 | 排名 |
|---|---|---|---|---|
| \(A_1\) | ||||
| \(A_2\) |
表注:综合得分由相对评价矩阵按行求和得到,数值越大表示方案越优。
10. 单篇终审补充
10.1 图题与表题对齐建议
参数表可写为:表X CODAS 参数设置表。原始数据表可写为:表X CODAS 原始决策矩阵表。标准化矩阵表可写为:表X CODAS 标准化矩阵表。指标权重表可写为:表X CODAS 指标权重表。加权矩阵表可写为:表X CODAS 加权矩阵表。负理想解表可写为:表X CODAS 负理想解表。距离表可写为:表X CODAS 欧氏距离与曼哈顿距离结果表。得分与排名表可写为:表X CODAS 综合得分与排序表。相对评价矩阵H表可写为:表X CODAS 相对评价矩阵 H 表。熵权法表可写为:表X CODAS 熵权法计算表。图表清单表可写为:表X CODAS 图表索引与路径表。weights.png建议写为:图X CODAS 指标权重分布图。distances.png建议写为:图X CODAS 距离对比图。codas_scores.png建议写为:图X CODAS 综合得分图。
10.2 终审说明
- 当前代表性结果目录可采用
results/__codex_codas_direct_run_fix_20260321/CODAS-组合距离评价法分析结果_20260321_033908。其中主工作簿为CODAS-组合距离评价法分析结果_20260321_033908.xlsx。 - 当前真实工作表为
参数/原始数据/标准化矩阵/指标权重/加权矩阵/负理想解/距离/得分与排名/相对评价矩阵H/熵权法/图表清单。论文表题应按这套中文 sheet 名落地。 - 当前稳定实体图文件为
charts/weights.png、charts/distances.png、charts/codas_scores.png。如果正文需要解释排序依据,应把距离工作表与distances.png一并引用,而不是只引用最终得分图。 - 真实 repro 脚本为
repro_codas_20260321_033908.py,并通过INPUT_FILE = SCRIPT_DIR / 'repro_inputs/input_snapshot.xlsx'读取输入快照,再输出到repro_outputs/。附录中的复现实验说明应保持这一repro_inputs + repro_outputs目录结构口径。 - 当前 repro 脚本还会校验方案顺序、排名和
CODAS综合得分S是否与主结果一致。因此论文若要强调可复现性,可以明确说明结果包不仅支持重算,还包含数值一致性校验。
10.3 全量强化补充
- 当前 CODAS 文档已按真实磁盘证据补强,完整代表目录为
具体的算法3/多指标评价/CODAS-组合距离评价法/results/__codex_codas_direct_run_fix_20260321/CODAS-组合距离评价法分析结果_20260321_033908。 - 该目录首层主结果工作簿为
CODAS-组合距离评价法分析结果_20260321_033908.xlsx,实际工作表为参数、原始数据、标准化矩阵、指标权重、加权矩阵、负理想解、距离、得分与排名、相对评价矩阵H、熵权法、图表清单。 - 首层主图目录为
charts/,真实图文件为weights.png、distances.png、codas_scores.png。其中distances.png应与距离工作表成对解释,codas_scores.png应与得分与排名工作表成对解释,weights.png应与指标权重或熵权法工作表成对解释。 - 该目录首层存在标准复现入口
repro_codas_20260321_033908.py,输入快照为repro_inputs/input_snapshot.xlsx,输出目录为repro_outputs/,脚本关键口径是INPUT_FILE = SCRIPT_DIR / 'repro_inputs/input_snapshot.xlsx'与OUTPUT_DIR = SCRIPT_DIR / 'repro_outputs'。 - 需要区分的是,
repro_outputs/内又生成了新的CODAS-组合距离评价法分析结果_20260321_033909/,其内部还继续保留了一层repro_outputs/CODAS-组合距离评价法分析结果_20260329_132239/。这些是复现脚本重复执行后的再生产物链,不应与首层20260321_033908主结果混写成同一次导出。 - 因此正文与附录应采用“三层证据”表述:首层主运行结果用于论文直接引用,
repro_inputs/input_snapshot.xlsx用于说明输入快照,repro_outputs/...用于说明复现后可再生成结果。 - 若论文强调数值可复核性,可以补充说明当前 repro 脚本不是仅生成文件,还会检查方案顺序、排名与
CODAS综合得分S的一致性,这一点比普通图表导出更适合作为复现实验依据。
11. 软件实现核查补充(2026-07)
- 当前实现的主结果目录应写作
具体的算法3/多指标评价/CODAS-组合距离评价法/results/__codex_codas_direct_run_fix_20260321/CODAS-组合距离评价法分析结果_20260321_033908,主工作簿以CODAS-组合距离评价法分析结果_20260321_033908.xlsx为准。 - 正文应围绕
参数、原始数据、标准化矩阵、指标权重、加权矩阵、负理想解、距离、得分与排名、相对评价矩阵H、熵权法、图表清单来写。 - 图证应对应
charts/weights.png、charts/distances.png、charts/codas_scores.png。 repro_codas_20260321_033908.py + repro_inputs/input_snapshot.xlsx是标准repro_inputs + repro_outputs口径,正文和附录应明确区分主结果与再生产物。