数学建模--Lingo语言使用总结以及经典例题

2023-10-21 03:40

本文主要是介绍数学建模--Lingo语言使用总结以及经典例题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

准备数学建模比赛中,使用的是Lingo软件,将学习中遇到的问题做下总结:

资料总结链接:https://blog.csdn.net/yzu_120702117/article/details/38415153

1、关于数学函数使用过程的问题
model:
sets:
object/1 .. 3/: f;
endsets
data:
a, b = 3, 4;
x = ?;
enddata
@free(x);
f(1) = a*@sin(x);
f(2) = b*@cos(x);
f(3) = a*@sin(x) + b*@cos(x);
y = @smax(f(1), f(2), f(3));
end

思路:建立集合,并将函数值保存到每个成员中的 f 中。
目的:练习使用集合以及常用函数。
遇到的问题:每次输入大于1.57(这是弧度,对应的角度就是大于90),就报错如下:
        在这里插入图片描述

意思就是说:f (2)的式子约束太多,不能表示出来,请减少变量约束;
其实也很好理解,当大于90时,cos(x)是小于0的,这时候就不能正常表示,需要free ( f ),让f可以为任意数。
代码加一句@for(object(i): @free(f(i)));即可(这是针对集合的语句呦)。

2、关于经典例题–职员时序安排问题求解思路

题目:职员时序安排模型 一项工作一周七天都需要有人,每天(周一至周日)所需的最少职员数位20,16,13,19,14和12,并要求每个职员一周连续工作5天,试求每周所需最少的职员数,并给出安排。注意这里我们考虑稳定后的情况。

  • 按照决策变量,目标函数,约束条件的思路从题目中提取相关信息。
    ① 根据一周连续工作5天,设决策变量为从周x开始的员工。(我用集合来表示:n(1)为周一开始工作的员工数目,…n(7)为周日开始工作的员工数目)
    ② 根据最少的职员数,确定木匾函数为n(1) + … + n(7)的最小值。
    ③ 根据最少职员数位20,16,13,19,14和12,确定约束条件。

                在这里插入图片描述
N(1) + N(4) + N(5) + N(6) + N(7) >= 20;
N(1) + N(2) + N(5) + N(6) + N(7) >= 16;
N(1) + N(2) + N(3) + N(6) + N(7) >= 13;
N(1) + N(2) + N(3) + N(4) + N(7) >= 16;
N(1) + N(2) + N(3) + N(4) + N(5) >= 19;
N(2) + N(3) + N(4) + N(5) + N(6) >= 14;
N(3) + N(4) + N(5) + N(6) + N(7) >= 12;

  • 这些分析完成之后,写代码就很简单了:
model:sets:
!决策变量:设员工周x开始工作的员工数目为n(x);
workers/1 .. 7/:n;
endsets
!员工数目为整数;
@for(workers(i): @gin(n));
!目标函数;
min = @sum(workers(i):n);
!约束条件;
n(1) + n(4) + n(5) + n(6) + n(7) >=20;
n(1) + n(2) + n(5) + n(6) + n(7) >= 16;
n(1) + n(2) + n(3) + n(6) + n(7) >= 13;
n(1) + n(2) + n(3) + n(4) + n(7) >= 16;
n(1) + n(2) + n(3) + n(4) + n(5) >= 19;
n(6) + n(2) + n(3) + n(4) + n(5) >= 14;
n(5) + n(6) + n(3) + n(4) + n(7) >= 12;end

这是我的很直观的解法,思路没问题,就是语句繁琐,标准答案参见:
https://blog.csdn.net/m307617071/article/details/5514489#commentsedit

3、经典例题–TSP问题(旅行商问题)

题目:有一个销售员,从城市1出发,要遍访城市2,3,…,n个一次,最后返回城市1.已知从城市i到j的距离为C(ij),问他该按怎样的次序访问这些城市,是得总距离最少?
这个旅行商问题可以转换成混合整数线性规划问题(MILP)。

  • 对TSP 的数学描述:
    引入0-1 变量??? (? ≠ ?):???=1 表示路线从i 到j;???=0 表示不走i→j 这条路。
    则TSP 可表示为:

            在这里插入图片描述
