尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

LINGO实战:从家政服务排班案例学习整数规划建模与求解

LINGO实战:从家政服务排班案例学习整数规划建模与求解 1. 项目概述从“家政服务”到数学建模的求解实践最近在带学生做数学建模的练习碰到了一个挺有意思的题目是关于家政服务的排班与调度优化。题目本身不复杂但非常适合用来讲解如何将一个现实问题抽象成数学模型并借助专业的优化工具来求解。很多同学在初次接触这类“运筹优化”问题时常常会卡在两个地方一是不知道怎么把文字描述转化成数学公式二是即便写出了模型也不知道该用什么工具来算或者觉得编程求解太麻烦。其实对于中小规模的线性规划、整数规划问题有一个非常经典且高效的工具——LINGO。这次我就以这个“家政服务2”的题目为例完整走一遍从问题理解、模型建立到LINGO求解的全过程。你会发现只要思路清晰工具趁手解决这类优化问题并没有想象中那么难。这个项目核心要解决的问题是一家家政公司需要根据未来一段时间内比如一周已知的客户服务需求量例如每天需要多少小时的保洁服务来合理安排其家政服务员的工作班次目标是使得公司的总成本主要是人力成本最低。这里面涉及到服务员的类型全职、兼职、工作时段、工资标准、能力限制等一系列约束。最终我们需要给出一个成本最优的排班方案。通过这个案例你不仅能学会LINGO的基本使用更能掌握一套处理资源分配与调度类优化问题的通用方法论。2. 问题拆解与数学模型构建2.1 核心需求与业务逻辑解析在动手写任何公式或代码之前我们必须先把业务逻辑吃透。题目“家政服务2”通常意味着这是一个系列问题第二部分可能在前一部分比如需求预测的基础上聚焦于资源调度。我们假设从题目中获得了以下关键信息这是基于常见赛题和实际业务的合理补充时间维度规划周期为一周每天划分为多个时段例如上午、下午、晚上。人力资源公司拥有两种类型的服务员全职和兼职。他们的特点不同全职服务员每天必须工作连续的两个时段如上午下午或下午晚上每周有固定工作日数要求如工作5天休息2天工资较高如日薪制。兼职服务员可以灵活安排单个时段工作按实际工作时段数支付报酬如时薪制但每周总工作时段数有上限。需求数据已知未来一周每天每个时段所需要的服务员“人·时段”数例如周一上午需要8个服务员工作。成本目标目标是最小化总人力成本即全职服务员的固定工资总额加上兼职服务员的浮动工资总额。约束条件每个时段安排的服务员总数全职兼职必须满足该时段的服务需求。全职服务员的工作安排必须符合其连续工作、固定工作日的规则。兼职服务员的工作量不能超过其最大可用时段数。所有服务员的人数都是整数整数规划。注意在实际建模中务必仔细阅读题目给出的每一个数据表格和文字说明上述假设是基于典型场景的补充。你的模型必须严格基于题目给出的具体参数比如具体划分几个时段、全职是否必须连续工作、兼职是否有最低工作时长要求等。2.2 决策变量定义把选择“数字化”建立数学模型的第一步是定义决策变量。决策变量就是我们要求解的那些未知数是模型输出的结果。对于这个排班问题我们需要决定每天每个时段安排多少名全职服务员工作每天每个时段安排多少名兼职服务员工作但这还不够。因为全职服务员的工作是连续的我们不能孤立地看单个时段。一个更清晰的思路是定义全职服务员的“工作模式”。例如假设每天有3个时段1,2,3那么全职服务员可能的工作模式有模式A工作时段1和2模式B工作时段2和3如果允许还可能有模式C工作时段1和3但通常要求连续所以此模式无效因此我们可以定义\( x_{d, p} \)第 \( d \) 天按照工作模式 \( p \) 工作的全职服务员人数。\( d 1,2,...,7 \)代表周一到周日\( p 1,2 \)代表两种连续工作模式。\( y_{d, t} \)第 \( d \) 天第 \( t \) 个时段工作的兼职服务员人数。\( t 1,2,3 \)。这样定义后\( x_{d,p} \) 和 \( y_{d,t} \) 就是我们要求解的所有决策变量。它们都必须是非负整数。2.3 目标函数与约束条件数学化接下来我们用数学公式来表达“成本最低”的目标和所有的业务规则。1. 目标函数最小化总成本假设全职服务员日薪为 \( C_f \) 元/天兼职服务员时薪为 \( C_p \) 元/时段。一个全职服务员工作一天无论他具体是模式A还是模式B都领取固定日薪 \( C_f \)。兼职服务员按工作时段数计薪。 则总成本为 \[ \text{Minimize } Z C_f \times \sum_{d1}^{7} \sum_{p1}^{2} x_{d,p} C_p \times \sum_{d1}^{7} \sum_{t1}^{3} y_{d,t} \] 我们的目标就是求出使 \( Z \) 最小的那些 \( x_{d,p} \) 和 \( y_{d,t} \) 的值。2. 需求满足约束对于每一天 \( d \) 的每一个时段 \( t \)安排的总服务能力必须大于等于需求量 \( D_{d,t} \)。在时段 \( t1 \)上午只有选择模式A工作时段1和2的全职服务员会工作。所以约束为 \[ x_{d, A} y_{d,1} \ge D_{d,1} \quad \forall d \]在时段 \( t2 \)下午选择模式A和模式B的全职服务员都在工作。所以约束为 \[ x_{d, A} x_{d, B} y_{d,2} \ge D_{d,2} \quad \forall d \]在时段 \( t3 \)晚上只有选择模式B工作时段2和3的全职服务员会工作。所以约束为 \[ x_{d, B} y_{d,3} \ge D_{d,3} \quad \forall d \]3. 全职服务员工作规则约束题目可能要求每个全职服务员每周工作5天。这意味着对于公司雇佣的全体全职服务员来说一周内总的工作“人·天”数必须等于全职服务员人数乘以5。但更常见的建模方式是将全职服务员视为同质的“资源池”我们只关心每天每种模式安排了多少人而不追踪具体个人。因此“每周工作5天”这个约束可能需要转化为对公司总全职人力规模的限制或者通过更复杂的排班模型实现。为了简化我们这里假设题目允许我们自由决定每天雇佣多少全职服务员没有跨天的个人连续性约束。这是一个重要的简化点在实际比赛中需根据题目要求调整。4. 兼职服务员能力约束假设每个兼职服务员每周最多工作 \( M \) 个时段。那么所有兼职服务员一周工作的总时段数不能超过公司可用的兼职总能力上限比如有10个兼职每人最多干10时段则总上限为100时段。约束为 \[ \sum_{d1}^{7} \sum_{t1}^{3} y_{d,t} \le M_{total} \] 或者如果题目规定的是人均上限则需要在模型中为每个或每类兼职服务员单独定义变量并施加约束模型会复杂得多。我们这里采用对总时段数限制的常见形式。5. 变量非负整数约束\[ x_{d,p}, y_{d,t} \in \mathbb{Z}^ \quad \forall d, p, t \]至此一个完整的整数线性规划ILP模型就构建完成了。接下来就是如何让计算机为我们求解这个模型。3. LINGO工具入门与模型实现3.1 为什么选择LINGO面对这样一个线性/整数规划模型我们有多种求解选择可以用Excel规划求解可以用Python的PuLP、SciPy库也可以用MATLAB的优化工具箱。那为什么专门用LINGO呢原因有几个语法直观LINGO的建模语言非常接近数学公式的书写方式定义集合、数据、变量、目标函数和约束非常直接学习成本低。求解高效LINGO内置了强大的线性、非线性和整数规划求解器特别是对整数规划其分支定界法实现得非常高效。调试方便LINGO能提供详细的求解报告包括松弛变量、对偶价格、灵敏度分析等对于理解模型和解的性质非常有帮助。数学建模竞赛“神器”在国内外很多数学建模竞赛中LINGO是解决优化类问题的标配工具之一掌握它很有必要。实操心得对于新手我建议从LINGO开始接触优化建模。它能让你更专注于模型本身而不是编程语法细节。当你对建模流程熟悉后再学习Python等通用语言下的优化库会更有方向感。3.2 LINGO快速安装与界面关于“lingo下载”目前LINGO属于商业软件其开发商是Lindo Systems。对于学习和参加数学建模竞赛通常可以下载其提供的功能受限但免费的演示版Demo Version足以解决中小规模问题。请通过搜索引擎查找“Lindo Systems官网”进入其官方网站在下载页面选择适合你操作系统的LINGO演示版。安装过程非常简单一路下一步即可。安装完成后打开LINGO你会看到一个简洁的界面主要包含菜单栏、工具栏和一个模型编辑窗口。我们所有的代码都将在这个编辑窗口中书写。3.3 在LINGO中实现家政服务模型现在我们将前面建立的数学模型“翻译”成LINGO语言。假设我们有以下具体数据为演示而虚构规划周期3天为简化每天3个时段。全职日薪 \( C_f 200 \) 元兼职时薪 \( C_p 60 \) 元/时段。兼职总时段上限 \( M_{total} 30 \) 时段。需求 \( D_{d,t} \) 如下表天(d)时段1需求时段2需求时段3需求1510826129371110下面是对应的LINGO代码我会逐段解释! 家政服务排班优化模型 - LINGO实现; ! 作者资深建模指导; ! 定义集合; SETS: DAYS /1..3/: ; ! 3天; PERIODS /1..3/: ; ! 每天3个时段; PATTERNS /A, B/: ; ! 全职工作模式A(时段1-2), B(时段2-3); ! 定义派生集合用于建立需求矩阵; NEED( DAYS, PERIODS): DEMAND; ! 定义决策变量所在的集合; FULLTIME( DAYS, PATTERNS): X; ! X(d,p): 第d天按模式p工作的全职人数; PARTTIME( DAYS, PERIODS): Y; ! Y(d,t): 第d天时段t工作的兼职人数; ENDSETS ! 输入数据; DATA: ! 需求数据 DEMAND(d, t); DEMAND 5 10 8 6 12 9 7 11 10; ! 成本参数; Cf 200; ! 全职日薪; Cp 60; ! 兼职时薪; Mmax 30; ! 兼职总工作时数上限; ENDDATA ! 目标函数最小化总成本; MIN SUM( FULLTIME(d, p): Cf * X(d, p)) SUM( PARTTIME(d, t): Cp * Y(d, t)); ! 约束条件; ! 1. 需求满足约束; ! 对于每一天d; FOR( DAYS(d): ! 时段1: 只有模式A的全职 兼职; X(d, A) Y(d, 1) DEMAND(d, 1); ! 时段2: 模式A和B的全职 兼职; X(d, A) X(d, B) Y(d, 2) DEMAND(d, 2); ! 时段3: 只有模式B的全职 兼职; X(d, B) Y(d, 3) DEMAND(d, 3); ); ! 2. 兼职总工作量上限约束; SUM( PARTTIME(d, t): Y(d, t)) Mmax; ! 3. 整数约束; FOR( FULLTIME(d, p): GIN( X(d, p) )); ! GIN表示广义整数即非负整数; FOR( PARTTIME(d, t): GIN( Y(d, t) )); ! 4. 非负约束 (在GIN中已隐含非负但显式写出是好习惯); FOR( FULLTIME(d, p): BND(0, X(d, p), 1000)); ! BND可以设定变量范围这里下界0上界一个很大的数; FOR( PARTTIME(d, t): BND(0, Y(d, t), 1000));代码关键点解析SETS/ENDSETS定义集合这是LINGO建模的核心。它类似于编程中的数组索引。我们先定义基本集合DAYS, PERIODS, PATTERNS然后用它们定义派生集合NEED, FULLTIME, PARTTIME这些派生集合将关联我们的数据和变量。DATA/ENDDATA用于初始化数据。数据可以直接写在等号后面按行排列。DEMAND是一个二维矩阵其赋值顺序对应NEED(DAYS, PERIODS)集合。SUM和FOR这是LINGO中最常用的两个函数。SUM用于求和FOR用于生成循环约束。例如FOR(DAYS(d): ...)意味着为每一天d都生成后面花括号内的一组约束。GIN和BNDGIN(X)指定变量X为整数。BND(L, X, U)给变量X设定下界L和上界U。目标函数直接使用MIN ...或MAX ...来定义。注释感叹号!后面的内容是注释不会被执行用于提高代码可读性。将上述代码复制到LINGO的模型窗口点击工具栏上的“求解”按钮一个靶心图标LINGO就会开始求解。4. 求解结果分析与解读4.1 读懂LINGO的求解报告点击求解后LINGO会弹出一个求解状态窗口显示“Global optimal solution found.”这表明它找到了全局最优解。关闭该窗口主界面会显示详细的求解报告。报告内容非常丰富我们重点关注以下几部分全局最优解与目标值报告开头会明确给出最优目标值。在我们的例子中可能会显示Objective value: 4680.000。这意味着最小总成本为4680元。变量值报告 (Variable Value)这是核心结果列出了所有决策变量的最优值。你会看到类似下面的输出Variable Value X( 1, A) 3.000000 X( 1, B) 5.000000 X( 2, A) 4.000000 X( 2, B) 6.000000 X( 3, A) 4.000000 X( 3, B) 5.000000 Y( 1, 1) 2.000000 Y( 1, 2) 2.000000 Y( 1, 3) 3.000000 Y( 2, 1) 2.000000 Y( 2, 2) 2.000000 Y( 2, 3) 3.000000 Y( 3, 1) 3.000000 Y( 3, 2) 2.000000 Y( 3, 3) 5.000000解读这给出了具体的排班方案。例如X(1, A)3表示第1天安排3名全职服务员按照模式A工作时段1和2工作。Y(1,1)2表示第1天时段1安排2名兼职服务员。缩减成本 (Reduced Cost)对于取值为0的变量缩减成本表示该变量的成本系数需要改善多少它才会进入最优解变为正值。对于取值为正数的变量其缩减成本为0。这个信息有助于进行成本灵敏度分析。松弛变量与对偶价格 (Slack or Surplus Dual Price)在约束条件部分每个约束都会显示“松弛/剩余”量和“对偶价格”。松弛/剩余 (Slack/Surplus)对于“”约束如果左端严格大于右端松弛量为正表示资源有剩余对于“”约束剩余量表示还有多少资源未使用。如果为0则表示该约束是“紧”的binding即最优解恰好使约束取等号该资源被完全利用或需求被恰好满足。对偶价格 (Dual Price)这是非常重要的经济解释。它表示对应约束的右端项如需求量、资源上限每增加1个单位最优目标值总成本会改善减少多少。例如如果某个时段需求约束的对偶价格是-50意味着该时段的需求增加1小时总成本将增加50元因为目标是最小化负的改善意味着增加。如果兼职总时段上限约束的对偶价格是-10意味着这个上限放松1个时段增加1总成本可以降低10元。注意事项对偶价格仅在当前最优基保持不变的小范围内有效。如果约束右端项变化太大对偶价格可能会改变。4.2 基于结果制定排班方案根据上面的变量值我们可以整理出一份清晰的人力排班表全职服务员排班表按模式天模式A人数模式B人数当日全职总人·天数第1天358第2天4610第3天459兼职服务员排班表按时段天时段1人数时段2人数时段3人数当日兼职总人·时段数第1天2237第2天2237第3天32510资源使用情况检查总成本4680元与报告一致。兼职总时段7710 24时段小于上限30时段有6个时段的空闲能力。需求满足情况可以逐时段验证例如第1天时段2需求10安排的全职模式A的3人模式B的5人共8人兼职2人总计10人恰好满足。这个方案就是公司在给定成本和需求下成本最优的人力配置方案。管理者可以直接据此安排员工上班。5. 模型扩展与实战技巧5.1 应对更复杂的业务规则我们之前构建的是一个基础模型。实际题目或业务中规则可能更复杂但建模思路是相通的。下面举几个扩展例子全职服务员个人连续排班如果要求每个全职服务员必须连续工作5天休息2天并且要追踪每个人模型会变得复杂。这需要引入更多的索引如服务员编号i和二元决策变量 \( x_{i,d,p} \)服务员i在第d天是否按模式p工作取值为0或1并添加约束确保每个人工作天数连续性和总数。这属于更复杂的“排班问题”Shift Scheduling通常需要借助专门的算法或更高级的建模技巧。兼职服务员技能差异与工资不同如果兼职服务员有不同的技能等级和对应的工资我们可以定义多类兼职服务员集合每类有各自的时薪和可用时段上限需求约束也需要按技能类别分别满足或汇总满足。考虑加班成本如果允许全职服务员加班超出正常时段并支付更高的加班工资我们需要引入新的决策变量表示加班时长并在目标函数中增加相应的加班成本项。最小化人数波动除了成本公司可能还希望每天雇佣的全职或兼职人数相对稳定以减少管理复杂度。这可以在目标函数中增加一个惩罚项用来最小化相邻两天人数之差的绝对值。但这会使目标函数非线性涉及绝对值在LINGO中需要使用线性化技巧处理。5.2 LINGO建模与调试高级技巧使用FILE和OLE函数读取外部数据当数据量很大时比如一个月的需求把数据直接写在DATA段会很臃肿。LINGO支持从文本文件(FILE)或Excel文件(OLE)读取数据极大提高了模型的通用性和可维护性。DATA: DEMAND FILE(demand_data.txt); ! 从文本文件读取; ! 或者从Excel的特定工作表范围读取; DEMAND OLE(data.xlsx, DemandSheet!B2:D8); ENDDATA利用FOR和SUM简化约束书写对于复杂的约束充分利用集合和函数。例如如果我们有多个技能等级需求约束可以写成FOR( NEED(d,t): SUM( SKILL_LEVEL(k): Y(d,t,k) ) DEMAND(d,t); );这比为每个等级写一遍约束简洁得多。调试与查错“No feasible solution found”模型无可行解。检查约束条件是否互相矛盾。例如总需求可能超过了总的人力资源能力上限。可以尝试放松一些约束如去掉整数限制看看线性松弛问题是否有解。“Unbounded solution”目标函数值可以无限小对于Min问题。检查是否漏掉了必要的约束比如成本系数是否为负或者某些资源使用没有上限求解时间过长对于大规模整数规划求解时间可能很长。可以尝试调整LINGO的求解器选项比如设置更长的求解时间限制、调整分支策略。如果对最优解要求不高可以设置一个允许的误差范围如设置SET(TERSEO, 2)和SET(IPTOLA, 0.05)允许5%的误差以加快求解速度。考虑是否能用启发式算法先得到一个较好的初始解然后提供给LINGO作为起始点。灵敏度分析与“What-If”分析LINGO的求解报告提供了丰富的灵敏度信息。你可以通过修改DATA段的数据重新求解来观察不同场景下的结果。例如如果市场需求增加10%成本会上升多少如果兼职时薪上涨公司是否会更多地依赖全职员工这些分析对于决策支持至关重要。5.3 从LINGO到通用编程语言的过渡虽然LINGO在建模便捷性上优势明显但在处理超大规模问题、需要集成到其他系统、或进行复杂算法自定义时使用Python等通用语言会更灵活。以Python的PuLP库为例上述模型的实现逻辑是相似的只是语法不同。import pulp # 定义问题 prob pulp.LpProblem(Housekeeping_Scheduling, pulp.LpMinimize) # 定义索引集合 days [1, 2, 3] periods [1, 2, 3] patterns [A, B] # 定义参数 DEMAND {(1,1):5, (1,2):10, (1,3):8, (2,1):6, (2,2):12, (2,3):9, (3,1):7, (3,2):11, (3,3):10} Cf 200 Cp 60 Mmax 30 # 定义决策变量 x pulp.LpVariable.dicts(x, (days, patterns), lowBound0, catInteger) y pulp.LpVariable.dicts(y, (days, periods), lowBound0, catInteger) # 定义目标函数 prob pulp.lpSum(Cf * x[d][p] for d in days for p in patterns) \ pulp.lpSum(Cp * y[d][t] for d in days for t in periods) # 定义约束 for d in days: prob x[d][A] y[d][1] DEMAND[(d,1)], fDemand_Constr_D{d}_T1 prob x[d][A] x[d][B] y[d][2] DEMAND[(d,2)], fDemand_Constr_D{d}_T2 prob x[d][B] y[d][3] DEMAND[(d,3)], fDemand_Constr_D{d}_T3 prob pulp.lpSum(y[d][t] for d in days for t in periods) Mmax, PartTime_Limit # 求解 prob.solve(pulp.PULP_CBC_CMD(msgFalse)) # 使用CBC求解器不显示求解日志 # 输出结果 print(fStatus: {pulp.LpStatus[prob.status]}) print(fOptimal Total Cost: {pulp.value(prob.objective)}) for d in days: for p in patterns: if pulp.value(x[d][p]) 0: print(fx[{d}, {p}] {pulp.value(x[d][p])}) for d in days: for t in periods: if pulp.value(y[d][t]) 0: print(fy[{d}, {t}] {pulp.value(y[d][t])})掌握LINGO的建模思想后学习PuLP这样的库主要就是熟悉其API核心的优化模型逻辑是完全一致的。6. 常见问题与排查技巧实录在带领学生和自身实践中我总结了一些使用LINGO解决此类优化模型时的高频问题和解决技巧。6.1 模型构建阶段问题1集合定义错误导致“索引越界”或数据不对应。现象运行时提示“Invalid index”或数据赋值后与预期不符。排查仔细检查SETS段中集合的定义顺序和派生集合的维度。确保DATA段中数据矩阵的排列顺序与派生集合的索引顺序完全一致。LINGO默认按行主序填充矩阵。技巧在数据赋值后可以用WRITE函数将数据打印出来验证。例如在DATA段后加上WRITE(Demand matrix:\n, TABLE(DEMAND));可以在输出窗口查看整个需求矩阵。问题2约束条件写错符号或漏写。现象求解结果明显不合理如成本为0或极大或者报告“No feasible solution”。排查逐行检查约束。特别是注意“”大于等于和“”小于等于不要弄反。检查每个约束是否覆盖了所有必要的集合索引。对于需求约束最容易漏掉FOR(DAYS(d): ...)这个循环。技巧先注释掉所有约束只保留目标函数和变量定义求解。这时应该得到一个无约束下的“最优解”通常是所有变量为0成本为0。然后逐个启用约束每加一个就求解一次观察目标函数和变量值的变化这样可以快速定位是哪个约束导致了问题。6.2 求解与结果分析阶段问题3整数规划求解速度慢甚至无法在有限时间内找到最优解。现象求解状态长时间显示“Branch-and-Bound”进度缓慢。排查与解决检查模型规模整数变量是否过多如果超过几百个求解时间会显著增加。提供初始解如果你能根据经验猜测一个较好的解可以通过INIT段赋给变量作为初始值能大大加快分支定界法的收敛速度。INIT: X(1, A) 3; ... ! 其他变量初始值 ENDINIT调整求解器选项在LINGO菜单选择LINGO - Options - Integer Solver可以调整“Branching Direction”分支方向、“Solver Strategy”求解策略等。对于最大化问题通常优先分支向上取整的变量对于最小化问题优先分支向下取整。也可以尝试不同的策略。接受近似解设置整数求解的容忍误差 (Optimality Tolerance)。默认是0要求绝对最优。可以将其设置为一个小的正数如0.01允许求解器在找到比最优解差1%以内的解时就停止能大幅缩短时间。模型重构有时通过引入额外的约束或改变变量的定义方式可以收紧模型的线性规划松弛从而加速求解。这需要更深入的运筹学知识。问题4如何解读“Reduced Cost”和“Dual Price”为0的情况现象报告中很多变量的缩减成本和对偶价格都是0。解读缩减成本为0对于当前取值为正的变量其缩减成本必然为0。只有取值为0的变量其缩减成本才可能非零。如果所有变量的缩减成本都是0那可能意味着所有变量在最优解中取值都大于0或者模型有多个最优解退化。对偶价格为0表示对应约束的右端项在当前基础上微调不会影响最优目标值。这通常意味着该约束不是“紧”的资源有剩余或需求有超额满足。例如兼职总时段上限约束如果对偶价格为0说明即使再增加这个上限也无法降低成本因为当前最优解还未用满这个上限。6.3 数据与结果输出阶段问题5如何将结果优雅地输出到文件或Excel需求直接看报告窗口不便于后续分析和报告撰写。解决方案使用OLE函数将结果写回Excel。DATA: ... ! 读取数据的部分 ! 将求解后的变量值输出到Excel OLE(result.xlsx, FullTimeSchedule) X; OLE(result.xlsx, PartTimeSchedule) Y; OLE(result.xlsx, TotalCost) Total_Cost; ! 假设你在模型中用变量Total_Cost记录了总成本 ENDDATA在求解语句SOLVE()之后LINGO会自动将变量X,Y的值写入指定Excel文件的相应工作表中。问题6模型需要频繁修改参数进行多次求解情景分析。需求不想每次都手动改DATA段。解决方案使用LINGO的脚本功能.LTF文件或命令行调用。你可以编写一个脚本文件用TAKE命令读取模型文件用ALTER命令修改参数然后循环求解并记录结果。这对于自动化批量测试不同参数场景非常有用。最后我想强调的是数学建模和优化求解是一个“迭代”的过程。很少有模型能一次就完美无缺。通常的流程是构建简单模型 - 求解 - 分析结果 - 发现不合理之处 - 修改或增加约束 - 再次求解。通过这个“家政服务排班”的案例我希望你掌握的不是LINGO的几个命令而是这套从现实问题抽象到数学模型再到软件求解和结果分析的完整思维框架。这个框架可以应用到物流配送、生产计划、投资组合等无数个优化领域。当你再遇到“XX资源分配”、“XX成本最小化”这类问题时不妨先问问自己决策变量是什么目标怎么量化约束条件有哪些想清楚这三点你就已经成功了一大半。剩下的就是选择合适的工具像我们使用LINGO一样把想法变成可执行的方案。
返回列表