ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

LINGO运输问题实验报告:数学模型、集合语法与不平衡处理

LINGO运输问题实验报告:数学模型、集合语法与不平衡处理 简介这是一份基于LINGO求解运输问题的实验报告适合运筹学、物流优化或供应链管理方向的学生与入门者阅读用于学习如何将实际的产销平衡运输问题转化为线性规划模型并用LINGO完成求解。资源压缩包为456KB包含1个doc文档内容覆盖实验目的、数学模型、LINGO程序、求解结果与结论分析结构完整可直接参考。已有2034人学习下载。报告以三个产地和四个销地的运输问题为例给出了产量、需求量、单位运价等参数并展示了供应约束和需求约束的LINGO代码运行得到全局最优解总运费239、迭代6次的输出数据。读者可以据此对照学习LINGO集合、数据段及for/sum函数的用法理解最小化总运费模型的建立与结果验证过程是一份兼具模板价值与实操指导性的课程实验资源。1. LINGO 运输问题的实验报告卡点通常不在 LINGO深夜改一份《LINGO 运输问题的实验报告》是很多人的共同经历手算用了西北角法、最小元素法伏格尔法做了三四张表最后 LINGO 一跑发现总费用比手算版低了 21 元。这不是模型写错往往是两组数据口径不一致。运输问题本身不复杂真正容易翻车的地方是把手算过程翻译成 LINGO 时代码里的集合、下标和恒等关系错一个结果就全塌要么报无解要么解出来行列合计对不上。下面从一组能直接抄的代码出发把数学模型、集合写法、不平衡处理和报告核对串起来适合第一次在 LINGO 里写运输模型的学生也适合被表上作业法绕晕、需要一份可复核结果的作业党。2. 运输问题的数学模型与 LINGO 集合写法对应关系2.1 平衡运输问题的标准形等式约束来自供需守恒运输问题的标准形要求产销平衡也就是所有产地供给总量恰好等于所有销地需求总量。决策变量x(i,j)表示第 i 个产地发往第 j 个销地的数量c(i,j)是单位运价目标函数是所有调运量与运价的乘积之和。约束条件分两组看任取一个产地它发往各个销地的总运量必须等于它的产量任取一个销地它从各个产地收到的总运量必须等于它的需求量。写实验报告时通常把运价做成一张 m 行 n 列的表格运输问题就是在表格里选格子让每一行、每一列都刚好满额同时总费用最小。它的目标函数和约束全部线性因此是线性规划之所以很多课程指定用 LINGO是因为 LINGO 的集合语法能让模型代码不随产地和销地的数量变化而产生结构改动。下面这张符号表是后续所有代码的基础符号含义a_i产地 i 的供应量b_j销地 j 的需求量c(i,j)从 i 到 j 的单位运价x(i,j)决策变量实际调运量写报告时建议在数据段注释里标明单位比如“吨”“件”或“百箱”。单位不统一最容易导致目标值出现奇怪的位数这种错误 LINGO 不会报只能靠人工发现。2.2 用 LINGO 集合语法写运输问题SETS / DATA / 目标约束三段LINGO 的典型运输模型分成三段SETS段声明产地集合、销地集合以及两者组合成的派生集合DATA段写供应量、需求量和运价矩阵第三部分是目标函数与约束。对照下面这段完整的 3×4 模型sets: xd /1..3/ : supply; ! 产地集合supply 保存产量 yd /1..4/ : demand; ! 销地集合demand 保存需求量 links(xd, yd) : cost, x; ! 派生集合运价 cost 与决策变量 x endsets data: supply 50 60 45; demand 40 55 35 25; cost 6 4 8 3 5 2 7 4 7 6 3 5; enddata min sum(links(i, j) : cost(i, j) * x(i, j)); for(xd(i) : sum(yd(j) : x(i, j)) supply(i); ); for(yd(j) : sum(xd(i) : x(i, j)) demand(j); );sum(links(i,j): cost(i,j)*x(i,j))表示对所有产地销地组合累加费用for(xd(i): ...)表示把括号里的约束对每个产地展开一次等价于手写 m 个等式。 supply(i)对应供应量守恒 demand(j)对应需求量守恒。LINGO 默认所有变量非负不需要额外写x(i,j) 0。集合规模扩大时只改集合范围和DATA段的数据条数即可。2.3 小规模模型直接手写目标函数先验证再扩展集合语法第一次接触会觉得抽象尤其是for展开后的效果看不见。对 3×4 这种小规模问题把变量全部列出来也能算出错时定位更直接。这个版本没有SETS约束按行、列顺序手写min 6*x11 4*x12 8*x13 3*x14 5*x21 2*x22 7*x23 4*x24 7*x31 6*x32 3*x33 5*x34; x11 x12 x13 x14 50; x21 x22 x23 x24 60; x31 x32 x33 x34 45; x11 x21 x31 40; x12 x22 x32 55; x13 x23 x33 35; x14 x24 x34 25;前三个等式对应产地行约束后四个对应销地列约束。变量名x11只是一个名字LINGO 遇到第一次出现的变量会自动创建并默认非负因此不需要预先声明变量表。这个版本的缺点是变量名一多就容易把x14写成x41LINGO 不报错会直接当成另一个变量最终结果可能目标值正常但运输表行列和全部对不上。出现这种情况时优先检查变量名下标。我的常见做法是先用这个版本确认数据和目标值再把模型迁移到集合版本两个都留在实验报告里中间分析部分正好写“对比手写约束与集合展开的一致性”。3. 用 LINGO 跑通一个 3×4 运输问题报告需要的最小步骤3.1 一个可以完整复现的 3 产地 4 销地实例实验报告要可审查数据不宜拍脑袋。下面这组数据总供应量与总需求量都是 155产地 A1、A2、A3 的产量分别为 50、60、45销地 B1 到 B4 的需求分别为 40、55、35、25。单位运价矩阵如下运价B1B2B3B4A16483A25274A37635这个实例有一个适合写报告的特点低价线路非常明显A2 到 B2 运价只有 2A3 到 B3 运价是 3人工用最小元素法能得到可行解但最优方案还要看 A1 如何分流因此手算和 LINGO 结果之间有可讨论的差距。数据也不要用随机生成的大矩阵LINGO 无所谓但报告里表上作业法部分会变得不可读。3.2 求解与报告读取Objective value 和 x 矩阵把第 2 章的集合版本代码粘贴进 LINGO 新建的空白模型点击菜单LINGO - Solve求解。没有语法错误时会弹出 Solution Report 窗口第一块显示求解状态和目标函数值。这个模型是纯线性规划报告中会出现Objective value: 535.0000。决策变量x的取值在变量列表里逐行给出LINGO 显示变量名时统一大写例如X(1,1)Variable Value Reduced Cost X(1,1) 25.00000 0.000000 X(1,2) 0.000000 1.000000 X(1,3) 0.000000 6.000000 X(1,4) 25.00000 0.000000 X(2,1) 5.000000 0.000000 X(2,2) 55.00000 0.000000 X(2,3) 0.000000 6.000000 X(2,4) 0.000000 2.000000 X(3,1) 10.00000 0.000000 X(3,2) 0.000000 2.000000 X(3,3) 35.00000 0.000000 X(3,4) 0.000000 1.000000读结果时只看Value列值为正的变量构成调运方案值为 0 代表这条线路未启用。报告里的Reduced Cost后面还会用到它表示把某个非基变量强制增加 1 单位时目标函数的增量是判断最优解唯一性的关键指标。整理报告表格时不要把 0 运量直接删掉保留 0 才能看出哪些线路没有启用。3.3 把报告结果整理成运输表并用 SUMPRODUCT 复核把上面的Value整理成 3 行 4 列运输表行合计应等于产量列合计应等于需求量。整理后如下调运量B1B2B3B4合计A125002550A25550060A310035045合计40553525155总费用不需要在报告里展开长篇乘法列一行综合式子即可25×6 25×3 5×5 55×2 10×7 35×3 535。更稳妥的做法是在 Excel 里用SUMPRODUCT(运价表区域, 调运表区域)与 LINGO 的Objective value交叉验证数值一致再写结论。报告里如果解出现多行或多列全 0不要写成“没有调运”注明“该线路未启用”即可LINGO 输出的 0 是变量的值不是缺省值。4. 供需不平衡的 LINGO 处理虚产地、虚销地与报告写法4.1 需求大于供应加一个虚拟产地产量等于缺口实际业务里供需经常不平衡。标准模型此时无解因为所有真实产地都发完也不够满足需求。实验报告的标准做法是加虚拟产地虚拟产地没有真实位置产量等于总需求与总供应的差额运价一律为 0。它在结果中调入某个销地的数量解释为该销地未满足的需求量。把第 3 章的例子改为总需求 165、总供应 155缺口 10。集合里增加一个产地supply补上 10cost增加一行 4 个 0目标函数和约束不用动sets: xd /1..4/ : supply; ! 第 4 个产地为虚拟产地 yd /1..4/ : demand; links(xd, yd) : cost, x; endsets data: supply 50 60 45 10; ! 虚拟产量 需求缺口 demand 40 55 35 35; cost 6 4 8 3 5 2 7 4 7 6 3 5 0 0 0 0; ! 虚拟产地运价全为 0 enddata min sum(links(i, j) : cost(i, j) * x(i, j)); for(xd(i) : sum(yd(j) : x(i, j)) supply(i); ); for(yd(j) : sum(xd(i) : x(i, j)) demand(j); );结果中虚拟产地所在行的调运量合计必然等于 10分布到哪个销地哪个销地就缺货这么多因此不必把虚拟产地描述成“免费运输”它是数学上的松弛手段。注意虚拟行内部的分配通常不唯一因为所有虚拟运价都是 0LINGO 只给出一组最优解报告里建议只汇报该行合计。4.2 供应大于需求加虚拟销地解释剩余产能反过来总供应多于总需求时在销地集合里加虚拟销地。虚拟销地的需求量等于多余供应量所有真实产地到它的运价为 0。结果中每个产地打到虚拟销地的量就是该产地未运出的剩余产能。两种改造在 LINGO 里只改集合和数据段下面是实验报告写作时逐项核对的对照表不平衡情形集合修改数据修改结果读法需求 供应xd增加一个虚拟产地supply补差额cost补一行 0虚拟产地的调出量 缺货量供应 需求yd增加一个虚拟销地demand补差额cost补一列 0真实产地打到虚拟销地的量 剩余产能4.3 改参数时容易踩的三个坑第一个坑是只改supply和demand没有同步改集合范围。LINGO 会报数据条数不匹配或者模型运行后某些数据被忽略。第二个坑是虚拟产地运价填了非零数这会让“缺货”也产生成本从而改变真实产地的调运方案除非报告明确要惩罚缺货否则保持 0。第三个坑是改造后总供需没有重新相等模型直接无解。一个快速自检办法是在模型末尾加一条平衡约束sum(xd(i) : supply(i)) sum(yd(j) : demand(j));把它作为额外约束放进去如果模型无解说明不平衡处理环节有加减错误求解成功则说明产销已经重新平衡。报告里保留这条约束并解释它是“确保改造后的数据重新平衡”比单独在正文里写一句“本例已平衡”更有说服力。5. 运输问题实验报告加分项Reduced Cost、敏感性分析与核对技巧5.1 用 Reduced Cost 判断当前解是否唯一最优报告里“本方案是最优方案”这句话要有依据。在最小化问题中非基变量的Reduced Cost表示该变量增加 1 单位时目标函数的最小增量。全部大于 0说明任何未启用的线路一旦启用都会抬高总费用当前解是唯一最优只要存在一个为 0 的非基变量就存在另一个总费用相同的方案属于多重最优解。第 3 章的例子里非基变量Reduced Cost分别为 1、6、6、2、2、1全部为正因此报告可以明确写“本例为唯一最优解”。多重最优时不必慌张报告里写出两组总费用相同的调运方案反而更能体现对模型结构理解到位。5.2 做敏感性分析需要提前打开的范围计算实验报告若讨论“某条线路运价变化后方案是否仍然最优”需要在求解前打开范围计算菜单LINGO - Options - General Solver找到 Dual Computations选择Prices Ranges后重新求解。报告中会多出Ranges in which the basis is unchanged区域包含目标函数系数允许变化范围和右端项允许变化范围。对运输问题重点看运价系数的上下限若某条线路当前运价的允许范围很窄说明方案对该线路价格变化敏感范围宽则说明当前方案对该线路价格变化不敏感。把目标系数范围与 5.1 的Reduced Cost结合就能解释为什么某条线路即使降价 2 元当前调运方案也不会变动。5.3 一个 30 秒的解验证技巧提交前用外部工具交叉验证比反复看 LINGO 输出更有效。把Value列整理成运输表后在 Excel 中用SUMPRODUCT(运价表区域, 调运表区域)与 LINGO 的Objective value对照再把调运表按行、按列分别求和与supply、demand对比。数值不一致时优先怀疑人工抄写时行列对调而不是求解器运输问题很少出现精度问题错误几乎都出在报告整理环节。提交前按这个顺序自检LINGO 原始输出、整理后的运输表、SUMPRODUCT 复核数三项对齐后再写结论。本文还有配套的精品资源点击获取
返回列表