十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

组合优化与凸优化课程实验指南:算法实现与报告写作全解析

组合优化与凸优化课程实验指南:算法实现与报告写作全解析 简介哈工大组合优化与凸优化研究生课程实验资料包面向需要系统理解离散优化与凸优化理论的研究生和工程人员通过动手实验掌握动态规划、贪心、梯度下降、内点法等经典算法。压缩包共262个文件约47.1MB包含128个bmp和100个png图像用于实验结果可视化与数据集展示12个Python脚本及对应pyc文件用于算法实现配套xml/iml工程配置、mat数据文件和all-data数据集结构完整便于复现。实验覆盖无约束优化与有约束优化两大主题从一维搜索、梯度下降到线性规划、惩罚函数与内点法实验报告详细记录问题背景、求解步骤与结果分析说明书则给出清晰的操作指引。资源提供全套实验代码、可视化图表和撰写规范的报告适合研究生课程学习、期末复习或优化算法入门参考。目前已有294人学习下载。1. 组合优化与凸优化研究生课程实验这个包应该怎么读一个命名规规矩矩的包“哈工大组合优化与凸优化研究生课程实验内含实验报告和说明书.zip”本质上不是一份现成的答案而是一套需要你还原出完整实验流程的素材。组合优化和凸优化是两类不同的数学优化体系前者面对离散决策变量后者面对连续可微目标课程实验往往要求你在同一个报告里既有理论推导又有可复现代码还要把实验结果组织成说明书。我接下来按常见实验设计把整个包拆开告诉你每一部分该用什么算法实现、报告怎么写、最终怎么打包成一个能直接交的ZIP。适合正在做这门课实验的研究生也适合把这类问题当面试准备的工程师。2. 组合优化实验从建模到分支定界的落地写法2.1 先判断问题的难度P、NP-hard还是可近似组合优化实验几乎不会让你从零发明算法而是让你在几个经典模型里选一个TSP、背包、指派、最大割。课程实验对应的通常是一个离散优化问题以0-1背包最典型因为状态空间清晰且便于验证最优解。我在动手前会先做两件事一是把问题写成整数规划或0-1规划的数学形式二是判断规模。比如给定物品数n和背包容量C价值为v、重量为w这类问题当n越过40时暴力枚举就非常吃力必须用分支定界或动态规划。分支定界的思想是把原始问题的解空间分成子集用松弛问题的解作界剪掉不可能优于当前最优解的分支。对于最大化背包问题上界可以用连续背包松弛来计算——把剩余容量按价值密度从高到低装满。这个上界越紧剪枝效率越高。2.2 用Python写一个背包问题的分支定界骨架下面这版代码不是最优工程实现而是用于课程实验展示算法逻辑的最小骨架import heapq def bound(i, n, w, v, cap, cur_v, cur_w): 计算从第i个物品开始可能达到的价值上界 if cur_w cap: return 0 total_v cur_v remain cap - cur_w j i while j n and w[j] remain: remain - w[j] total_v v[j] j 1 if j n: total_v v[j] * remain / w[j] return total_v def knapsack_branch_bound(n, w, v, cap): # 按价值密度降序排序 items sorted(range(n), keylambda idx: -v[idx] / w[idx]) w [w[i] for i in items] v [v[i] for i in items] best 0 best_sol [0] * n # 使用最大堆因为heapq是最小堆取负值 heap [] heapq.heappush(heap, (0, 0, 0, 0, [])) # (-cur_v, level, cur_v, cur_w, path) while heap: neg_v, level, cur_v, cur_w, path heapq.heappop(heap) if level n: continue # 选择当前物品 if cur_w w[level] cap: new_v cur_v v[level] new_path path [1] if new_v best: best new_v best_sol new_path [0] * (n - level - 1) if level 1 n and bound(level 1, n, w, v, cap, new_v, cur_w w[level]) best: heapq.heappush(heap, (-new_v, level 1, new_v, cur_w w[level], new_path)) # 不选当前物品 new_v cur_v new_path path [0] if level 1 n and bound(level 1, n, w, v, cap, new_v, cur_w) best: heapq.heappush(heap, (-new_v, level 1, new_v, cur_w, new_path)) return best, best_sol这段代码的bound函数是整个分支定界的核心它把剩余容量按价值密度连续填充得到当前分支的价值上界。只有当上界超过当前已知最优解时才入堆否则直接剪枝。参数n、w、v、cap分别对应物品数、重量列表、价值列表和背包容量堆里存储的二元组把cur_v取负是为了借用heapq实现最大堆。注意排序后返回的解对应的是排序后的物品顺序实验报告里需要再做一次映射回原顺序。2.3 参数选择和启发式算法的边界分支定界适合n在几十到几百之间的问题一旦物品数超过三四百上界可能不够紧队列会膨胀到内存吃紧。这时实验通常会允许你换用启发式算法。模拟退火、遗传算法这类方法不保证最优但能在秒级给出不错的结果。我一般用两个指标来选问题规模是否超过分支定界的可解上限以及是否要求最优解。课程实验要求的往往是最优解或指定gap所以优先分支定界或动态规划不要一开始就上启发式。下面这张表总结了组合优化实验中常见的算法定位写报告时可以对照算法适用规模解质量运行时间实验报告重点暴力枚举n 20最优指数级说明状态空间爆炸动态规划n * C 可存下最优伪多项式状态转移方程分支定界n 200最优依赖上界紧度剪枝策略与界的选择模拟退火n 较大近似可调温度退火曲线遗传算法n 较大近似种群规模影响大选择、交叉、变异设计写报告时通常要给出至少一个精确算法和一个启发式算法的对比这样才能体现对组合优化“可解性”的理解。很多同学只贴结果不放剪枝过程分数上不去原因就在这里。2.4 组合优化实验的自测指标实验报告里不能只说“运行成功”。你需要记录三组数值最优解与已知下界的差距、运行时长、内存占用。对于随机生成的数据可以先用小的n验证算法能找到穷举最优再放大规模记录时间曲线。把时间-规模数据画成对数坐标图几乎能直接看出算法是否指数增长。这个图比几十页推导更有说服力。3. 凸优化实验梯度下降、牛顿法与对偶的代码路径3.1 凸函数判定与实验目标设计凸优化实验的第一步不是写代码而是先确认目标函数是凸的。你拿到实验题时可能给的是一个带约束的二次规划或最小二乘问题。要验证凸性最可靠的方法是检查定义域内Hessian矩阵是否半正定。对不可导函数则用定义式对任意两点判断。课程实验很多是线性回归或逻辑回归损失函数天然凸但不要跳过判定因为报告需要你写这一句。我一般会在代码里先做一个Hessian计算import numpy as np def hessian_check(X, y, theta): 线性回归目标函数的Hessian应为半正定 m len(y) H (X.T X) / m # 检查所有特征值是否大于等于0 eigvals np.linalg.eigvalsh(H) return H, eigvals X np.random.randn(50, 5) y np.random.randn(50) H, eigvals hessian_check(X, y, None) print(最小特征值:, eigvals.min())这里的X是设计矩阵y是观测向量。线性回归目标函数为 ||y - X theta||^2 / (2m)其Hessian是(X^T X)/m只要样本数足够且特征不共线特征值非负。注意这里为什么除以m目的是让目标函数和梯度量级不随数据量增长实验里很多收敛问题都源于忘记归一化。3.2 梯度下降和牛顿法的参数怎么设凸优化的核心实验通常比较三种一阶/二阶优化器普通梯度下降、带动量的梯度下降、牛顿法。下面是一个收敛对比的最小实现def gradient_descent(X, y, lr0.1, iter_max200, tol1e-6): m, n X.shape theta np.zeros(n) history [] for _ in range(iter_max): grad (X.T (X theta - y)) / m theta - lr * grad history.append(np.linalg.norm(grad)) if history[-1] tol: break return theta, history def newton_method(X, y, iter_max50, tol1e-8): m, n X.shape H (X.T X) / m theta np.zeros(n) history [] for _ in range(iter_max): grad (X.T (X theta - y)) / m delta np.linalg.solve(H, grad) theta - delta history.append(np.linalg.norm(grad)) if history[-1] tol: break return theta, history这里的lr是学习率tol是梯度范数的终止阈值。普通梯度下降对学习率非常敏感lr太大会震荡太小则收敛慢。牛顿法直接求解线性系统相当于用曲率缩放梯度所以不需要学习率但代价是每次迭代需要解一个n乘n线性方程组特征多时计算量很大。你可以把两者跑在同一份数据上画出梯度范数随迭代次数的下降曲线然后检查实验报告里的收敛对比表。下面是参数的一个经验范围参数/方法常用值说明学习率 lr0.01 到 0.3过大发散过小收敛慢迭代次数100 到 1000配合tol停止梯度范数 tol1e-6太松会提前停到较差解牛顿法迭代一般不超过30二阶收敛但每步开销高特征缩放必须不缩放的梯度下降可能非常慢3.3 约束优化从拉格朗日对偶到KKT条件的验证组合优化和凸优化在约束处理上思路不同。凸优化实验会给出一个带约束的线性规划或二次规划要求你写出拉格朗日函数并用对偶问题求最优解。一个最小例子是最小化 0.5 x^2约束 x 1。拉格朗日函数 L(x, lambda) 0.5x^2 - lambda*(x-1)lambda 0。对x求导得到 x lambda代入原问题得到对偶函数 g(lambda) -0.5lambda^2 lambda。最大化这个凹函数得到lambda 1所以x 1。这个解满足原问题的约束且互补松弛条件 lambda*(x-1)0成立。代码里验证KKT只需要几步import numpy as np def check_kkt(x, grad_f, grad_h, lam): # 稳定性梯度加上约束梯度的线性组合应为0 print(stationarity:, np.dot(grad_f(x) lam * grad_h(x), grad_f(x) lam * grad_h(x))) print(primal feasible:, x - 1 0) print(dual feasible:, lam 0) print(complementary:, lam * (x - 1))实际参数x1, lambda1四个条件全满足。需要注意的是对于非凸问题KKT是必要条件而非充分条件报告里要写明约束规格如Slater条件以保证对偶强对偶性成立。3.4 数值稳定性与收敛判定的坑凸优化实验最常见的失败是目标值变成NaN。原因一般是学习率过大、数据未归一化或Hessian奇异。遇到这种情况先检查特征值再把学习率降到0.01重跑。另一个容易被忽略的参数是停止条件用梯度范数比用目标函数变化更可靠因为目标值可能在很平的区域缓慢变化而梯度范数能更直接反映是否到达平稳点。在写报告时把三种方法的目标函数下降曲线画在同一张图上横轴用迭代次数纵轴用log10(目标值-最优值)。如果牛顿法曲线是直线且很快贴到0说明二阶收敛梯度下降则呈线性收敛。这个区分是实验的高分点。4. 实验报告与说明书的写作规范让审阅者一眼看到工作量4.1 报告结构的四段式与分值布局实验报告不能是代码附件的说明文档。组合优化与凸优化课程实验的评分者一般会先看报告能否独立回答问题再看代码能否复现。我建议采用四段式问题建模、方法设计、数值实验、结论分析。问题建模写清楚决策变量、目标函数和约束方法设计写出算法伪代码和复杂度数值实验放结果表格和曲线结论分析写实验中发现的异常和尝试过的改进。常见实验报告包括需求分析、概要设计、详细设计、测试报告等。对于算法类课程不必写软件工程那套东西而是要把重点放在算法正确性、效率和实验覆盖度上。报告的长度不是越多越好能用一张表说清数据分布就不用堆代码。4.2 说明书里必须写清的三件事说明书是独立于报告之外的文本通常放在ZIP的根目录。它要回答三个问题用什么环境跑、按什么顺序跑、结果输出在哪里。我一般会在说明书写一个最小可复现步骤例python -m venv venv source venv/bin/activate pip install -r requirements.txt python run_combination.py python run_convex.py python plot_convergence.py然后说明每个脚本输出到哪个目录。这个可复现性往往被忽视但实验报告中只要有一处“在我的机器上能跑”以外的事实就能让审阅者信任。dependency-free的matlab脚本也要写清版本号比如R2023a因为不同版本的优化工具箱接口有差异。4.3 实验数据与图表怎么放实验报告内的表格格式可以这样组织实验编号数据规模n最优值运行时间(s)内存(MB)算法1201520.025动态规划2100未证明最优3.2120分支定界310001470.540模拟退火每个数据点最好连随机种子都记录方便别人复现。图不要截控制台输出而是用Matplotlib生成带数据标签和参数说明的曲线。图题写清坐标轴含义例如“测试集误差随学习率变化”不要写“结果图”这种无法检索的名称。4.4 附录把推导过程和失败实验也收进去满分报告几乎都有一个好附录。附录放两类内容一是凸优化中KKT条件、对偶间隙等关键公式的完整推导二是实验过程中失败算法的时间对比比如固定学习率导致发散的学习曲线。失败记录能说明你对算法收敛性的理解而不是只展示成功结果。ZIP包里报告和说明书区分开来报告面向“做了什么”说明书面向“怎么复现”。5. 把实验包打成干净的ZIP压缩参数、目录结构与校验5.1 压缩参数怎么选实验报告、说明书、源码和结果截图整理好后最终用zip打包。建议使用-9获得更小的体积但如果目录里有大量图像-9耗时会更长。我一般这样做zip -r -9 组合优化与凸优化课程实验.zip report.pdf README.md src/ figures/这个命令把report.pdf、README.md、src目录和figures目录递归打包。-r是递归目录的必需参数-9表示最高压缩比。如果还需要保留Unix权限可以加--symlinks但Windows解压时通常不需要。5.2 目录结构与README的写法一个清楚的包应该有可检索的入口组合优化与凸优化课程实验/ ├── README.md ├── 实验报告.pdf ├── 说明书.md └── src/ ├── combination_branch_bound.py └── convex_optimization.pyREADME写三件事实验概述、环境依赖、脚本入口。说明书在此基础上补上参数设置和输出路径。文件名避免final_final.py这类无法区分的命名用版本或日期区分。5.3 用校验和确认ZIP完整交付前用SHA-256记录文件摘要再用解压测试确认内部CRC正确sha256sum 组合优化与凸优化课程实验.zip unzip -t 组合优化与凸优化课程实验.zip第一条命令输出唯一校验值第二条命令逐个测试ZIP内部记录的CRC。返回没有错误说明这个包可以交给审阅者把校验值写进说明书后续换机器也能验证文件未被改动。本文还有配套的精品资源点击获取
返回列表