数学建模算法整理

数学建模常用算法

1. 大多数建模赛题中都离不开计算机仿真,随机性模拟是非常常见的算法之一。

举个例子就是97 年的A 题,每个零件都有自己的标定值,也都有自己的容差等级,而求解最优的组合方案将要面对着的是一个极其复杂的公式和108 种容差选取方案,根本不可能去求解析解,那如何去找到最优的方案呢?随机性模拟搜索最优方案就是其中的一种 方法,在每个零件可行的区间中按照正态分布随机的选取一个标定值和选取一个容差值作为一种方案,然后通过蒙特卡罗算法仿真出大量的方案,从中选取一个最佳的。另一个例子就是去年的彩票第二问,要求设计一种更好的方案,首先方案的优劣取决于很多复杂的因素,同样不可能刻画出一个模型进行求解,只能靠随机仿真模拟。

1.1 蒙特卡罗算法

蒙特卡罗模拟

就是随机数相关的东西,你只要知道随机数是怎么得到。其它的事就要好办了。

rand(m,n)产生m*n均匀随机数。

ex:

用概率方法求pi

N=100000;

x=rand(N,1);

y=rand(N,1);

count=0;

for i=1:N

if (x(i)^2+y(i)^2

count=count+1;

end

end

PI=4*count/N

试给出下面赌博中的蒙特卡洛模拟

在一次旅游途中,小王看到有人用20枚签(其中10枚标有5分分值,10枚标有10分分值) 设赌。让游客从中抽出10枚,以10枚签的分值总和为奖罚金额,见表1

表1

分值 50,100 55,95 60,65,85,90 70,75,80

奖罚金额 奖100元 奖10元 不奖不罚 罚1元

你看,有奖有罚,在11个分值中有4个分值可以获奖,且最高奖额为100元;只有3个分值要受罚,而罚额仅为1元,很有吸引力吧?怪不得有些游客摩拳擦掌,跃跃欲试。那么这些奖是不是这么好拿呢?

试分析此游戏中,谁是真正的赢家?

%%假设前10个分值为5,后10个分值为10

income=0; %% 收入

n=10000; %% 模拟次数, 即有n 个人参加游戏

for i=1:n

a=randperm(20);

a=a(1:10);

b=find(a>10); %%10分分值的

sumb=length(b)*10+(10-length(b))*5;

if sumb==50||sumb==100

income=income-100;

elseif sumb==55||sumb==95

income=income-10;

elseif sumb==70||sumb==75||sumb==80

income=income+1;

end

end

Income

2. 数据拟合、参数估计、插值等算法

数据拟合在很多赛题中有应用,与图形处理有关的问题很多与拟合有关系,一个例子就是98 年美国赛A 题,生物组织切片的

三维插值处理,94 年A 题逢山开路,山体海拔高度的插值计算,还有吵的沸沸扬扬可能会考的“非典”问题也要用到数据拟合算法,观察

数据的走向进行处理。此类问题在MA TLAB 中有很多现成的函数可

以调用,熟悉MATLAB ,这些方法都能游刃有余的用好。

2.1 三次样条插值在 Matlab 中的实现

在 Matlab 中数据点称之为断点。如果三次样条插值没有边界条件,最常用的方

法,就是采用非扭结(not-a-knot )条件。这个条件强迫第 1 个和第 2 个三多

项式的三阶导数相等。对最后一个和倒数第 2 个三次多项式也做同样地处理。 Matlab 中三次样条插值也有现成的函数:

y=interp1(x0,y0,x,'spline');

y=spline(x0,y0,x);

pp=csape(x0,y0,conds),y=ppval(pp,x)。

其中x0,y0是已知数据点,x 是插值点,y 是插值点的函数值。

对于三次样条插值,我们提倡使用函数csape ,csape 的返回值是 pp 形式,要

求插值点的函数值,必须调用函数 ppval。

pp=csape(x0,y0):使用默认的边界条件,即 Lagrange 边界条件。

pp=csape(x0,y0,conds)中的 conds 指定插值的边界条件,其值可为:

'complete' 边界为一阶导数,即默认的边界条件

'not-a-knot' 非扭结条件

'periodic' 周期条件

'second' 边界为二阶导数,二阶导数的值[0, 0]。

'variational' 设置边界的二阶导数值为[0,0]。

对于一些特殊的边界条件,可以通过 conds 的一个

1×2矩阵来表示,conds 元素的取值为 1,2。此时,使用命令

pp=csape(x0,y0_ext,conds)

其中 y0_ext=[left,y0,right],这里 left 表示左边界的取值,right 表示右

边界的取值。

conds(i)=j 的含义是给定端点i 的 j 阶导数, 即 conds 的第一个元素表示

左边界的条

件,第二个元素表示右边界的条件,conds=[2,1]表示左边界是二阶导数,右边

界是一阶

导数,对应的值由 left 和 right 给出。

2.2 二维插值

前面讲述的都是一维插值,即节点为一维变量,插值函数是一元函数(曲线) 。若节点是二维的,插值函数就是二元函数,即曲面。如在某区域测量了若干点(节

点)的高程(节点值) ,为了画出较精确的等高线图,就要先插入更多的点(插

值点) ,计算这些点的高程(插值)。

2.1.1 插值节点为网格节点

已知m ×n 个节点:(x i , y j , z ij ) (i=1,2.....m;j=1,2.....n)并且

(x 1

Matlab 中有一些计算二维插值的程序。如

z=interp2(x0,y0,z0,x,y,'method')

其中 x0,y0 分别为m 维和n 维向量,表示节点,z0 为n ×m 维矩阵,表示节点

值,x,y 为一维数组,表示插值点,x 与 y 应是方向不同的向量,即一个是行

向量,另一个是列向量,z 为矩阵,它的行数为 y 的维数,列数为 x 的维数,

表示得到的插值,'method' 的用法同上面的一维插值。

如果是三次样条插值,可以使用命令

pp=csape({x0,y0},z0,conds,valconds),z=fnval(pp,{x,y})

其中 x0,y0 分别为m 维和n 维向量,z0 为

m ×n 维矩阵,z 为矩阵,它的行数为x 的维数,列数为 y 的维数,表示得到的

插值,具体使用方法同一维插值。

例2 在一丘陵地带测量高程,x 和 y 方向每隔100米测一个点,得高程如2表,

试插值一曲面,确定合适的模型,并由此找出最高点和该点的高程。

解:编写程序如下:

clear,clc

x=100:100:500;

y=100:100:400;

z=[636 697 624 478 450

698 712 630 478 420

680 674 598 412 400

662 626 552 334 310];

pp=csape({x,y},z')

xi=100:10:500;yi=100:10:400

cz1=fnval(pp,{xi,yi})

cz2=interp2(x,y,z,xi,yi','spline')

[i,j]=find(cz1==max(max(cz1)))

x=xi(i),y=yi(j),zmax=cz1(i,j)

2.1.2 插值节点为散乱节点

已知n 个节点:(x i , y i , z i ) (i=1,2.....n)

求点(x ,y) 处的插值z 。

对上述问题,Matlab 中提供了插值函数 griddata,其格式为:

ZI = GRIDDATA(X,Y,Z,XI,YI)

其中 X、Y 、Z 均为 n 维向量,指明所给数据点的横坐标、纵坐标和竖坐标。向

量 XI、YI 是给定的网格点的横坐标和纵坐标,返回值 ZI 为网格(XI ,YI )处

的函数值。XI 与 YI 应是方向不同的向量,即一个是行向量,另一个是列向量。

例3 在某海域测得一些点(x,y )处的水深 z 由下表给出,在矩形区域(75,200)

×(-50,150) 内画出海底曲面的图形。

解:编写程序如下:

x=[129 140 103.5 88 185.5 195 105 157.5 107.5 77 81 162

162 117.5];

y=[7.5 141.5 23 147 22.5 137.5 85.5 -6.5 -81 3 56.5

-66.5 84 -33.5];

z=-[4 8 6 8 6 8 8 9 9 8 8 9

4 9];

xi=75:1:200;

yi=-50:1:150;

zi=griddata(x,y,z,xi,yi','cubic')

subplot(1,2,1), plot(x,y,'*')

subplot(1,2,2), mesh(xi,yi,zi)

2.2 最小二乘法的 Matlab 实现

2.2.1 解方程组方法

在上面的记号下, J (a 1,..., a m ) =RA -Y

Matlab 中的线性最小二乘的标准型为 min RA -Y A 222,

命令为:A=R\Y。

例 4 用最小二乘法求一个形如:

y =a +bx 2

的经验公式,使它与如下所示的数据拟合。

x 19 25 31 38 44

y 19.0 32.3 49.0 73.3 97.8

解 编写程序如下

x=[19 25 31 38 44]';

y=[19.0 32.3 49.0 73.3 97.8]';

r=[ones(5,1),x.^2];

ab=r\y

x0=19:0.1:44;

y0=ab(1)+ab(2)*x0.^2;

plot(x,y,'o',x0,y0,'r')

2.2.2 多项式拟合方法

如果取:{r 1(x ), r 2(x )..... r m +1(x )}={1, x 1..... x m }

即用m 次多项式拟合给定数据, Matlab中有现成的函数

a=polyfit(x0,y0,m)

其中输入参数 x0,y0 为要拟合的数据,m 为拟合多项式的次数,输出参数 a 为

拟合多项式 y=amxm+…+a1x+a0系数 a=[ am, …, a1, a0]。

多项式在 x 处的值 y 可用下面的函数计算

y=polyval(a,x)。

2.3 规划类问题算法

竞赛中很多问题都和数学规划有关,可以说不少的模型都可

以归结为一组不等式作为约束条件、几个函数表达式作为目标函数的

问题,遇到这类问题,求解就是关键了,比如98年B 题,用很多不

等式完全可以把问题刻画清楚,因此列举出规划后用Lindo 、Lingo 等

软件来进行解决比较方便,所以还需要熟悉这两个软件。

2.3.1 求解线性规划的 Matlab 解法

单纯形法是求解线性规划问题的最常用、最有效的算法之一。下面我们介绍线性

规划的 Matlab

解法。

Matlab 中线性规划的标准型为:

min z =C T X x

⎧Ax ≤b ⎪s . t ⎨Aeq . x =beq

⎪lb ≤x ≤ub ⎩

基本函数形式为 linprog(c,A,b), 它的返回值是向量 x 的值。 还有其它的一

些函数调用形式(在 Matlab 指令窗运行 help linprog 可以看到所有的函数调

用形式), 如:

[x,fval]=linprog(c,A,b,Aeq,beq,LB,UB,X0,OPTIONS)

这里 fval 返回目标函数的值, LB 和 UB 分别是变量 x 的下界和上界,x0是

x 的初始值,OPTIONS 是控制参数。

例 2 求解下列线性规划问题

max z =2x 1+3x 2-5x 3

⎧x 1+x 2+x 3=7⎪2x -5x +x ≥10 ⎪223s . t ⎨⎪x 1+3x 2+x 3≤12

⎪⎩x 1, x 2, x 3≥0

解 (i )编写 M 文件

c=[2;3;-5];

a=[-2,5,-1;1,3,1]; b=[-10;12];

aeq=[1,1,1];

beq=7;

x=linprog(-c,a,b,aeq,beq,zeros(3,1))

value=c'*x

§4 蒙特卡洛法(随机取样法)

前面介绍的常用的整数规划求解方法, 主要是针对线性整数规划而言, 而对于

非线性整数规划目前尚未有一种成熟而准确的求解方法, 因为非线性规划本身

的通用有效解法尚未找到,更何况是非线性整数规划。

然而, 尽管整数规划由于限制变量为整数而增加了难度; 然而又由于整数解是

有限个,于是为枚举法提供了方便。当然,当自变量维数很大和取值范围很宽情

况下,企图用显枚举法(即穷举法)计算出最优值是不现实的,但是应用概率理

论可以证明,在一定的计算量的情况下,完全可以得出一个满意解。

例 7 已知非线性整数规划为:

max z =x 1+x 2+3x 3+4x 4+2x 5-8x 1-2x 2-3x 3-x 4-2x 5

⎧0≤x i ≤99(i =1... 5)⎪x +x +x +x +x ≤40012345 ⎪⎪s . t ⎨x 1+2x 2+2x 3+x 4+6x 5≤800

⎪2x +x +6x ≤2003⎪12

⎪⎩x 3+x 4+5x 5≤20022222

如果用显枚举法试探,共需计算1010个点,其计算量非常之大。然而应用蒙特卡

洛去随机计算106个点,便可找到满意解,那么这种方法的可信度究竟怎样呢?

下面就分析随机取样采集106个点计算时,应用概率理论来估计一下可信度。不

失一般性,假定一个整数规划的最优点不是孤立的奇点。假设目标函数落在高值

区的概率分别为 0.01,0.00001,则当计算 个点后,有任一个点能落在高值区

的概率分别为:

1-0. 991000000≈0. 99..... 99(100多位)

1-0. [1**********]0 ≈0. 999954602。

解 (i )首先编写 M 文件 mente.m 定义目标函数 f 和约束向量函数 g,程序

如下:

function [f,g]=mengte(x);

f=x(1)^2+x(2)^2+3*x(3)^2+4*x(4)^2+2*x(5)-8*x(1)-2*x(2)-3*x(3)-...

x(4)-2*x(5);

g=[sum(x)-400

x(1)+2*x(2)+2*x(3)+x(4)+6*x(5)-800

2*x(1)+x(2)+6*x(3)-200

x(3)+x(4)+5*x(5)-200];

(ii )编写M 文件mainint.m 如下求问题的解:

rand('state',sum(clock));

p0=0;

tic

for i=1:10^6

x=99*rand(5,1);

x1=floor(x);x2=ceil(x);

[f,g]=mengte(x1);

if sum(g

if p0

x0=x1;p0=f;

end

end

[f,g]=mengte(x2);

if sum(g

if p0

x0=x2;p0=f;

end

end

end

x0,p0

toc

本题可以使用LINGO 软件求得精确的全局最有解,程序如下:

model:

sets:

row/1..4/:b;

col/1..5/:c1,c2,x;

link(row,col):a;

endsets

data:

c1=1,1,3,4,2;

c2=-8,-2,-3,-1,-2;

a=1 1 1 1 1

1 2 2 1 6

2 1 6 0 0

0 0 1 1 5;

b=400,800,200,200;

enddata

max=@sum(col:c1*x^2+c2*x);

@for(row(i):@sum(col(j):a(i,j)*x(j))

@for(col:@gin(x));

@for(col:@bnd(0,x,99));

end

解 (i )编写 M 文件 fun1.m 定义目标函数

function f=fun1(x);

f=sum(x.^2)+8;

(ii )编写M 文件fun2.m 定义非线性约束条件

function [g,h]=fun2(x);

g=[-x(1)^2+x(2)-x(3)^2

x(1)+x(2)^2+x(3)^3-20]; %非线性不等式约束

h=[-x(1)-x(2)^2+2

x(2)+2*x(3)^2-3]; %非线性等式约束

(iii )编写主程序文件 example2.m 如下:

options=optimset('largescale','off');

[x,y]=fmincon('fun1',rand(3,1),[],[],[],[],zeros(3,1),[], ...

'fun2', options)

解:编写 M 文件 fun2.m 如下:

function [f,g]=fun2(x);

f=100*(x(2)-x(1)^2)^2+(1-x(1))^2;

g=[-400*x(1)*(x(2)-x(1)^2)-2*(1-x(1));200*(x(2)-x(1)^2)]; 编写主函数文件example6.m 如下:

options = optimset('GradObj','on');

[x,y]=fminunc('fun2',rand(1,2),options) 即可求得函数的极小值。

在求极值时,也可以利用二阶导数,编写 M 文件 fun3.m 如下: function [f,df,d2f]=fun3(x);

f=100*(x(2)-x(1)^2)^2+(1-x(1))^2;

df=[-400*x(1)*(x(2)-x(1)^2)-2*(1-x(1));200*(x(2)-x(1)^2)]; d2f=[-400*x(2)+1200*x(1)^2+2,-400*x(1)

-400*x(1),200];

编写主函数文件example62.m 如下:

options = optimset('GradObj','on','Hessian','on'); [x,y]=fminunc('fun3',rand(1,2),options) 即可求得函数的极小值。

求多元函数的极值也可以使用 Matlab 的 fminsearch 命令,其使用格式为: [X,FVAL,EXITFLAG,OUTPUT]=

FMINSEARCH(FUN,X0,OPTIONS,P1,P2,...)

function f=fun4(x); f=sin(x)+3;

编写主函数文件example7.m 如下: x0=2;

[x,y]=fminsearch(@fun4,x0)

即求得在初值 2 附近的极小点及极小值。

Matlab 中求解二次规划的命令是

[X,FVAL]= QUADPROG(H,f,A,b,Aeq,beq,LB,UB,X0,OPTIONS)

返回值 X 是决策向量 x 的值,返回值 FVAL 是目标函数在 x 处的值。 (具体细节可以参

看在 Matlab 指令中运行 help quadprog 后的帮助) 。 例 8 求解二次规划

h=[4,-4;-4,8]; f=[-6;-3]; a=[1,1;4,1];

b=[3;9];

[x,value]=quadprog(h,f,a,b,[],[],zeros(2,1))

解 (1)编写 M 文件 fun6.m 定义目标函数如下: function f=fun6(x,s); f=sum((x-0.5).^2);

(2)编写 M 文件 fun7.m 定义约束条件如下: function [c,ceq,k1,k2,s]=fun7(x,s); c=[];ceq=[];

if isnan(s(1,1)) s=[0.2,0;0.2 0]; end

%取样值

w1=1:s(1,1):100; w2=1:s(2,1):100; %半无穷约束

k1=sin(w1*x(1)).*cos(w1*x(2))-1/1000*(w1-50).^2-sin(w1*x(3))-x(3)-1; k2=sin(w2*x(2)).*cos(w2*x(1))-1/1000*(w2-50).^2-sin(w2*x(3))-x(3)-1; %画出半无穷约束的图形

plot(w1,k1,'-',w2,k2,'+'); (3)调用函数 fseminf 在 Matlab 的命令窗口输入

[x,y]=fseminf(@fun6,rand(3,1),2,@fun7) 即可。

解 (1)编写 M 文件 fun8.m 定义向量函数如下: function f=fun8(x);

f=[2*x(1)^2+x(2)^2-48*x(1)-40*x(2)+304 -x(1)^2-3*x(2)^2 x(1)+3*x(2)-18

-x(1)-x(2) x(1)+x(2)-8];

(2)调用函数 fminimax

[x,y]=fminimax(@fun8,rand(2,1))

解 (1)编写 M 文件 fun9.m 定义目标函数及梯度函数: function [f,df]=fun9(x);

f=exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1);

df=[exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+8*x(1)+6*x(2)+1);exp(x(1))*(4*x(2) +4*x(1)+2)];

(2)编写 M 文件 fun10.m 定义约束条件及约束条件的梯度函数: function [c,ceq,dc,dceq]=fun10(x);

c=[x(1)*x(2)-x(1)-x(2)+1.5;-x(1)*x(2)-10]; dc=[x(2)-1,-x(2);x(1)-1,-x(1)]; ceq=[];dceq=[];

(3)调用函数 fmincon,编写主函数文件 example13.m 如下: %采用标准算法

options=optimset('largescale','off'); %采用梯度

options=optimset(options,'GradObj','on','GradConstr','on'); [x,y]=fmincon(@fun9,rand(2,1),[],[],[],[],[],[],@fun10,options)

3.4 Matlab 优化工具箱的用户图形界面解法:

Matlab 优化工具箱中的 optimtool 命令提供了优化问题的用户图形界面解法。 optimtool 可应用到所有优化问题的求解,计算结果可以输出到 Matlab 工作空间中。

2.4 图论问题

98 年B 题、00 年B 题、95 年锁具装箱等问题体现了图

论问题的重要性,这类问题算法有很多,包括:Dijkstra 、Floyd 、Prim 、Bellman-Ford ,最大流,二分匹配等问题。每一个算法都应该实现一遍,否则到比赛时再写就晚了。 2.4.1 两个指定点间的最短路径

Dijkstra 算法(单源最短路径边权非负)

w=[0 8 inf inf inf inf 7 inf inf inf inf;inf 0 3 inf inf inf 6 inf inf inf inf;...

inf inf 0 5 6 inf inf inf inf inf inf;inf inf inf 0 1 inf inf inf inf inf 12;...

inf inf inf inf 0 2 inf inf inf 9 inf;inf inf inf inf inf 0 9 inf 3 inf inf;...

inf inf 5 inf inf inf 0 10 inf inf inf;8 inf inf inf inf inf inf 0 inf inf inf;...

inf inf inf inf 7 inf inf 9 0 inf inf;inf inf inf inf inf inf inf inf 2 0 2;...

inf inf inf inf 10 inf inf inf inf inf 0] n=size(w,1); w1=w(1,:); for i=1:n

dist(i)=w1(i); path(i)=1; end s=[]; s(1)=1; u=s(1); k=1 dist path

while k

for j=1:k

if i~=s(j)

if dist(i)>dist(u)+w(u,i) dist(i)=dist(u)+w(u,i); path(i)=u; end end end end dist path

distdist=dist; for i=1:n

for j=1:k

if i~=s(j)

distdist(i)=distdist(i); else

distdist(i)=inf; end end end

distv=inf; for i=1:n

if distdist(i)

s(k+1)=v k=k+1 u=s(k) end dist path

Linggo 代码:

编写 LINGO 程序如下: model: sets:

cities/A,B1,B2,C1,C2,C3,D/;

roads(cities,cities)/A B1,A B2,B1 C1,B1 C2,B1 C3,B2 C1, B2 C2,B2 C3,C1 D,C2 D,C3 D/:w,x; endsets data:

w=2 4 3 3 1 2 3 1 1 3 4; enddata

n=@size(cities); !城市的个数; min=@sum(roads:w*x);

@for(cities(i)|i #ne#1 #and# i #ne#n:

@sum(roads(i,j):x(i,j))=@sum(roads(j,i):x(j,i))); @sum(roads(i,j)|i #eq#1:x(i,j))=1; @sum(roads(i,j)|j #eq#n:x(i,j))=1; end

编写 LINGO 程序如下: model: sets:

cities/1..11/;

roads(cities,cities):w,x; endsets data: w=0; enddata calc:

w(1,2)=2;w(1,3)=8;w(1,4)=1; w(2,3)=6;w(2,5)=1;

w(3,4)=7;w(3,5)=5;w(3,6)=1;w(3,7)=2; w(4,7)=9;

w(5,6)=3;w(5,8)=2;w(5,9)=9; w(6,7)=4;w(6,9)=6; w(7,9)=3;w(7,10)=1; w(8,9)=7;w(8,11)=9;

w(9,10)=1;w(9,11)=2;w(10,11)=4;

@for(roads(i,j):w(i,j)=w(i,j)+w(j,i));

@for(roads(i,j):w(i,j)=@if(w(i,j) #eq# 0, 1000,w(i,j))); endcalc

n=@size(cities); !城市的个数; min=@sum(roads:w*x);

@for(cities(i)|i #ne#1 #and# i #ne#

n:@sum(cities(j):x(i,j))=@sum(cities(j):x(j,i))); @sum(cities(j):x(1,j))=1;

@sum(cities(j):x(j,1))=0; !不能回到顶点1; @sum(cities(j):x(j,n))=1; @for(roads:@bin(x)); end

与有向图相比较,在程序中只增加了一个语句@sum(cities(j):x(j,1))=0,即 从顶点 1 离开后,再不能回到该顶点。

求得的最短路径为 1→2→5→6→3→7→10→9→11,最短路径长度为 13。

2.4.2 Flord算法

%a=[0 50 inf inf inf;inf 0 inf inf 80;inf 30 0 20 inf;inf inf inf 0 70;65 inf 100 inf 0];

function [D,path]=floyd(a) % Floyd’s Algorithm n=size(a,1);

%设置D 和Path 的初值 D=a;path=zeros(n,n); for i=1:n for j=1:n if D(i,j)~=inf

path(i,j)=j; %j是i 的后继点 end end end

%做n 次迭代, 每次迭代均更新D(i,j)和path(i,j) for k=1:n for i=1:n for j=1:n

if D(i,k)+D(k,j)

D(i,j)=D(i,k)+D(k,j) %修改长度 path(i,j)=path(i,k) %修改路径 end end end end

%a=[0 50 inf inf inf;inf 0 inf inf 80;inf 30 0 20 inf;inf inf inf 0 70;65 inf 100 inf 0]; %[D,path]=floyd(a)

2.4.3 prim算法(最优选线问题,最小生成树)

clear;

a=[0 8 inf 1 5; 8 0 6 inf 7; inf 6 0 9 10; 1 inf 9 0 3; 5 7 10 3 0];

T=[];c=0;v=1;n=5;sb=2:n;

for j=2:n b(1,j-1)=1; b(2,j-1)=j; b(3,j-1)=a(1,j); end

while size(T,2)

[tmin,i]=min(b(3,:)); T(:,size(T,2)+1)=b(:,i); c=c+b(3,i); v=b(2,i);

temp=find(sb == b(2,i)); sb(temp)=[];b(:,i)=[]; for j=1:length(sb) d=a(v,b(2,j)); if d

b(1,j)=v;b(3,j)=d; end end end T,c

2.4.4 Bellman-Ford算法(单源最短路径边权可正可负)

function [D,R]= floydwarshall(A)

% %采用floyd 算法计算图中任意两点之间最短路程,可以有负权。 %参数D 为连通图的权矩阵 %R是路由矩阵

D=A; n=length(D); %赋初值

for (i=1:n)for (j=1:n)R(i,j)=j;end ; end %赋路径初值 for (k=1:n) for (i=1:n) for (j=1:n)

if (D(i,k)+D(k,j)

R(i,j)=k;end ; end ; end %更新rij ,需要通过k k; %显示迭代步数 D; %显示每步迭代后的路长 R; %显示每步迭代后的路径 pd=0;for i=1:n %含有负权时

if (D(i,i)

if (pd==1) fprintf(' 有负回路' ); break ; end %存在一条负回路, 跳出最外层循环 终止程序

end %程序结束

2.4.5 最大流算法

function [flow,val]=mincostmaxflow(rongliang,cost,flowvalue); %第一个参数:容量矩阵;第二个参数:费用矩阵; %前两个参数必须在不通路处置零

%第三个参数:指定容量值(可以不写,表示求最小费用最大流) %返回值flow 为可行流矩阵,val 为最小费用值 global M

flow=zeros(size(rongliang));allflow=sum(flow(1,:)); if nargin

while allflow

w=(flow0).*cost)'; path=floydpath(w);%调用floydpath 函数 if isempty(path)

val=sum(sum(flow.*cost)); return ; end

theta=min(min(path.*(rongliang-flow)+(path.*(rongliang-flow)==0).*M));

theta=min([min(path'.*flow+(path'.*flow==0).*M),theta]); flow=flow+(rongliang>0).*(path-path').*theta; allflow=sum(flow(1,:)); end

val=sum(sum(flow.*cost));

2.4.6 二分匹配

二分图最大匹配 匈牙利算法

#include #include const int N=502; int map[N][N];

int link[N],useif[N]; int n,m; int can(int t)

{

for (int i=1;i

if (useif[i]==0 && map[t][i]) {

useif[i]=1;

if (link[i]==-1 || can(link[i])) {

link[i]=t; return 1; } } }

return 0; }

int maxmatch() {

int i,num; num=0;

memset(link,-1, sizeof (link)); for (i=1;i

memset(useif,0, sizeof (useif)); if (can(i)) num++; }

return num; }

int main() {

int k,a,b;

while (scanf("%d",&k),k) {

scanf("%d%d",&n,&m); memset(map,0, sizeof (map)); while (k--) {

scanf("%d%d",&a,&b); map[a][b]=1; }

printf("%d\n",maxmatch()); }

return 0; }

2.5 计算机算法设计中的问题

计算机算法设计包括很多内容:动态规划、回溯搜索、分治算法、分支定界。比如92 年B 题用分枝定界法,97 年B 题是典型的动态规划问题,此外98 年B 题体现了分治算法。这方面问题和ACM 程序设计竞赛中的问题类似,推荐看一下《计算机算法设计与分析》(电子工业出版社)等与计算机算法有关的书。 2.5.1 动态规划

如果一个问题能用动态规划方法求解,那么,我们可以按下列步骤首先建立起动态规划的数学模型:

(i )将过程划分成恰当的阶段。 (ii )正确选择状态变量时确定允许状态集合

X k

x k

,使它既能描述过程的状态,又满足无后效性,同

()(iii )选择决策变量u k ,确定允许决策集合U k x k

(iv )写出状态转移方程。

(v )确定阶段指标v k (x k , u k )及指标函数V kn 的形式(阶段指标之和,阶段指标之积,阶段指标之极大或极小等)。

(vi )写出基本方程即最优值函数满足的递归方程,以及端点条件。

model:

Title Dynamic Programming; sets:

vertex/A,B1,B2,C1,C2,C3,C4,D1,D2,D3,E1,E2,E3,F1,F2,G/:L;

road(vertex,vertex)/A B1,A B2,B1 C1,B1 C2,B1 c3,B2 C2,B2 C3,B2 C4, C1 D1,C1 D2,C2 D1,C2 D2,C3 D2,C3 D3,C4 D2,C4 D3, D1 E1,D1 E2,D2 E2,D2 E3,D3 E2,D3 E3,

E1 F1,E1 F2,E2 F1,E2 F2,E3 F1,E3 F2,F1 G,F2 G/:D; endsets data:

D=5 3 1 3 6 8 7 6 6 8 3 5 3 3 8 4 2 2 1 2 3 3

3 5 5 2 6 6 4 3; L=0,,,,,,,,,,,,,,,; enddata

@for(vertex(i)|i#GT#1:L(i)=@min(road(j,i):L(j)+D(j,i))); End

2.5.2分支定界

2.6.2 神经网络

下面利用上文所叙述的网络结构及方法,对蠓虫分类问题求解。编写 Matlab 程序 如下: clear

p1=[1.24,1.27;1.36,1.74;1.38,1.64;1.38,1.82;1.38,1.90; 1.40,1.70;1.48,1.82;1.54,1.82;1.56,2.08]; p2=[1.14,1.82;1.18,1.96;1.20,1.86;1.26,2.00 1.28,2.00;1.30,1.96]; p=[p1;p2]'; pr=minmax(p);

goal=[ones(1,9),zeros(1,6);zeros(1,9),ones(1,6)]; plot(p1(:,1),p1(:,2),'h',p2(:,1),p2(:,2),'o') net=newff(pr,[3,2],{'logsig','logsig'});

net.trainParam.show = 10; net.trainParam.lr = 0.05; net.trainParam.goal = 1e-10; net.trainParam.epochs = 50000; net = train(net,p,goal);

x=[1.24 1.80;1.28 1.84;1.40 2.04]'; y0=sim(net,p) y=sim(net,x)

层次分析法:

根据层次总排序权值,该生最满意的工作为工作 1。 计算的 Matlab 程序如下:

clc,clear

fid=fopen('txt3.txt','r'); n1=6;n2=3; a=[];

for i=1:n1

tmp=str2num(fgetl(fid));

a=[a;tmp]; %读准则层判断矩阵 end

for i=1:n1

str1=char(['b',int2str(i),'=[];']);

str2=char(['b',int2str(i),'=[b',int2str(i),';tmp];']); eval(str1); for j=1:n2

tmp=str2num(fgetl(fid));

eval(str2); %读方案层的判断矩阵 end end

ri=[0,0,0.58,0.90,1.12,1.24,1.32,1.41,1.45]; %一致性指标 [x,y]=eig(a);

lamda=max(diag(y));

num=find(diag(y)==lamda); w0=x(:,num)/sum(x(:,num)); cr0=(lamda-n1)/(n1-1)/ri(n1) for i=1:n1

[x,y]=eig(eval(char(['b',int2str(i)]))); lamda=max(diag(y));

num=find(diag(y)==lamda); w1(:,i)=x(:,num)/sum(x(:,num)); cr1(i)=(lamda-n2)/(n2-1)/ri(n2); end

cr1, ts=w1*w0, cr=cr1*w0

纯文本文件txt3.txt 中的数据格式如下: 1 1 1 4 1 1/2 1 1 2 4 1 1/2 1 1/2 1 5 3 1/2 1/4 1/4 1/5 1 1/3 1/3 1 1 1/3 3 1 1 2 2 2 3 3 1 1 1/4 1/2 4 1 3 2 1/3 1 1 1/4 1/5 4 1 1/2 5 2 1

1 3 1/3

1/3 1 1/7

3 7 1

1 1/3 5

3 1 7

1/5 1/7 1

1 1 7

1 1 7

1/7 1/7 1

1 7 9

1/7 1 1

1/9 1 1

模糊算法(折衷型多目标决策优化)

mohu.txt

290 85 90 100 85 90 100 75 80 85 75 80 85 288 85 90 100 75 80 85 85 90 100 60 70 75

288 75 80 85 85 90 100 50 55 60 60 70 75

285 85 90 100 75 80 85 75 80 85 75 80 85

283 75 80 85 85 90 100 75 80 85 75 80 85

283 75 80 85 50 55 60 85 90 100 75 80 85

280 85 90 100 75 80 85 60 70 75 75 80 85

280 75 80 85 85 90 100 85 90 100 60 70 75

280 75 80 85 75 80 85 85 90 100 75 80 85

280 50 55 60 75 80 85 85 90 100 60 70 75

278 50 55 60 60 70 75 75 80 85 85 90 100

277 85 90 100 75 80 85 60 70 75 85 90 100

275 75 80 85 60 70 75 50 55 60 85 90 100

275 50 55 60 75 80 85 85 90 100 75 80 85

274 85 90 100 75 80 85 60 70 75 75 80 85

273 75 80 85 85 90 100 75 80 85 60 70 75

%数据存在纯文本文件 mohu.txt 中

clc,clear

load mohu.txt

sj=[repmat(mohu(:,1),1,3),mohu(:,2:end)];

%首先进行归一化处理

m=size(sj,1); n=size(sj,2)/3;

w=[0.5*ones(1,3),0.125*ones(1,12)];

w=repmat(w,m,1);

y=[];

%收益型指标对应的模糊指标值归一化处理

for i=1:n

tm=sj(:,3*i-2:3*i);

max_t=max(tm);

max_t=repmat(max_t,m,1);

max_t=max_t(:,3:-1:1);

yt=tm./max_t; yt(:,3)=min([yt(:,3)',ones(1,m)]); y=[y,yt];

end

%成本型指标对应的模糊指标值归一化处理

% for i=1:n

% tm=sj(:,3*i-2:3*i);

% min_t=min(tm);

% min_t=repmat(min_t,m,1);

% tm=tm(:,3:-1:1);

% yt=min_t./tm; yt(:,3)=min([yt(:,3)',ones(1,m)]); % y=[y,yt];

% end

%下面求模糊决策矩阵

r=[];

for i=1:n

tm1=y(:,3*i-2:3*i);tm2=w(:,3*i-2:3*i);

r=[r,tm1.*tm2];

end

%求 M +、M -和距离

mplus=max(r);mminus=min(r);

dplus=dist(mplus,r');dminus=dist(mminus,r');

%求隶属度

mu=dminus./(dplus+dminus);

[mu_sort,ind]=sort(mu,'descend')


相关文章

  • 数学一上第七单元小小运动会教案
  • 第七单元小小运动会 单元名称:小小运动会-20以内数的进位加法 单元教学内容:青岛版课本93-104页 单元教材分析: 本单元是在10以内数的加减法及20以内数的认识的基础上进行学习的.它是学习多位数计算的基础,也是进一步学习其他数学知识必 ...

  • 2015.8备课模板
  • 青岛版四年级数学上册 备课本 学校:唐坊镇第一小学 班级: 姓名: 年级 班 课题 课型 小小运动会 单元备课 使用时间 课时 二次备课 单元教材解读: 本单元是在 10 以内数的加减法及 20 以内数的认识的基础上进行学习的. 它是学 习 ...

  • 四.阅览室里的书
  • 四.阅览室里的书主题图 教学目标: 1.让学生经历观察阅览室场景图的过程,并根据相关的活动经验和图表.对话的信息,提出加减法计算的问题. 2.培养学生观察能力.获取信息的能力和表达交流能力. 3.对单元学习的内容有整体的感知,为学习本单元的 ...

  • 苏教版数学三年级上册教材分析
  • 苏教版课程标准实验教科书 数学 三年级(上册) 教材分析 全册教材安排 三年级是第一学段的最后一个学年,也是习惯划分的中年级的起始.经过 一.二年级的教学,学生发生了很大的变化,一方面表现在积累了许多数学知识和数学活动经验,学习数学的能力增 ...

  • 翼教版小学二年级数学上册教案
  • 翼教版小学二年级数学上册教案 二.加减混合运算 第一课时 教学目标: 1.结合具体情境,经历自主探索三个数连加的估算.计算的过程,体验算法多样化,学会灵活地进行计算. 2.能正确的计算100以内数的连加. 3.在于同学交流各自算法的过程中, ...

  • [长方体和正方体复习]听课反思
  • <十几减9>听课反思 you 我听了韦金荣主任关于<十几减9>这节课的教学,现做出听课反思如下:<十几减9>是新课程标准实验教材数学一年级下册第二单元第一课时的内容.本课教学在学生学习了20以内的进位加, ...

  • 数字高程模型期末整理复习资料
  • 数字高程模型期末复习资料 第一章 1. 高程用来描述地形表面的起伏形态,传统的高程模型是等高线,其数学意义是定义在二维地理空间上的连续曲面函数,当此高程模型用计算机来表达时,称为数字高程模型. 2. 的定义为:数字高程模型是对二维地理空间上 ...

  • 数学史论文
  • 数学史论文 --中世纪的中国数学 院系:数信学院 班级:数教一班 姓名:韩军香 学号:[1**********] 摘要:从公元476年西罗马帝国灭亡到14世纪文艺复兴长达1000多年的欧洲历史称为欧洲中世纪.与希腊数学相比,中世纪的东方数学 ...

  • 二年级数学下册教学计划
  • 一、教学内容这册教材包括下面一些内容:解决问题、表内除法(一)、图形与变化、表内除(二)、万以内数的认识、克和千克的认识、万以内的加法和减法(一)、统计、找规律、总复习等。 这册教材的计算教学内容是万以内的加、减法笔算和表内除法。这两部分内 ...

© 2024 范文参考网 | 联系我们 webmaster# 12000.net.cn