尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

MathorCup B题获奖论文拆解:熵权法+ILP+贪心算法搞定搬迁规划

MathorCup B题获奖论文拆解:熵权法+ILP+贪心算法搞定搬迁规划 简介面向城市规划师、政府决策人员和城市更新研究者这份获奖论文针对2025年MathorCup B题老城街区“平移置换”搬迁规划问题提供了一套从居民意愿量化到搬迁方案优化的完整建模思路。资源为单个PDF文档大小仅1.63MB内容覆盖熵权法-TOPSIS组合模型、整数线性规划ILP、贪心算法及多目标动态规划等核心方法并附有全部代码与详细附录便于读者复现和二次开发。文中结合具体街区数据展开求解实现了79个完整院落腾空、总收益约108602.1万元、总成本2080.39万元、性价比52.2等关键结果充分展示了模型在实际场景中的可行性和经济性。目前已有153人学习浏览适合需要借鉴获奖论文结构、算法实现或搬迁规划思路的数学建模参赛者、科研人员及政府相关从业者。1. 一份 B 题获奖论文拆解平移置换搬迁背后的三层模型链条2025年MathorCup B题“老城街区‘平移置换’搬迁规划”本质是一个城市更新背景下的决策优化问题把散居在各个院落的居民集中迁到杂院腾出尽可能多完整的院落为后续统一开发腾出空间。队伍编号 MC25008227 的这份获奖论文采用了“熵权法-TOPSIS 量化居民搬迁意愿 → 整数线性规划ILP生成搬迁方案 → 贪心算法判断性价比拐点”的三层组合解法最终在 2600 万成本预算内实现了 79 个完整院落腾空投入成本 2582 万元。它解决的不仅是“怎么搬”而是把“居民愿不愿意搬、谁搬到哪、值不值得继续搬”三个问题串成了一条可量化的链路。适合备赛数模、城市更新项目前期的方案推演以及想理解 ILP 与贪心如何搭配使用的人。下面按复现顺序把公式、参数和坑逐一展开。2. 熵权法-TOPSIS 量化搬迁意愿五个指标、一次排序、一处易错点2.1 影响搬迁意愿的五个指标和量化口径论文先把“居民愿不愿意搬”拆成五类可量化因素面积补偿度、采光舒适度、修缮投入度、街道距离便利度、房屋密集度。这个拆法的好处在于把“居住体验”“生活便利”这类主观诉求映射成有上下界的数值后续才能进入同一套评价框架。指标方向量化口径面积补偿度正向S面积 min(A迁入 / A现居, 1.3)采光舒适度正向正南/正北取4东厢取3西厢取2修缮投入度正向S修缮 5 (A地块 - A_min) / (A_max - A_min) × (20 - 5)单位万元街道距离便利度负向S街道 d_max - (A地块 - A_min) / (A_max - A_min) × (d_max - d_min)单位米房屋密集度峰型S密集 D_max - (A院落 - A_min) / (A_max - A_min) × (D_max - D_min)面积补偿度用 min 函数封顶到 1.3是一个很实用的设计。它表达的意思是迁入面积可以比原面积大但最大只认 1.3 倍超过的部分再大也不计入补偿评价。这样既保证居民面积不缩水又避免过度补偿推高成本。比如现居 80 平方米、迁入 100 平方米比值 1.25S面积就是 1.25迁入 110 平方米比值 1.375S面积只按 1.3 算。采光舒适度等级按朝向划分逻辑是正南正北采光最好东厢次之西厢最差。搬迁时要求迁入房屋的采光等级不低于现居房屋这也成为后续 ILP 模型里一条重要约束。修缮投入度则与地块面积挂钩最小地块 10 平方米对应 5 万最大地块 50 平方米对应 20 万面积越大修缮预算越高。街道距离便利度和房屋密集度要注意方向差别。街道距离便利度输出的是折算后的距离值越小代表离街道越近所以是负向指标房屋密集度原文说“数值接近 5 左右表明越符合居民心理预期”这是一个峰型指标而不是单调的正向或负向指标。复现时如果简单把它归为负向大院落会被整体低估排序结果会和直觉差很多。我一般会先做分箱看分布再决定是否保留原始表达。2.2 熵权法定权重、TOPSIS 排序的数学链条熵权法的作用是给五个指标定权重核心逻辑是某项指标在不同地块之间数据离散度越大它对“区分居民搬迁意愿”的贡献就越高权重也越大。计算顺序是对原始数据做正向或负向标准化 → 计算每个评价对象在第 j 个指标下的比重 p_ij → 用 p_ij 计算熵值 c_j → 用差异系数 g_j 1 - c_j 归一化得到权重 w_j。TOPSIS 接着处理权重后的标准化矩阵。先找正理想解和负理想解正理想解是每个指标都取最大值负理想解是每个指标都取最小值然后计算每个地块到正理想解的距离 d 和到负理想解的距离 d-最后用贴近度 C d- / (d d-) 排序。C 越接近 1说明该地块越接近理想状态居民接受度越高。这组组合模型的选型理由很明确数模场景下没有真实专家打分熵权法完全从数据出发可复现性强TOPSIS 又比简单加权求和更扛极端值避免一个指标异常直接把排序带偏。最终结果是地块 388 综合得分 0.823接受度最高地块 6 得分 0.547最低。得分高的地块建议优先沟通得分低的则意味着面积补偿、采光或者修缮投入上需要额外让步。2.3 Python 复现骨架标准化的方向要提前标清楚import numpy as np import pandas as pd def normalize_matrix(df, pos_cols, neg_cols): df_norm pd.DataFrame(indexdf.index) for col in pos_cols: x df[col].astype(float) df_norm[col] (x - x.min()) / (x.max() - x.min()) for col in neg_cols: x df[col].astype(float) df_norm[col] (x.max() - x) / (x.max() - x.min()) return df_norm def entropy_weight(Y): # Y: 标准化后的矩阵m 个评价对象n 个指标 m, n Y.shape P Y / Y.sum(axis0, keepdimsTrue) P np.clip(P, 1e-12, None) # 防止 ln(0) entropy -np.sum(P * np.log(P), axis0) / np.log(m) diff 1 - entropy w diff / diff.sum() return w def topsis_score(Y, w): Z Y * w zp Z.max(axis0) zn Z.min(axis0) dp np.sqrt(((Z - zp) ** 2).sum(axis1)) dn np.sqrt(((Z - zn) ** 2).sum(axis1)) return dn / (dp dn)这段代码的逻辑是先区分正向列和负向列分别标准化正向列越大越好负向列越小越好再用熵权法算权重最后用 TOPSIS 的贴进度公式出分。参数上要注意正向列传 pos_cols、负向列传 neg_cols如果某一项指标所有地块数值都一样它的熵值接近 1、差异系数接近 0权重也会非常小说明这项指标对排序没有区分度。这里最容易翻车的就是负向指标的方向。很多人用 sklearn 的 MinMaxScaler 顺手一放街道距离越远的地块得分反而越高第一版排序出来根本没法解释。我的习惯是在标准化函数里用 direction 参数显式标记方向而不是靠列名猜。另一个细节是房屋密集度这种峰型指标如果直接进熵权法最好先做一次居中变换或者单独说明方向否则权重解释会出问题。这套意愿得分并不直接作为 ILP 目标函数的系数它是给“先谈哪些居民”做优先级排序的。ILP 模型里用的是面积、采光、成本这些硬约束意愿得分负责优化沟通顺序。两套模型的分工不同复现时不要试图把 0.823 这种分值硬塞进整数规划目标里。3. 整数线性规划设计搬迁方案决策变量、四条约束与 Gurobi 求解3.1 为什么这个问题要选 ILP而不是启发式搜索搬迁规划问题的决策变量是“居民 × 空置地块”的二元配对再加上院落腾空标志天然就是 0-1 整数规划。地块规模在一百出头、居民数量几千量级时ILP 用分支定界可以拿到全局最优解而且约束表达非常自然。换用遗传算法或模拟退火虽然也能跑出可行解但每次结果会抖动还无法证明当前解是最优的。论文里问题二的回答目标是“腾空完整院落数量最多”这是单一主目标配上预算、面积、采光、唯一性这类线性约束正是整数线性规划的标准场景。启发式算法的典型应用场景是目标函数非线性、约束不可解析表达、或者规模大到精确求解器扛不住的情况而这里都不满足。所以选 ILP 不是因为听起来高级而是问题结构决定的。另外要区分问题二和问题三的定位。问题二要的是一个全局最优的搬迁方案问题三要的是判断“继续搬还值不值”是动态增量视角。这两个目标不同前者用 ILP后者用贪心属于同一份资源里两套模型各司其职。3.2 变量定义、目标函数和五条约束的数学表达模型里有两组二元变量X_ij 表示居民 i 是否搬迁到地块 jY_k 表示院落 k 是否完全腾空。目标函数是最大化腾空完整院落的数量也就是 max ΣY_k。注意这里没有直接把“搬迁人数最少”写进目标因为如果直接在目标里加人数惩罚会干扰主目标我一般会用 max ΣY_k - ε·ΣX_ij 的形式ε 取 0.001在保证腾空院落数不牺牲的前提下让模型优先选搬迁人数更少的方案。约束条件一共五类每一类都对应一个实际问题居民搬迁唯一性约束 Σ_j X_ij ≤ 1确保每个居民最多搬一次。这里用的是 ≤ 而不是 因为不是每个居民都必须搬迁强制搬迁会导致某些无法安置的居民进入不可行状态。地块容纳约束 Σ_i X_ij ≤ 1确保每个空置地块最多接收一个居民避免多个居民挤进同一地块造成安置混乱。院落腾空条件约束 Σ_{i∈k} Σ_j X_ij n_k · Y_k是整组模型的核心。它表达了院落 k 完全腾空当且仅当院内的 n_k 个居民全部搬迁。Y_k 是聚合状态X_ij 是底层动作两者通过这条等式耦合。成本约束要求面积损失成本、修缮成本、沟通成本之和不超过 2600 万。面积损失成本和修缮成本都和地块选择相关沟通成本和居民户数相关这条约束直接保证方案的经济可行性。面积与采光约束要求迁入地块面积 A_j 落在 [A_i, 1.3A_i] 区间内且迁入采光等级不低于原居住采光等级。这是一组硬性居住条件底线模型里通常先做一次预筛选把不满足条件的 X_ij 直接置 0而不是写进大约束里让求解器去搜索。3.3 Gurobi 求解骨架与结果复核import gurobipy as gp from gurobipy import GRB model gp.Model(relocation_ilp) X model.addVars(residents, plots, vtypeGRB.BINARY, nameX) Y model.addVars(courts, vtypeGRB.BINARY, nameY) # 主目标最大化腾空完整院落数量 model.setObjective(Y.sum(), GRB.MAXIMIZE) # 约束1每个居民最多搬迁一次 for i in residents: model.addConstr( gp.quicksum(X[i, j] for j in plots) 1, namefresident_once_{i}) # 约束2每个空置地块最多接收一户 for j in plots: model.addConstr( gp.quicksum(X[i, j] for i in residents) 1, namefplot_once_{j}) # 约束3院落k完全腾空 - 所有n_k户居民都搬走 for k in courts: idx resident_in_court[k] model.addConstr( gp.quicksum(X[i, j] for i in idx for j in plots) n_people[k] * Y[k], namefcourt_strict_{k}) # 约束4总成本不超过2600万 model.addConstr( gp.quicksum((C_area[i, j] C_repair[j] C_comm[i]) * X[i, j] for i in residents for j in plots) 26_000_000, namebudget) # 约束5面积与采光不满足的配对直接禁用 for i in residents: for j in plots: if A_plot[j] A_room[i] or A_plot[j] 1.3 * A_room[i]: model.addConstr(X[i, j] 0, namefarea_block_{i}_{j}) elif L_plot[j] L_room[i]: model.addConstr(X[i, j] 0, nameflight_block_{i}_{j}) model.Params.TimeLimit 300 model.Params.MIPGap 0.001 model.optimize()代码逻辑X 和 Y 都是二元变量主目标用 Y.sum() 最大化腾空院落数四条核心约束通过 addConstr 逐步加入。面积和采光约束我用了预筛选写法不满足条件的配对直接固定为 0这样求解器的搜索空间会小很多比把条件写成大 M 约束更高效。参数说明TimeLimit 300 是给求解器 300 秒上限防止死磕MIPGap 0.001 表示允许 0.1% 的优化间隙对这个规模的问题足够C_area 是面积损失成本C_repair 是修缮成本C_comm 是沟通成本单位都是元所以预算写 26_000_000。如果换用开源求解器可以改成 pulp CBC代码结构几乎不变。论文最终结果腾空 79 个完整院落投入成本 2582 万元腾空院落总面积 15703 平方米。前几组搬迁映射为原地块 34 → 搬入地块 365原地块 80 → 搬入 416原地块 81 → 搬入 124原地块 110 → 搬入 253原地块 111 → 搬入 483。完整 79 个院落的 ID 列表和搬迁映射在论文附录里。拿到结果后要做的不是看分数而是复核两个总量把 79 个 Y1 的院落面积加总应该接近 15703 平方米把方案里的三类成本加总应该不超过 2600 万。这两步不通过 Python 脚本做靠手工抄表很容易出错。我每次看到论文里这种“79 个、2582 万、15703 平方米”三个数字对齐都会下意识验一遍因为这三个数字一旦对不上整个方案的可信度就崩了。4. 贪心算法找性价比拐点收益增量、成本增量和阈值怎么设4.1 基准收益、增量收益和增量成本的计算口径问题三的第一步是算“不搬迁时”的基准收益。论文按朝向把地块分成东西厢 8 元/㎡/天、南北厢 15 元/㎡/天两档乘以十年 3650 天得到不搬迁状态下的租金收益 R0。这个基准收益是后面衡量“搬了到底多赚多少”的参照系。搬迁后完整院落的租金是 30 元/㎡/天如果院落属于毗邻院落租金在 30 元基础上提升 1.2 倍也就是 36 元/㎡/天。单个院落的收益增量 ΔR 就是搬迁后整院十年租金收益减去该院落不搬迁时的租金收益。这里的“毗邻”动态性很强搬完一个院落旁边院落可能从非毗邻变成毗邻所以 ΔR 不是静态值需要每轮迭代重新评估。成本增量 ΔC 由三块构成。沟通成本按 3 万/户计算乘以院落里的户数修缮成本按不超过 20 万/户的标准根据实际面积线性调整面积损失成本计算的是“迁入面积 - 原面积”这部分多补偿的面积乘以对应朝向租金标准后再乘 120 天也就是估算四个月的租金损失。注意面积补偿的上限是 1.3 倍原面积所以面积损失成本也有封顶不会无限膨胀。4.2 “性价比拐点”为什么用贪心而不是线性规划问题二的 ILP 是全局最优视角给定所有数据找出一个让腾空完整院落数最多的方案。问题三的视角完全不同它问的是“继续搬还值不值”这是典型的动态决策问题。现实中搬迁也是一批一批推进的先把性价比最高的院落谈下来再根据结果决定要不要继续。贪心算法恰好匹配这种决策节奏。每次从剩余未搬迁院落里选性价比 m ΔR / ΔC 最高的一个然后更新剩余院落的收益和成本状态。当某一步的 m 低于阈值 20 时说明每投入 1 万元只能带来不到 20 万元收益继续搬的经济动力不足。论文里还加了“连续 3 次趋势判断”作为防误判机制避免因为单个院落的特殊情况提前停止。阈值 20 的设定我理解是一个经验决策线。因为收益侧是十年租金累计成本侧是一次性投入所以比值天然会偏高20 这个数值意味着必须用十年周期摊薄来看才合理。实际复现时应该对这个阈值做敏感性分析而不是只贴一个固定值。这到后面第 6 章再说。论文在该问中的结果为搬迁 32 个整院总收益 108602.1 万元总成本 2080.39 万元整体性价比 52.2显著高于阈值 20因此当前数据下未出现性价比拐点。这里的 52.2 是 32 个院落加总后的整体比值不是某一轮的单步值。没有出现拐点说明当前搬迁集合仍处于收益快速增长区段但如果继续扩大规模高性价比院落数量会越来越少最终还是会进入递减区。4.3 贪心迭代代码骨架与拐点判定def greedy_relocation(candidates, threshold20.0, streak3): moved set() total_r R0 # 不搬迁基准收益 total_c 0.0 # 累计搬迁成本 low_count 0 # 连续低于阈值的轮次 while True: best_k None best_m -1.0 # 每轮选择性价比最高的未搬迁院落 for k in candidates: if k in moved: continue dr benefit_increment(k, moved) dc cost_increment(k, moved) if dc 1e-9: continue m dr / dc if m best_m: best_m m best_k k if best_k is None: break # 连续 streak 次低于阈值判定进入拐点区 if best_m threshold: low_count 1 if low_count streak: break else: low_count 0 moved.add(best_k) total_r benefit_increment(best_k, moved) total_c cost_increment(best_k, moved) return moved, total_r, total_c代码逻辑是标准的贪心模板内层循环找当前性价比最高的院落外层循环更新状态并判断终止条件。关键点是 benefit_increment 和 cost_increment 都接收 moved 集合作为参数因为毗邻关系会随搬迁进程变化。这里还有一个性能细节每轮全量重算所有未搬迁院落的增量和成本在几百个院落规模下没问题但规模上到几千时应该采用“只更新受影响邻域”的策略否则每轮 O(n) 的扫描会成为瓶颈。参数说明threshold 对应性价比阈值 20streak 对应连续 3 次判断dc 单位是万元。代码里 dc 加了一个 1e-9 的保护防止成本增量为 0 时除零报错。跑完后的结果可以用下面的表核对指标数值搬迁整院数32总收益108602.1 万元总成本2080.39 万元整体性价比52.2拐点是否出现未出现这里容易产生一个疑问问题三只搬了 32 个院总成本 2080 万问题二搬了 79 个院反而成本 2582 万是不是矛盾了不矛盾。问题二以腾空院落数量最大化为目标因此会搬很多成本偏高但能凑出完整院落的组合问题三只挑性价比最高的 32 个院落成本自然更低。两个问题的目标函数不同结论无法直接横向比较。5. 平移置换建模避坑实录指标、约束与求解器的高频故障复现这篇论文时踩过的坑按“现象 → 原因 → 解决”的格式整理如下。顺序基本就是实际复现过程中会遇到问题的先后顺序。5.1 负向指标标准化方向反了意愿得分与实际直觉相反现象第一版排序结果出来街道距离远的地块得分反而高于距离近的地块怎么看都不合理。分析原因后发现负向指标用了正向标准化的公式。原因街道距离便利度是负向指标数值越小代表离街道越近、生活越便利。但标准化时省略了方向判断直接用 (x - min) / (max - min)导致距离越远得分越高。房屋密集度如果也按单调方向处理还会带来第二层误差。解决在标准化函数里显式区分正负向负向用 (max - x) / (max - min)。更稳妥的做法是给每个指标配一个 direction 字段而不是靠列名记忆。房屋密集度这种峰型指标不要硬塞进正向或负向先做分布检查再决定是否单独处理。这一步错了后面所有地块排序、搬迁沟通优先级都会跟着错。5.2 Gurobi 报 Infeasible先别急着怀疑数据现象模型跑出来直接提示 Model is infeasibleY 变量全部输出 0腾空院落一个都没有。原因最常见的坑是院落腾空条件约束写成 ≤。写成 ≤ 时即使院落只搬走一部分居民约束也可能满足Y 会被引导到 1但这是错误的“半腾空”反过来如果面积约束预筛选和成本约束叠加过紧也可能导致居民完全找不到可迁入地块。还有一种情况是居民索引和院落住户数 n_k 对不上比如某院落实际有 3 户但数据里记成 2 户等式永远无法成立。解决先注释掉成本约束跑一次确认可行域非空再用 model.computeIIS() 输出不可行约束集合逐条检查。检查顺序我一般固定为索引对齐 → 腾空耦合约束写法 → 面积采光预筛选 → 成本约束松紧。如果是预算过紧导致无解就把 2600 万放宽到 2700 万观察腾空院落增量再在报告里说明这个增量的经济学含义。5.3 版本不一致导致 Gurobi 报错或结果对不上现象同一份代码在自己电脑上跑得好好的换到队友电脑上 import gurobipy 直接失败或者同样数据下最优解数量变了。原因Gurobi 版本、Python 位数、license 环境变量不一致都会导致这类问题。更隐蔽的是 MIPGap 默认值不同有的版本默认 1e-4有的版本默认 1e-2提前停止时拿到的解自然不同。解决代码里显式固定 m.Params.MIPGap 和 m.Params.Seed保证跨平台结果可复现requirements.txt 里固定 gurobi 版本。更重要的习惯是论文里的表格不要手动抄直接让脚本导出 CSV由 CSV 生成最终表格。这样即使换了环境跑出不同结果也能快速定位是版本问题还是模型问题而不是对着两份手工表发呆。5.4 贪心算法把面积损失成本算重性价比瞬间跌破阈值现象某个院落区位很好预期性价比应该很高但算出来的 m 不到 10直接触发了拐点判断导致提前停止。原因贪心成本里把“迁入面积 - 原面积”全部计入了面积损失又给修缮成本直接取 20 万/户的上限。实际上面积补偿只对超出原面积的部分折算并且迁入面积被限制在 [A_i, 1.3A_i] 区间内成本是有天然封顶的修缮成本也应该按实际面积在 5 万到 20 万之间线性取值而不是默认取满。解决面积损失成本写成 (A迁入 - A现居) × 对应朝向租金 × 120 天同时保证 A迁入 ≤ 1.3A现居修缮成本按面积线性插值。修正后 ΔC 降下来性价比才反映真实情况。这一条是问题三最容易翻车的地方很多团队在这里把结果凑出“拐点出现”的结论其实只是因为成本被高估了。5.5 论文结果和附录代码数量对不上现象复现时腾空院落 ID 数量和论文表里不一致或者 79 个院落的面积加总不等于 15703 平方米。原因论文结果可能是约束微调后跑的而附录代码是早期版本或者求解器非确定性导致在不同机器上拿到不同最优解还有人统计时把原本就空置的院落计入了腾空列表重复计数。解决定稿前把全流程重新跑一遍输出 Y1 的院落 ID、面积、成本三个 CSV再用一个校验脚本核对三个总量腾空院落数是否为 79、面积和是否为 15703、成本是否小于等于 2600 万。这里没有后悔药唯一的办法就是所有表格从脚本输出生成不经过手工转录。从那以后我每次看到“79”这个数字第一反应都是先加一遍面积再说话。6. 提交前多一步参数敏感性检查与结果复核技巧这类论文最怕的就是一问参数就翻车。评审或者后续使用者大概率会问面积补偿上限 1.3 改成 1.479 个腾空院落还能保住吗贪心阈值 20 改成 15 或 30拐点结论还成立吗所以在定稿前我会把关键参数都做一组邻域扰动测试确认结论不是只在一个参数点上成立。实操做法是固定其余参数逐个扰动关键值面积补偿上限从 1.3 分别改成 1.17 和 1.43成本预算从 2600 万改成 2340 万和 2860 万贪心阈值从 20 改成 18 和 22连续判断次数从 3 改成 2 和 4。每改一次完整跑一遍问题二和问题三记录腾空院落数、总成本、整体性价比以及是否出现拐点。整理成一张敏感性表放在论文附录或答辩材料里远比只说“结果稳定”有说服力。扰动参数参数值腾空院落数变化拐点结论变化面积补偿上限1.17 / 1.3 / 1.43轻微下降 / 基准 / 轻微上升均未出现成本预算2340 / 2600 / 2860 万成本收紧时下降均未出现贪心阈值18 / 20 / 22视数据变化无翻转这张表是敏感性框架的示意图具体数值要根据自己的计算结果填入。如果某个参数的微小变化导致拐点出现或消失那论文里必须明确写出该参数的确定依据而不是藏起来。比如阈值 20 到底怎么来的至少要给一个“阈值从 15 到 30 扫描拐点位置只在阈值超过 26 时出现”之类的说明。复核顺序我也固定一个习惯第一步核总量腾空院落数、面积和、成本三条线必须用脚本对平第二步核约束随机抽 10 个腾空院落手工检查每个院落是否所有居民都搬出、搬入地块是否满足面积采光条件第三步核拐点把阈值从低到高扫一遍确认结论是否稳健。之前在一道类似的搬迁题上吃过亏拍脑袋设了阈值 15答辩时评委问“为什么不是 20”当场答不上来。从那以后我每次做完数模模型都强制自己把所有关键参数跑一遍邻域敏感性区间再做结论。这份论文的完整推导和附录 Python 代码值得拉下来对着跑一遍建议先跑问题一的标准化再跑问题二 ILP最后把问题三阈值从 10 到 30 扫一遍你会明显看到整套模型的设计取舍。希望帮到你。本文还有配套的精品资源点击获取
返回列表