数学建模 第三节

目录

前言

[一 钻井布局问题](#一 钻井布局问题)

第一问分析

第二问分析

总结


前言

这里讲述99年的钻井布局问题,利用这个问题讲述模型优化,LINGO,MATLAB的使用


一 钻井布局问题

这个是钻井布局的原题,坐标的位置为

a = [0.50,1.41,3.00,3.37,3.40,4.72,4.72,5.43,7.57,8.38,8.98,9.50];

b = [2.00,3.50,1.50,3.51,5.50,2.00,6.24,4.10,2.01,4.50,3.41,0.80];

这个a是每一个井的横坐标,b是每一个井的纵坐标

第一问分析

题意:我们要去移动网格,然后这个井的x坐标和y坐标距离这个网格的点的x坐标和y坐标的的误差可以再0.05之内,这个是十分重要的

我们先用MATLAB把这个图画出来

代码如下

cpp 复制代码
a=[0.50,1.41,3.00,3.37,3.40,4.72,4.72,5.43,7.57,8.38,8.98,9.50];
b=[2.00,3.50,1.50,3.51,5.50,2.00,6.24,4.10,2.01,4.50,3.41,0.80];
plot(a,b,'o');//画点
grid;  //显示表格
for i = 1:12
    text(a(i)+0.1,b(i),int2str(i));//显示坐标点的标记
end    

然后我们要去根据题意知道这个模型要怎么进行构建

模型就是我们0---1变量规划,算法中就是背包问题,选择还是不选择,选择是1,不选择是0,然后只要把这些值加起来就好了,因为我们就最多就是12口井,那全部取1的话,那不就是12吗,向下很多人都听懂这个了

我们可以进行总结一下,这个就是选择和不选择的问题

所以我们有一个变量肯定是要记录0和1的,那么我们就找到了一个变量了,在创建模型中,变量是十分关键的,现在我们创建了一个变量就是0,1的f

然后剩下变量不就是我们上面的x坐标和y坐标嘛

然后还有一个就是我们平移,平移多少呢?我们不知道,所以设一个x和y,因为x和y都要移动嘛

现在我们就有5个变量了

这个是我们建立的第一个模型

我们可以看到这个就是利用了水井坐标减去方格坐标的绝对值小于0.05,为什么呢?读者自己思考,因为这个很关键,讲出来的话就没意义了

然后f就是我们所说的01变量,但是这个模型好像编写不出来,为什么?

因为我们的式子要和01变量进行有所关联,所以我们直接这样就好了

然后我们就得到了关联,这个时候我们可以先用LINGO进行编写或者MATLAB编写

LINGO

cpp 复制代码
sets:
    aa/1..12/:s,b,f;
endsets

data:
    s = 0.50,1.41,3.00,3.37,3.40,4.72,4.72,5.43,7.57,8.38,8.98,5.50;
    b = 2.00,3.50,1.50,3.51,5.50,2.00,6.24,4.10,2.01,4.50,3.41,0.80;
enddata

Max = @sum(aa(i):f(i));

x<1;
x>0;
y<1;
y>0;

@for(aa(i):@abs(s(i)+x-@floor(s(i)+x+0.5))*f(i)<=0.05);
@for(aa(i):@abs(b(i)+y-@floor(b(i)+y+0.5))*f(i)<=0.05);
@for(aa(i):@bin(f(i)));

这里讲解一下语法,可能很多读者不着调这个语法

首先这个sets是创建集合的,endset是结束创建集合,这里你可以理解一个数组,sdf是aa的元素,然后这个sfd里面都有12个元素,这个元素你可以自己进行赋值,如果只有一个的话,那就直接向我写x和y一样就好了

然后这个data是进行赋值的区域enddata是结束赋值的语句,这是一一对应的

然后后面就是for循环,这个for循环前面aa你可以想象成for循环的里面的三个表达式,aa就是位置,然后循环12次

MATLAB

cpp 复制代码
a=[0.50,1.41,3.00,3.37,3.40,4.72,4.72,5.43,7.57,8.38,8.98,9.50];
b=[2.00,3.50,1.50,3.51,5.50,2.00,6.24,4.10,2.01,4.50,3.41,0.80];
m = 0;
d = 0;
c=[];
e=[];
for x=0:0.01:1
    aa = a + x;
   for y=0:0.01:1
     bb = b + y;
     n = 0;
       for i = 1:12
           if abs(aa(i) - round(aa(i))) <= 0.05 && abs(bb(i) - round(bb(i))) <= 0.05
               n = n + 1;
               c(end + 1) = i;
           end    
       end  
       if m < n
           m = n;
           e = c;
       end
       c = [];
   end
end   

这个m的值就是我们的答案,这个MATLAB跟我们c差不多,这里就不多介绍了,很简单

第二问分析

第二问就是在第一问的基础上加了一个旋转

那我们是先旋转还是先平移呢?

其实都可以,我这里选择的是先旋转,读者可以自行思考另外一个情况

我们要知道我们已经知道了这个点的坐标,那么我们就要把他基于原点的角度知道,这里使用arctan就好了,可以直接求取角度,在原有的角度上进行增加角度,然后转动的只后把这个x和y计算出来,在井的坐标上加上就好了,这个就是旋转,平移更上述的一样

首先我们先要利用MATLAB来进行变成才好理解构建模型

cpp 复制代码
a = [0.50,1.41,3.00,3.37,3.40,4.72,4.72,5.43,7.57,8.38,8.98,9.50];
b = [2.00,3.50,1.50,3.51,5.50,2.00,6.24,4.10,2.01,4.50,3.41,0.80];
max = 0;
rr = atan(b./a);
long = sqrt(a.^2 + b.^2);

for ang = 0:0.01:pi*2
    for x = 0:0.01:1
        for y = 0:0.01:1
            m = 0;
            for i = 1:12
            xx = long(i) * cos(rr(i) + ang);
            yy = long(i) * sin(rr(i) + ang);
            aa = xx + x;
            bb = yy + y;
                if sqrt((aa - round(aa))^2 + (bb - round(bb))^2) <= 0.05
                   m = m + 1;
                end
            end 
            if max < m
                max = m; 
            end   
        end
    end     
end    

我们利用原长来计算这个转动的x和y然后再加上平移就好了,注意这里的是计算欧里距离,别弄错了,如果这个理解了之后就可以进行模型的搭建了,这里是作者自己构建的,每个模型都是不一样,但是意思正确即可

这个是作者自己构建的,有了这个模型我们就可以再LINGO上面敲出来了

cpp 复制代码
sets:
  aa/1..12/:a,b,f,p,ang1,ang2,liang1,liang2,c;
endsets

data:
  a = 0.50,1.41,3.00,3.37,3.40,4.72,4.72,5.43,7.57,8.38,8.98,9.50;
  b = 2.00,3.50,1.50,3.51,5.50,2.00,6.24,4.10,2.01,4.50,3.41,0.80;
enddata

calc:
@for(aa(i):c(i)=@atan(b(i)/a(i)));
@for(aa(i):p(i)=@sqrt(a(i)^2 + b(i)^2));
endcalc

max = @sum(aa(i):f(i));
@for(aa(i):@bin(f(i)));
x<1;
y<1;
w<3.14/2;
@for(aa(i):ang1(i)=@cos(c(i)+w));
@for(aa(i):ang2(i)=@sin(c(i)+w));
!@for(aa(i):liang1(i)=p(i)*ang1(i));
!@for(aa(i):liang2(i)=p(i)*ang2(i));
!@for(aa(i):@free(liang1(i)));
!@for(aa(i):@free(liang2(i)));
@for(aa(i):@free(ang1(i)));
@for(aa(i):@free(ang2(i)));
@for(aa(i):@sqrt((p(i)*ang1(i) + x -@floor(p(i)*ang1(i) + x + 0.5))^2 + (p(i)*ang2(i) + y-@floor(p(i)*ang2(i) + y + 0.5))^2)*f(i)<=0.05);

由于我们的编程的刚开始的算法很慢,然后作者就加了注释不断地优化,这里calc是数值区域,其他就是条件区域,这里要知道才可以进行算法地优化

最后地答案是6

然后这里要设置自由变量,因为lINGO是他这个角度地cos和sin如果取到了负值就默认正值,所以要设置为自由变量


总结

这里主要是非线性规划,怎么看出来的,因为乘以了未知量,模型地构建就是要抓住变量和约束条件,然后还理解了LINGO和MATLAB这两个工具地好处和编写

相关推荐
烟锁池塘柳09 小时前
【数学建模】灰色关联分析模型详解与应用
算法·数学建模
ToreanonyTang15 小时前
自动驾驶AEB误触发率评估的必要测试里程估计
人工智能·数学建模·自动驾驶
科研小白_16 小时前
2025年优化算法:人工旅鼠算法(Artificial lemming algorithm,ALA)
人工智能·算法·机器学习·数学建模·数据挖掘·回归
数模竞赛Paid answer19 小时前
2024年国赛高教杯数学建模E题交通流量管控解题全过程文档及程序
数学建模·全国大学生数学建模竞赛·国赛高教杯
烟锁池塘柳01 天前
【数学建模】TOPSIS法简介及应用
算法·数学建模
郝YH是人间理想2 天前
Python、MATLAB和PPT完成数学建模竞赛中的地图绘制
开发语言·python·数学建模·matlab·echarts
烟锁池塘柳02 天前
【数学建模】熵权法
算法·数学建模
一头大学牲3 天前
数学建模:常用模型
数学建模
嵌入式冰箱3 天前
2024 年第四届高校大数据挑战赛-赛题 A:岩石的自动鉴定
数学建模