上述约束条件中的前三个类似指派型问题,只是TSP 的必要条件;因此我们针对第四条约束条件用下列数学表达式来实现:
增加变量?? (? = 1,2, … , ?),并且?? − ?? + ???? ≤ ? − 1; ?? , ?? ≥ 0, ? = 1,2, … , ?, ? = 2,3, … , ?, i ≠ j.
于是TSP 问题转化成了一个混合整数线性规划模型。

决策变量:每个城市之间的距离Cij(代码中是dist表示)以及xij;
目标函数:总距离的最小值,min = @sum(link: dist * x);
约束条件:① @for(city(i):@sum(city(j) | i#ne#j:x(i, j)) = 1);
       @for(city(i):@sum(city(j) | i#ne#j:x(j, i)) = 1);!行和以及列和都是1
     ② @for(city(i):@for(city(j) | i#gt#1 #and# i#ne#j : u(i) - u(j) + n*x(i, j) <= n - 1 ) ; );!添加的额外约束
     ③ @for(link:@bin(x));!只能是0或1
分析完毕之后,写代码就很简单了。
源代码:

model:
!5个城市;
sets:
city/1 .. 5/:u;
link(city, city):dist, x;
endsets
!将距离信息放到dist文件中;
data:
dist = @file('dist.txt');
enddata
!城市的数量;
n = @size(city);!约束条件;
!行 列和为1;
@for(city(i):@sum(city(j)|i#ne#j:x(i, j)) = 1;@sum(city(j)|i#ne#j:x(j, i)) = 1);
!新约束;
@for(city(i):@for(city(j)| j#gt#1 #and# i#ne#j:u(i) - u(j) + n*x(i, j) <= n - 1););
@for(city(i):u(i) <= n - 1);
!只能是0, 1;
@for(link: @bin(x));
!目标函数;
min = @sum(link:dist*x);
end

文件dist中内容是(我选取的是5个城市。)

              在这里插入图片描述

4、最短路径问题。(动态规划法求解)

题目:给定N个点Pi组成集合{Pi},由集合中任一点Pi到另一点Pj的距离用Cij表示,如果Pi到Pj没有弧连接,则规定Cij=正无穷大,有规定Cii=0,指定一个终点PN,要求从Pi到PN的最短路线。
假设F(i)是第i点到第N点的最短距离,那么 F(i) = min(j)(Cij + F(j));
                    F(N) = 0;

  • 原理理解之后写代码就很简单了:
    决策变量:城市之间的连接和距离W,那么就定义两个集合:
    city/1 … 10/:F;
    road(city, city)/1,2 1,3 2,4 2,5 2,6 3,4 3,5 3,6 4,7 4,8 5,7 5,8 5,9 6,8 6,9 7,10 8,10 9,10/:W,P;
    目标函数:
    @for(city(i) i#lt# n : F(i) = @min(road(i, j): W(i, j) + F(j)));
    由于没有约束条件,所以不考虑约束。
    求解P(i, j)的语句如下:
    @for(road(i, j): P(i, j) = @if(F(i) #eq# W(i, j) + F(j), 1, 0));

那么代码如下:

model:
sets:
!定义集合城市,属性是到终点的最短距离;
city/1 .. 10/:F;
!继承集合包含图的连接部分的权重W以及P(若该连接是最短路径的子集,那么P为1否则为0,是为了方便找最佳路径);
road(city, city)/1,2 1,32,4 2,5 2,63,4 3,5 3,64,7 4,85,7 5,8 5,96,8 6,9 7,108,109,10/:W, P;
endsets
data:
W = 6 53 6 97 5 119 18 7 5 4 10579;enddatan = @size(city);
! 动态规划式子;
@for(city(i)| i#lt#n:F(i) = @min( road(i, j): W(i, j) + F(j)) );
!寻找路径;
@for(road(i, j): P(i, j) = @if(F(i) #eq# W(i, j) + F(j), 1, 0));end
5、指派问题(分配问题)

题目:这是给n个人分配n项工作以获得最高效率的问题。第i个人完成第j项工作需要的平均时间为Cij。要求给每个人分配一项工作,并要求分配完这些工作,以使完成全部任务的总时间最小。

思路:
①决策变量:设集合person是工人,集合work是需要指派的任务,那么派生集合allocate(person, work),并加上属性Tij为第i个工人做第j个工作的时间,Aij是如果dii个工人做第j个工作,那么Aij = 1,否则Aij = 0.
②目标函数:
          在这里插入图片描述
③约束条件:
          在这里插入图片描述

那么代码就很好写了:

model:sets:
work/1 .. 7/;
person/1 .. 7/;
allocate(person, work):T, A;
endsetsdata:
T = 6 2 6 7 4 2 54 9 5 3 8 5 85 2 1 9 7 4 37 6 7 3 9 2 72 3 9 5 7 2 65 5 2 2 8 11 49 2 3 12 4 5 10;enddata
!目标函数;
!min = @sum(@for(person(i):@for(work(j):T(i, j)*A(i, j))));
min = @sum(allocate(i, j): T(i, j)*A(i, j));
!约束条件;
@for(person(i):@sum(work(j): A(i, j)) = 1);
@for(work(i):@sum(person(j): A(j, i)) = 1);@for(allocate : @bin(A));end
6、最优选择问题。

题目: 某钻井队要从10个可供选择的井位中确定5个钻井探油,使总的钻探费用为最小。若10个井位的代号为s1,s2,…,s10,相应的钻探费用c1,c2,…,c10为5,8,10,6,9,5,7,6,10,8.并且井位选择上要满足下列限制条件:
(1) 或选择s1和s7,或选择钻探s9;
(2) 选择了s3或s4就不能选s5,或反过来也一样;
(3) 在s5,s6,s7,s8中最多只能选两个.

试建立这个问题的整数规划模型,确定选择的井位。
明显这是一个混合整数线性规划问题。

  • 思路:根据题意,确定:
    决策变量:集合 井oilplace/s1 … s10/ : c,f;包含属性价格c和是否开采f。
    目标函数:min = @sum(oilplace:c*f);费用和的最小值。
    约束条件:(s1 + s7 - 2)(s9 - 1) = 0;
          s(3)*s(5) + s(4)*s(5) = 0;
          s5 + s6 + s7 + s8 <= 2;
          @for(oilplace:@bin(f));
          @sum(oilplace: f) = 5.

核心就是将约束条件变换成程序。

代码就很简单写了:

model:sets:
oilplace/s1 .. s10/:c, f;
endsetsdata:
c = 5 8 10 6 9 5 7 6 10 8;
enddatamin = @sum(oilplace: c*f);@sum(oilplace(i)| i#gt#4 #and# i#lt#9: f(i)) <= 2;
@sum(oilplace: f) = 5;
(f(1) + f(7) - 2)*(f(9) - 1) = 0;
!f(9) = @if(f(1)#eq#1 #and# f(7)#eq#1,  0, 1);
!f(5) = @if(f(3)#eq#1 #or# f(4)#eq#1, 0, 1);
!f(3) = @if(f(5)#eq#1, 0, 1);
!f(4) = @if(f(5)#eq#1, 0, 1);
f(3)*f(5) + f(4)*f(5) = 0;
@for(oilplace:@bin(f));end
7、选址问题(1)

某公司有六个建筑工地,位置坐标(ai,bi)(单位:公里),水泥日用量di(单位:吨)
在这里插入图片描述
(1) 现有2个料场,位于A(5,1),B(2,7),记(xj,yj),及,2,日存储量ej各有20吨。假设工地和料场之间有直线道路,制定每天的供应计划,即从A,B两料场分别向工地运送水泥,是得总的吨公里数最小,其中Cij表示i工地从j料场运来的水泥量。则可以建立模型
在这里插入图片描述
分析得到:
决策变量:工地:workplace/1 … 6/: a, b, d;
      料场 ;material/A B/:x, y, e;
      两者合集all(material, workplace):c;
目标函数:min = @sum(all(i, j):@sqrt((x(i) - a(j))^2 + (y(i) - b(j))^2)*c(i, j));
约束条件:@for(material(i):
             @sum(workplace(j):c(i, j)) <= 20);
      @for(workplace(j):
             @sum(material(i):c(i, j)) = d(j));
那么代码就很好写了:

model:sets:
workplace/1 .. 6/:a, b, d;
material/A B/:x, y, e;
all(material, workplace): c;
endsetsdata:
e = 20;
a = 1.25 8.75 0.5 5.75 3 7.25;
b = 1.25 0.75 4.75 5 6.5 7.75 ;
x = 5, 2;
y = 1, 7;
d = 3 5 4 7 6 11;
enddatamin = @sum(all(i, j):((x(i) - a(j))^2 + (y(i) - b(j))^2)^.5*c(i, j));@for(material(i):@sum(workplace(j): c(i, j)) <= 20);
!c(1, 1) + c(2, 1) = 3;
!c(1, 2) + c(2, 2) = 5;
!c(1, 3) + c(2, 3) = 4;
!c(1, 4) + c(2, 4) = 7;
!c(1, 5) + c(2, 5) = 6;
!c(1, 6) + c(2, 6) = 11;@for(workplace(j):@sum(material(i): c(i, j)) = d(j));
end

(2)改建两个新料场,需要确定新料场位置(xj,yj)和运量cij,在其他条件不变下使总公里数最小。模型与上面的一样,位置变量变为料场位置(xj,yj),变为非线性优化问题。
加一个init初始化就可以,给两个料场赋初值,找最近点。新代码如下:

model:sets:
workplace/1 .. 6/:a, b, d;
material/A B/:x, y, e;
all(material, workplace): c;
endsetsdata:
e = 20;
a = 1.25 8.75 0.5 5.75 3 7.25;
b = 1.25 0.75 4.75 5 6.5 7.75 ;
d = 3 5 4 7 6 11;
enddatainit:
x = 5 2;
y = 1 7;
endinitmin = @sum(all(i, j):((x(i) - a(j))^2 + (y(i) - b(j))^2)^.5*c(i, j));@for(material(i):@sum(workplace(j): c(i, j)) <= 20);
!c(1, 1) + c(2, 1) = 3;
!c(1, 2) + c(2, 2) = 5;
!c(1, 3) + c(2, 3) = 4;
!c(1, 4) + c(2, 4) = 7;
!c(1, 5) + c(2, 5) = 6;
!c(1, 6) + c(2, 6) = 11;@for(workplace(j):@sum(material(i): c(i, j)) = d(j));
end
8、选址问题(2)

题目:某海岛上有12个主要的居民点,每个居民点的位置(用平面坐标x,y表示,单位km)和居住人数(r)如下表所示。现在准备在海岛上建一个服务中心为居民提供各种服务,那么服务中心应该建在那里?
在这里插入图片描述

这个题目没有约束变量,仅仅要一个最小值的目标函数就可以。
在这里插入图片描述

代码:

model:sets:
live/1 .. 12/: x, y, r;
server/A/:a, b;
all(server, live);
endsetsdata:
x = 0 8.20 0.50 5.70 0.77 2.87 4.43 2.58 0.72 9.76 3.19 5.55;
y = 0 0.50 4.90 5.00 6.49 8.75 3.26 9.32 9.96 3.16 7.20 7.88;
r = 600 1000 800 1400 1200 700 600 800 1000 1200 1000 1100;
enddatainit:
a = 0;
b = 0;
endinitmin = @sum(all(i, j): ((a(i) - x(j))^2 + (b(i) - y(j))^2)^.5*r(j));end
9、非线性整数规划

在这里插入图片描述
还要求Xi是整数。

这就很明显的题目了,直接写就可以。
最显然的写法:

model:sets:
data1/1 .. 5/:d;
endsetsmax = d(1)^2 + d(2)^2 + 3*d(3)^2 + 4*d(4)^2 + 2*d(5)^2 - 8*d(1) - 2*d(2) - 3*d(3) - d(4) - 2*d(5);!@for(data1:d >= 0);
!@for(data1:d <= 99);d(1) + d(2) + d(3) + d(4) + d(5) <= 400;
d(1) + 2*d(2) + 2*d(3) + d(4) + 6*d(5) <= 800;
2*d(1) + d(2) + 6*d(3)  <= 200;
d(3) + d(4) +5* d(5) <= 200;
@for(data1:@gin(d));
@for(data1:@bnd(0, d, 99));
end

应用Lingo比较熟练的代码:

model:sets:
row/1 .. 4/:r;
col/1 .. 5/:c1, c2, x;
all(row, col):a;
endsetsdata:
c1 = 1 1 3 4 2;
c2 = -8 -2 -3 -1 -2;
a = 1 1 1 1 11 2 2 1 62 1 6 0 00 0 1 1 5;
r = 400 800 200 200;
enddatamax = @sum(col: c1*x^2 + c2*x);@for(row(i):@sum(col(j): a(i, j)*x(j)) <= r(i));
@for(col:@gin(x));
@for(col:@bnd(0, x, 99));end

这篇关于数学建模--Lingo语言使用总结以及经典例题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/251669

相关文章

Spring中@Lazy注解的使用技巧与实例解析

《Spring中@Lazy注解的使用技巧与实例解析》@Lazy注解在Spring框架中用于延迟Bean的初始化,优化应用启动性能,它不仅适用于@Bean和@Component,还可以用于注入点,通过将... 目录一、@Lazy注解的作用(一)延迟Bean的初始化(二)与@Autowired结合使用二、实例解

SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)

《SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)》本文介绍了如何在SpringBoot项目中使用Jasypt对application.yml文件中的敏感信息(如数... 目录SpringBoot使用Jasypt对YML文件配置内容进行加密(例:数据库密码加密)前言一、J

Spring Boot 中正确地在异步线程中使用 HttpServletRequest的方法

《SpringBoot中正确地在异步线程中使用HttpServletRequest的方法》文章讨论了在SpringBoot中如何在异步线程中正确使用HttpServletRequest的问题,... 目录前言一、问题的来源:为什么异步线程中无法访问 HttpServletRequest?1. 请求上下文与线

在 Spring Boot 中使用异步线程时的 HttpServletRequest 复用问题记录

《在SpringBoot中使用异步线程时的HttpServletRequest复用问题记录》文章讨论了在SpringBoot中使用异步线程时,由于HttpServletRequest复用导致... 目录一、问题描述:异步线程操作导致请求复用时 Cookie 解析失败1. 场景背景2. 问题根源二、问题详细分

从零教你安装pytorch并在pycharm中使用

《从零教你安装pytorch并在pycharm中使用》本文详细介绍了如何使用Anaconda包管理工具创建虚拟环境,并安装CUDA加速平台和PyTorch库,同时在PyCharm中配置和使用PyTor... 目录背景介绍安装Anaconda安装CUDA安装pytorch报错解决——fbgemm.dll连接p

Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx

使用Python创建一个能够筛选文件的PDF合并工具

《使用Python创建一个能够筛选文件的PDF合并工具》这篇文章主要为大家详细介绍了如何使用Python创建一个能够筛选文件的PDF合并工具,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录背景主要功能全部代码代码解析1. 初始化 wx.Frame 窗口2. 创建工具栏3. 创建布局和界面控件4

一文详解如何在Python中使用Requests库

《一文详解如何在Python中使用Requests库》:本文主要介绍如何在Python中使用Requests库的相关资料,Requests库是Python中常用的第三方库,用于简化HTTP请求的发... 目录前言1. 安装Requests库2. 发起GET请求3. 发送带有查询参数的GET请求4. 发起PO

Java中的Cursor使用详解

《Java中的Cursor使用详解》本文介绍了Java中的Cursor接口及其在大数据集处理中的优势,包括逐行读取、分页处理、流控制、动态改变查询、并发控制和减少网络流量等,感兴趣的朋友一起看看吧... 最近看代码,有一段代码涉及到Cursor,感觉写法挺有意思的。注意是Cursor,而不是Consumer

Node.js net模块的使用示例

《Node.jsnet模块的使用示例》本文主要介绍了Node.jsnet模块的使用示例,net模块支持TCP通信,处理TCP连接和数据传输,具有一定的参考价值,感兴趣的可以了解一下... 目录简介引入 net 模块核心概念TCP (传输控制协议)Socket服务器TCP 服务器创建基本服务器服务器配置选项服