文档库 最新最全的文档下载
当前位置:文档库 › 中国数学建模-编程交流-贪婪算法_1

中国数学建模-编程交流-贪婪算法_1

中国数学建模-编程交流-贪婪算法_1
中国数学建模-编程交流-贪婪算法_1

中国数学建模-编程交流-贪婪算法

wh-ee 重登录隐身用户控制面板搜索风格论坛状态论坛展区社区服务社区休闲网站首页退出

>> VC++,C,Perl,Asp...编程学习,算法介绍. 我的收件箱 (0)

中国数学建模→学术区→编程交流→贪婪算法

您是本帖的第 889 个阅读者

* 贴子主题:贪婪算法

b

等级:职业侠客

文章:470

积分:956

门派:黑客帝国

注册:2003-8-28

鲜花(0) 鸡蛋(0) 楼主

贪婪算法

第 1 章贪婪算法

虽然设计一个好的求解算法更像是一门艺术,而不像是技术,但仍然存在一些行之有效的能够用于解决许多问题的算法设计方法,你可以使用这些方法来设计算法,并观察这些算法是如何工作的。一般情况下,为了获得较好的性能,必须对算法进行细致的调整。但是在某些情况下,算法经过调整之后性能仍无法达到要求,这时就必须寻求另外的方法来求解该问题。

本章首先引入最优化的概念,然后介绍一种直观的问题求解方法:贪婪算法。最后,应用该算法给出货箱装船问题、背包问题、拓扑排序问题、二分覆盖问题、最短路径问题、最小代价生成树等问题的求解方案。

1.1 最优化问题

本章及后续章节中的许多例子都是最优化问题( optimization problem),每个最优化问题都包含一组限制条件( c o

n s t r a i n t)和一个优化函数( optimization

function),符合限制条件的问题求解方案称为可行解( feasible

solution),使优化函数取得最佳值的可行解称为最优解(optimal solution)。

例1-1 [ 渴婴问题]

有一个非常渴的、聪明的小婴儿,她可能得到的东西包括一杯水、一桶牛奶、多罐不同种类的果汁、许多不同的装在瓶子或罐子中的苏打水,即婴儿可得到n

种不同的饮料。根据以前关于这n

种饮料的不同体验,此婴儿知道这其中某些饮料更合自己的胃口,因此,婴儿采取如下方法为每一种饮料赋予一个满意度值:饮用1盎司第i

种饮料,对它作出相对评价,将一个数值si 作为满意度赋予第i 种饮料。

通常,这个婴儿都会尽量饮用具有最大满意度值的饮料来最大限度地满足她解渴的需要,但是不幸的是:具有最大满意度值的饮料有时并没有足够的量来满足此婴儿解渴的需要。设ai是第i

种饮料的总量(以盎司为单位),而此婴儿需要t 盎司的饮料来解渴,那么,需要饮用n种不同的饮料各多少量才能满足婴儿解渴的需求呢?

设各种饮料的满意度已知。令xi 为婴儿将要饮用的第i 种饮料的量,则需要解决的问题是:

找到一组实数xi(1≤i≤n),使n åi = 1si xi 最大,并满足:n åi=1xi =t 及0≤xi≤ai 。

需要指出的是:如果n åi = 1ai < t,则不可能找到问题的求解方案,因为即使喝光所有的饮料也不能使婴儿解渴。

对上述问题精确的数学描述明确地指出了程序必须完成的工作,根据这些数学公式,可以对输入/ 输出作如下形式的描述:

输入:n,t,si ,ai(其中1≤i≤n,n 为整数,t、si 、ai 为正实数)。

输出:实数xi(1≤i≤n),使n åi= 1si xi 最大且n åi=1xi =t(0≤xi≤ai)。如果n åi = 1ai

在这个问题中,限制条件是n åi= 1xi =t 且0≤xi≤ai,1≤i≤n。而优化函数是n åi= 1si xi

。任何满足限制条件的一组实数xi 都是可行解,而使n åi= 1si xi 最大的可行解是最优解。

例1-2 [装载问题] 有一艘大船准备用来装载货物。所有待装货物都装在货箱中且所有货箱的大小都一样,但货箱的重量都各不相同。设第i个货箱的重量为wi(1≤i ≤n),而货船的最大载重量为c,我们的目的是在货船上装入最多的货物。

这个问题可以作为最优化问题进行描述:设存在一组变量xi ,其可能取值为0或1。如xi 为0,则货箱i 将不被装上船;如xi

为1,则货箱i 将被装上船。我们的目的是找到一组xi ,使它满足限制条件n åi = 1wi xi ≤c 且x i Î {0,

1}, 1 ≤i≤n。相应的优化函数是n åi= 1xi 。

满足限制条件的每一组xi 都是一个可行解,能使n åi= 1xi 取得最大值的方案是最优解。

例1-3 [最小代价通讯网络]

城市及城市之间所有可能的通信连接可被视作一个无向图,图的每条边都被赋予一个权值,权值表示建成由这条边所表示的通信连接所要付出的代价。包含图中所有顶点(城市)的连通子图都是一个可行解。设所有的权值都非负,则所有可能的可行解都可表示成无向图的一组生成树,而最优解是其中具有最小代价的生成树。

在这个问题中,需要选择一个无向图中的边集合的子集,这个子集必须满足如下限制条件:所有的边构成一个生成树。而优化函数是子集中所有边的权值之和。

----------------------------------------------

plot(100+t+15*cos(3.05*t),t=0..200,coords=polar,axes=none,scaling=constrained); 2004-5-27 19:37:49

b

等级:职业侠客

文章:470

积分:956

门派:黑客帝国

注册:2003-8-28

第 2 楼

1.2 算法思想

在贪婪算法(greedy

method)中采用逐步构造最优解的方法。在每个阶段,都作出一个看上去最优的决策(在一定的标准下)。决策一旦作出,就不可再更改。作出贪婪决策的依据称为贪婪准则(greedy

criterion)。

例1-4 [找零钱]

一个小孩买了价值少于1美元的糖,并将1美元的钱交给售货员。售货员希望用数目最少的硬币找给小孩。假设提供了数目不限的面值为2 5美分、1 0美分、5美分、及1美分的硬币。售货员分步骤组成要找的零钱数,每次加入一个硬币。选择硬币时所采用的贪婪准则如下:每一次选择应使零钱数尽量增大。为保证解法的可行性(即:所给的零钱等于要找的零钱数),所选择的硬币不应使零钱总数超过最终所需的数目。

假设需要找给小孩6 7美分,首先入选的是两枚2 5美分的硬币,第三枚入选的不能是2 5美分的硬币,否则硬币的选择将不可行(零钱总数超过6 7美分),第三枚应选择1 0美分的硬币,然后是5美分的,最后加入两个1美分的硬币。

贪婪算法有种直觉的倾向,在找零钱时,直觉告诉我们应使找出的硬币数目最少(至少是接近最少的数目)。可以证明采用上述贪婪算法找零钱时所用的硬币数目的确最少(见练习1)。

例1-5 [机器调度] 现有n 件任务和无限多台的机器,任务可以在机器上得到处理。每件任务的开始时间为si,完成时间为fi ,si

< fi 。[si , fi ] 为处理任务i 的时间范围。两个任务i,j 重指两个任务的时间范围区间有重叠,而并非是指i,j

的起点或终点重合。例如:区间[ 1,4 ]与区间[ 2,4 ]重叠,而与区间[ 4,

]不重叠。一个可行的任务分配是指在分配中没有两件重叠的任务分配给同一台机器。因此,在可行的分配中每台机器在任何时刻最多只处理一个任务。最优分配是指使用的机器最少的可行分配方案。

假设有n= 7件任务,标号为a 到g。它们的开始与完成时间如图13-1a 所示。若将任务a分给机器M1,任务b 分给机器M2,. .

.,任务g

分给机器M7,这种分配是可行的分配,共使用了七台机器。但它不是最优分配,因为有其他分配方案可使利用的机器数目更少,例如:可以将任务a、b、d分配给同一台机器,则机器的数目降为五台。

一种获得最优分配的贪婪方法是逐步分配任务。每步分配一件任务,且按任务开始时间的非递减次序进行分配。若已经至少有一件任务分配给某台机器,则称这台机器是旧的;若机器非旧,则它是新的。在选择机器时,采用以下贪婪准则:根据欲分配任务的开始时间,若此时有旧的机器可用,则将任务分给旧的机器。否则,将任务分配给一台新的机器。

根据例子中的数据,贪婪算法共分为n = 7步,任务分配的顺序为a、f、b、c、g、e、d。第一步没有旧机器,因此将a

分配给一台新机器(比如M1)。这台机器在0到2时刻处于忙状态。在第二步,考虑任务f。由于当f 启动时旧机器仍处于忙状态,因此将f

分配给一台新机器(设为M2 )。第三步考虑任务b, 由于旧机器M1在Sb = 3时刻已处于闲状态,因此将b分配给M1执行,M1下一次可用时刻变成fb = 7,M2的可用时刻变成ff =

5。第四步,考虑任务c。由于没有旧机器在Sc = 4时刻可用,因此将c 分配给一台新机器(M3),这台机器下一次可用时间为fc =

7。第五步考虑任务g,将其分配给机器M2,第六步将任务e 分配给机器M1, 最后在第七步,任务2分配给机器M3。(注意:任务d

也可分配给机器M2)。

上述贪婪算法能导致最优机器分配的证明留作练习(练习7)。可按如下方式实现一个复杂性为O (nl o

gn)的贪婪算法:首先采用一个复杂性为O (nl o gn)的排序算法(如堆排序)按Si

的递增次序排列各个任务,然后使用一个关于旧机器可用时间的最小堆。

例1-6 [最短路径] 给出一个有向网络,路径的长度定义为路径所经过的各边的耗费之和。要求找一条从初始顶点s 到达目的顶点d

的最短路径。

贪婪算法分步构造这条路径,每一步在路径中加入一个顶点。假设当前路径已到达顶点q,

且顶点q 并不是目的顶点d。加入下一个顶点所采用的贪婪准则为:选择离q 最近且目前不在路径中的顶点。

这种贪婪算法并不一定能获得最短路径。例如,假设在图1 3 -

2中希望构造从顶点1到顶点5的最短路径,利用上述贪婪算法,从顶点1开始并寻找目前不在路径中的离顶点1最近的顶点。到达顶点3,长度仅为2个单位,从顶点3可以到达的最近顶点为4,从顶点4到达顶点2,最后到达目的顶点5。所建立的路径为1

, 3 , 4 , 2 , 5,其长度为1

0。这条路径并不是有向图中从1到5的最短路径。事实上,有几条更短的路径存在,例如路径1,4,5的长度为6。

根据上面三个例子,回想一下前几章所考察的一些应用,其中有几种算法也是贪婪算法。例如,霍夫曼树算法,利用n-

1步来建立最小加权外部路径的二叉树,每一步都将两棵二叉树合并为一棵,算法中所使用的贪婪准则为:从可用的二叉树中选出权重最小的两棵。L

P T调度规则也是一种贪婪算法,它用n 步来调度n

个作业。首先将作业按时间长短排序,然后在每一步中为一个任务分配一台机器。选择机器所利用的贪婪准则为:使目前的调度时间最短。将新作业调度到最先完成的机器上(即最先空闲的机器)。

注意到在机器调度问题中,贪婪算法并不能保证最优,然而,那是一种直觉的倾向且一般情况下结果总是非常接近最优值。它利用的规则就是在实际环境中希望人工机器调度所采用的规则。算法并不保证得到最优结果,但通常所得结果与最优解相差无几,这种算法也称为启发式方法(

h e u r i s t i c s )。因此L P T方法是一种启发式机器调度方法。定理

9 - 2陈述了L P

T调度的完成时间与最佳调度的完成时间之间的关系,因此L P T启发式方法具有限定性

能( bounded performance )。具有限定性能的启发式方法称为近似算法( a p p r o x i m a t i

o na l g o r i t h m)。

本章的其余部分将介绍几种贪婪算法的应用。在有些应用中,贪婪算法所产生的结果总是最优的解决方案。但对其他一些应用,生成的算法只是一种启发式方法,可能是也可能不是近似算法。

----------------------------------------------

plot(100+t+15*cos(3.05*t),t=0..200,coords=polar,axes=none,scaling=constrained);

2004-5-27 19:39:12

b

等级:职业侠客

文章:470

积分:956

门派:黑客帝国

注册:2003-8-28

第 3 楼

练习

1. 证明找零钱问题(例1 3 - 4)的贪婪算法总能产生具有最少硬币数的零钱。

2. 考虑例1 3 - 4的找零钱问题,假设售货员只有有限的2 5美分, 1 0美分,

5美分和1美分的硬币,给出一种找零钱的贪婪算法。这种方法总能找出具有最少硬币数的零钱吗?证明结论。

3. 扩充例1 3 - 4的算法,假定售货员除硬币外还有50, 20, 10, 5, 和1美元的纸币,顾客买价格为x 美元和y

美分的商品时所付的款为u 美元和v 美分。算法总能找出具有最少纸币与硬币数目的零钱吗?证明结论。

4. 编写一个C + +程序实现例1 3 - 4的找零钱算法。假设售货员具有面值为1 0 0,2 0,1

0,5和1美元的纸币和各种硬币。程序可包括输入模块(即输入所买商品的价格及顾客所付的钱数),输出模块(输出零钱的数目及要找的各种货币的数目)和计算模块(计算怎样给出零钱)。

5. 假设某个国家所使用硬币的币值为1 4 , 2 , 5和1分,则例1 3 -

4的贪婪算法总能产生具有最少硬币数的零钱吗?证明结论。

6. 1) 证明例1 3 - 5的贪婪算法总能找到最优任务分配方案。

2) 实现这种算法,使其复杂性为O (nl o gn)(提示:根据完成时间建立最小堆)。

*7. 考察例1 3 -

5的机器调度问题。假定仅有一台机器可用,那么将选择最大数量的任务在这台机器上执行。例如,所选择的最大任务集合为{a,b,e}。解决这种任务选择问题的贪婪算法可按步骤选择任务,每步选择一个任务,其贪婪准则如下:从剩下的任务中选择具有最小的完成时间且不会与现有任务重叠的任务。

1) 证明上述贪婪算法能够获得最优选择。

2) 实现该算法,其复杂性应为O(nl o gn)。(提示:采用一个完成时间的最小堆)

----------------------------------------------

plot(100+t+15*cos(3.05*t),t=0..200,coords=polar,axes=none,scaling=constrained);

2004-5-27 19:39:26

b

等级:职业侠客

文章:470

积分:956

门派:黑客帝国

注册:2003-8-28

第 4 楼

1.3 应用

1.3.1 货箱装船

这个问题来自例1 -

2。船可以分步装载,每步装一个货箱,且需要考虑装载哪一个货箱。根据这

种思想可利用如下贪婪准则:从剩下的货箱中,选择重量最小的货箱。这种选择次序可以保证所选的货箱总重量最小,从而可以装载更多的货箱。根据这种贪婪策略,首先选择最轻的货箱,然后选次轻的货箱,如此下去直到所有货箱均装上船或船上不能再容纳其他任何一个货箱。

例1-7 假设n =8, [w1 , ... w8 ]=[100,200,50,90,150,50,20,80], c= 4 0 0。利用贪婪算法时,所考察货箱的顺序为7 , 3 , 6 , 8 , 4 , 1 , 5 , 2。货箱7 , 3 , 6 , 8 ,

4 , 1的总重量为3 9 0个单位且已被装载,剩下的装载能力为1 0个单位,小于剩下的任何一个货箱。在这种贪婪解决算法中得到[x1

, ..., x8 ] = [ 1 , 0 , 1 , 1 , 0 , 1 , 1 , 1 ]且åxi = 6。

定理1-1 利用贪婪算法能产生最佳装载。

证明可以采用如下方式来证明贪婪算法的最优性:令x = [x1 , ..., xn ]为用贪婪算法获得的解,令y =[ y1 ,

..., yn ]为任意一个可行解,只需证明n åi= 1xi ≥n åi= 1yi 。不失一般性,可以假设货箱都排好了序:即wi≤wi + 1(1≤i≤n)。然后分几步将y

转化为x,转换过程中每一步都产生一个可行的新y,且n åi = 1yi 大

于等于未转化前的值,最后便可证明n åi = 1xi ≥n

åj = 1yi 。

根据贪婪算法的工作过程,可知在[0, n] 的范围内有一个k,使得xi =1, i ≤k且xi =0, i>k。寻找[ 1

,n]范围内最小的整数j,使得xj≠yj 。若没有这样的j 存在,则n åi= 1xi =n åi = 1yi 。如果有这样的j

存在,则j≤k,否则y 就不是一个可行解,因为xj≠yj ,xj = 1且yj = 0。

令yj = 1,若结果得到的y

不是可行解,则在[ j+ 1 ,n]范围内必有一个l 使得yl = 1。令yl = 0,

由于wj≤wl ,则得到的y

是可行的。而且,得到的新y 至少与原来的y 具有相同数目的1。

经过数次这种转化,可将y 转化为x。由于每次转化产生的新y 至少与前一个y 具有相同数目的1,因此x 至少与初始的y

具有相同的数目1。货箱装载算法的C + +代码实现见程序1 3 - 1。由于贪婪算法按货箱重量递增的顺序装载,程序1 3 -

1首先利用间接寻址排序函数I n d i r e c t S o r t对货箱重量进行排序(见3 .

5节间接寻址的定义),随后货箱便可按重量递增的顺序装载。由于间接寻址排序所需的时间为O (nl o gn)(也可利用9 . 5 .

1节的堆排序及第2章的归并排序),算法其余部分所需时间为O (n),因此程序1 3 - 1的总的复杂性为O (nl o gn)。

程序13-1 货箱装船

template

void ContainerLoading(int x[], T w[], T c, int n)

{// 货箱装船问题的贪婪算法

// x[i] = 1 当且仅当货箱i被装载, 1<=i<=n

// c是船的容量, w 是货箱的重量

// 对重量按间接寻址方式排序

// t 是间接寻址表

int *t = new int [n+1];

I n d i r e c t S o r t ( w, t, n);

// 此时, w[t[i]] <= w[t[i+1]], 1<=i

// 初始化x

for (int i = 1; i <= n; i++)

x[i] = 0;

// 按重量次序选择物品

for (i = 1; i <= n && w[t[i]] <= c; i++) {

x[t[i]] = 1;

c -= w[t[i]];} // 剩余容量

delete [] t;

}

----------------------------------------------

plot(100+t+15*cos(3.05*t),t=0..200,coords=polar,axes=none,scaling=constrained); 2004-5-27 19:39:39

b

等级:职业侠客

文章:470

积分:956

门派:黑客帝国

注册:2003-8-28

第 5 楼

1.3.2 0/1背包问题

在0 / 1背包问题中,需对容量为c 的背包进行装载。从n 个物品中选取装入背包的物品,每件物品i 的重量为wi ,价值为pi

。对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高,即n åi=1pi xi

取得最大值。约束条件为n åi =1wi xi≤c 和xiÎ[ 0 , 1 ] ( 1≤i≤n)。

在这个表达式中,需求出xt 的值。xi = 1表示物品i 装入背包中,xi =0 表示物品i 不装入背包。0 /

1背包问题是一个一般化的货箱装载问题,即每个货箱所获得的价值不同。货箱装载问题转化为背包问题的形式为:船作为背包,货箱作为可装入背包的物品。

例1-8 在杂货店比赛中你获得了第一名,奖品是一车免费杂货。店中有n

种不同的货物。规则规定从每种货物中最多只能拿一件,车子的容量为c,物品i 需占用wi 的空间,价值为pi

。你的目标是使车中装载的物品价值最大。当然,所装货物不能超过车的容量,且同一种物品不得拿走多件。这个问题可仿照0 /

1背包问题进行建模,其中车对应于背包,货物对应于物品。

0 /

1背包问题有好几种贪婪策略,每个贪婪策略都采用多步过程来完成背包的装入。在每一步过程中利用贪婪准则选择一个物品装入背包。一种贪婪准则为:从剩余的物品中,选出可以装入背包的价值最大的物品,利用这种规则,价值最大的物品首先被装入(假设有足够容量),然后是下一个价值最大的物品,如此继续下去。这种策略不能保证得到最优解。例如,考虑n=2,

w=[100,10,10], p =[20,15,15], c = 1 0 5。当利用价值贪婪准则时,获得的解为x= [ 1 , 0

, 0 ],这种方案的总价值为2 0。而最优解为[ 0 , 1 , 1 ],其总价值为3 0。

另一种方案是重量贪婪准则是:从剩下的物品中选择可装入背包的重量最小的物品。虽然这种规则对于前面的例子能产生最优解,但在一般情况下则不一定能得到最优解。考虑n=

2 ,w=[10,20], p=[5,100], c= 2 5。当利用重量贪婪策略时,获得的解为x =[1,0], 比最优解[ 0

, 1 ]要差。

还可以利用另一方案,价值密度pi /wi 贪婪算法,这种选择准则为:从剩余物品中选择可

装入包的pi /wi 值最大的物品,这种策略也不能保证得到最优解。利用此策略试解n= 3 ,w=[20,15,15],

p=[40,25,25], c=30 时的最优解。

我们不必因所考察的几个贪婪算法都不能保证得到最优解而沮丧, 0 / 1背包问题是一个N

P-复杂问题。对于这类问题,也许根本就不可能找到具有多项式时间的算法。虽然按pi /wi

非递(增)减的次序装入物品不能保证得到最优解,但它是一个直觉上近似的解。我们希望它是一个好的启发式算法,且大多数时候能很好地接近最后算法。在6

0 0个随机产生的背包问题中,用这种启发式贪婪算法来解有2 3 9题为最优解。有5 8 3个例子与最优解相差1 0 %,所有6 0

0个答案与最优解之差全在2 5 %以内。该算法能在O (nl o gn)时间内获得如此好的性能。我们也许会问,是否存在一个x

(x<1 0 0 ),使得贪婪启发法的结果与最优值相差在x%以内。答案是否定的。为说明这一点,考虑例子n =2, w = [ 1

,y], p= [ 1 0 , 9y], 和c= y。贪婪算法结果为x=[1,0], 这种方案的值为1 0。对于y≥1 0 /

9,最优解的值为9 y。因此,贪婪算法的值与最优解的差对最优解的比例为( ( 9y - 1 0)/9y* 1 0 0 )

%,对于大的y,这个值趋近于1 0 0 %。但是可以建立贪婪启发式方法来提供解,使解的结果与最优解的值之差在最优值的x%

(x<100) 之内。首先将最多k 件物品放入背包,如果这k 件物品重量大于c,则放弃它。否则,剩余的容量用来考虑将剩余物品按pi

/wi 递减的顺序装入。通过考虑由启发法产生的解法中最多为k 件物品的所有可能的子集来得到最优解。

例13-9 考虑n =4, w=[2,4,6,7], p=[6,10,12,13], c = 11。当k=

0时,背包按物品价值密度非递减顺序装入,首先将物品1放入背包,然后是物品2,背包剩下的容量为5个单元,剩下的物品没有一个合适的,因此解为x

= [ 1 , 1 , 0 , 0 ]。此解获得的价值为1 6。

现在考虑k = 1时的贪婪启发法。最初的子集为{ 1 } , { 2 } , { 3 } , { 4 }。子集{ 1 } , { 2

}产生与k= 0时相同的结果,考虑子集{ 3 },置x3

为1。此时还剩5个单位的容量,按价值密度非递增顺序来考虑如何利用这5个单位的容量。首先考虑物品1,它适合,因此取x1

为1,这时仅剩下3个单位容量了,且剩余物品没有能够加入背包中的物品。通过子集{ 3 }开始求解得结果为x = [ 1 , 0 , 1

, 0 ],获得的价值为1 8。若从子集{ 4 }开始,产生的解为x = [ 1 , 0 , 0 , 1 ],获得的价值为1

9。考虑子集大小为0和1时获得的最优解为[ 1 , 0 , 0 , 1 ]。这个解是通过k= 1的贪婪启发式算法得到的。

若k= 2,除了考虑k< 2的子集,还必需考虑子集{ 1 , 2 } , { 1 , 3 } ,

{ 1 , 4 } , { 2 ,

3 } , { 2 ,

4 }和{ 3 , 4

}。首先从最后一个子集开始,它是不可行的,故将其抛弃,剩下的子集经求解分别得到如下结果:[ 1 , 1 , 0 , 0 ] , [

1 , 0 , 1 , 0 ] , [ 1 , 0 , 0 , 1 ] , [ 0 , 1 , 1 , 0 ]和[ 0 , 1 , 0 , 1 ],这些结果中最后一个价值为

2 3,它的值比k= 0和k= 1时获得的解要高,这个答案即为启发式方法产生的结果。

这种修改后的贪婪启发方法称为k阶优化方法(k - o p t i m a l)。也就是,若从答案中取出k 件物品,并放入另外k

件,获得的结果不会比原来的好,而且用这种方式获得的值在最优值的( 1 0 0 / (k + 1 ) ) %以内。当k=

1时,保证最终结果在最佳值的5 0 %以内;当k= 2时,则在3 3 . 3 3 %以内等等,这种启发式方法的执行时间随k

的增大而增加,需要测试的子集数目为O (nk ),每一个子集所需时间为O (n),因此当k >0时总的时间开销为O (nk+1

)。实际观察到的性能要好得多。

----------------------------------------------

plot(100+t+15*cos(3.05*t),t=0..200,coords=polar,axes=none,scaling=constrained); 2004-5-27 19:39:53

b

等级:职业侠客

文章:470

积分:956

门派:黑客帝国

注册:2003-8-28

第 6 楼

1.3.3 拓扑排序

一个复杂的工程通常可以分解成一组小任务的集合,完成这些小任务意味着整个工程的完成。例如,汽车装配工程可分解为以下任务:将底盘放上装配线,装轴,将座位装在底盘上,上漆,装刹车,装门等等。任务之间具有先后关系,例如在装轴之前必须先

将底板放上装配线。任务的先后顺序可用有向图表示——称为顶点活动(

Activity On Vertex, AOV)网络。有向图的顶点代表任务,有向边(i, j) 表示先后关系:任务j 开始前任务i

必须完成。图1 - 4显示了六个任务的工程,边( 1 , 4)表示任务1在任务4开始前完成,同样边( 4 ,

6)表示任务4在任务6开始前完成,边(1 , 4)与(4 ,

6)合起来可知任务1在任务6开始前完成,即前后关系是传递的。由此可知,边(1 , 4)是多余的,因为边(1 , 3)和(3 ,

4)已暗示了这种关系。

在很多条件下,任务的执行是连续进行的,例如汽车装配问题或平时购买的标有“需要装配”的消费品(自行车、小孩的秋千装置,割草机等等)。我们可根据所建议的顺序来装配。在由任务建立的有向图中,边(

i, j)表示在装配序列中任务i 在任务j 的前面,具有这种性质的序列称为拓扑序列(topological

orders或topological sequences)。根据任务的有向图建立拓扑序列的过程称为拓扑排序(topological

sorting)。图1 - 4的任务有向图有多种拓扑序列,其中的三种为1 2 3 4 5 6,1 3 2 4 5 6和2 1 5 3

4 6,序列1 4 2 3

5 6就不是拓扑序列,因为在这个序列中任务4在3的前面,而任务有向图中的边为( 3 ,

4),这种序列与边( 3 ,

4)及其他边所指示的序列相矛盾。可用贪婪算法来建立拓扑序列。算法按从左到右的步骤构造拓扑序列,每一步在排好的序列中加入一个顶点。利用如下贪婪准则来选择顶点:从剩下的顶点中,选择顶点w,使得w

不存在这样的入边( v,w),其中顶点v 不在已排好的序列结构中出现。注意到如果加入的顶点w违背了这个准则(即有向图中存在边(

v,w)且v 不在已构造的序列中),则无法完成拓扑排序,因为顶点v 必须跟随在顶点w 之后。贪婪算法的伪代码如图1 3 -

5所示。while 循环的每次迭代代表贪婪算法的一个步骤。

现在用贪婪算法来求解图1 -

4的有向图。首先从一个空序列V开始,第一步选择V的第一个顶点。此时,在有向图中有两个候选顶点1和2,若选择顶点2,则序列V =

2,第一步完成。第二步选择V的第二个顶点,根据贪婪准则可知候选顶点为1和5,若选择5,则V = 2

5。下一步,顶点1是唯一的候选,因此V = 2 5 1。第四步,顶点3是唯一的候选,因此把顶点3加入V

得到V = 2 5 1 3。在最后两步分别加入顶点4和6 ,得V = 2 5 1 3 4 6。

1. 贪婪算法的正确性

为保证贪婪算法算的正确性,需要证明: 1) 当算法失败时,有向图没有拓扑序列; 2) 若

算法没有失败,V即是拓扑序列。2) 即是用贪婪准则来选取下一个顶点的直接结果, 1) 的证明见定理1 3 -

2,它证明了若算法失败,则有向图中有环路。若有向图中包含环qj qj + 1.qk qj , 则它没有拓扑序列,因为该序列暗示了qj

一定要在qj 开始前完成。

定理1-2 如果图1 3 - 5算法失败,则有向图含有环路。

证明注意到当失败时| V |

q1)且q2 不在V中,否则, q1 是可加入V的候选顶点。同样,必有边(q3 , q2)使得q3 不在V中,若q3 = q1

则q1 q2 q3 是有向图中的一个环路;若q3 ≠q1,则必存在q4 使(q4 , q3)是有向图的边且q4 不在V中,否则,q3

便是V的一个候选顶点。若q4 为q1 , q2 , q3

中的任何一个,则又可知有向图含有环,因为有向图具有有限个顶点数n,继续利用上述方法,最后总能找到一个环路。

2. 数据结构的选择

为将图1 - 5用C +

+代码来实现,必须考虑序列V的描述方法,以及如何找出可加入V的候选顶点。一种高效的实现方法是将序列V用一维数组v

来描述的,用一个栈来保存可加入V的候选顶点。另有一个一维数组I n D e g r e e,I n D e g r e e[ j

]表示与顶点j相连的节点i 的数目,其中顶点i不是V中的成员,它们之间的有向图的边表示为( i, j)。当I n D e g r e

e[ j ]变为0时表示j 成为一个候选节点。序列V初始时为空。I n D e g r e e[ j ]为顶点j

的入度。每次向V中加入一个顶点时,所有与新加入顶点邻接的顶点j,其I n D e g r e e[ j ]减1。对于有向图1 -

4,开始时I n D e g r e e [ 1 : 6 ] = [ 0 , 0 , 1 , 3 , 1 , 3

]。由于顶点1和2的I n D e g r e

e值为0,因此它们是可加入V的候选顶点,由此,顶点1和2首先入栈。每一步,从栈中取出一个顶点将其加入V,同时减去与其邻接的顶点的I

n D e g r e e值。若在第一步时从栈中取出顶点2并将其加入V,便得到了v [ 0 ] = 2,和I n D e g r e

e [ 1 : 6 ] = [ 0 , 0 , 1 , 2 , 0 , 3 ]。由于I n D e g r e e [ 5 ]刚刚变为0,因此将顶点5入栈。

程序1 3 - 2给出了相应的C + +代码,这个代码被定义为N e t w o r k的一个成员函数。而且,它对于有无加权的有向图均适用。但若用于无向图(不论其有无加权)将会得到错误的结果,因为拓扑排序是针对有向图来定义的。为解决这个问题,利用同样的模板来定义成员函数AdjacencyGraph,

AdjacencyWGraph,L i n k e d G r a p h和L i n k e d W G r a p

h。这些函数可重载N e t w o r k中的函数并可输出错误信息。如果找到拓扑序列,则Topological 函数返回t r u

e;若输入的有向图无拓扑序列则返回f a l s e。当找到拓扑序列时,将其返回到v [ 0 :n- 1 ]中。

3. Network:Topological 的复杂性

第一和第三个f o r循环的时间开销为(n )。若使用(耗费)邻接矩阵,则第二个for 循环所用的时间为(n2

);若使用邻接链表,则所用时间为(n+e)。在两个嵌套的while 循环中,外

层循环需执行n次,每次将顶点w 加入到v

中,并初始化内层while 循环。使用邻接矩阵时,内层w h i l e循环对于每个顶点w

需花费(n)的时间;若利用邻接链表,则这个循环需花费dwout 的时间,因此,内层while 循环的时间开销为(n2

)或(n+e)。所以,若利用邻接矩阵,程序1 3 - 2的时间复杂性为(n2 ),若利用邻接链表则为(n+e)。

程序13-2 拓扑排序

bool Network::Topological(int v[])

{// 计算有向图中顶点的拓扑次序

// 如果找到了一个拓扑次序,则返回t r u e,此时,在v [ 0 : n - 1 ]中记录拓扑次序

// 如果不存在拓扑次序,则返回f a l s e

int n = Ve r t i c e s ( ) ;

// 计算入度

int *InDegree = new int [n+1];

InitializePos(); // 图遍历器数组

for (int i = 1; i <= n; i++) // 初始化

InDegree[i] = 0;

for (i = 1; i <= n; i++) {// 从i 出发的边

int u = Begin(i);

while (u) {

I n D e g r e e [ u ] + + ;

u = NextVe r t e x ( i ) ; }

}

// 把入度为0的顶点压入堆栈

LinkedStack S;

for (i = 1; i <= n; i++)

if (!InDegree[i]) S.Add(i);

// 产生拓扑次序

i = 0; // 数组v 的游标

while (!S.IsEmpty()) {// 从堆栈中选择

int w; // 下一个顶点

S . D e l e t e ( w ) ;

v[i++] = w;

int u = Begin(w);

while (u) {// 修改入度

I n D e g r e e [ u ] - - ;

if (!InDegree[u]) S.Add(u);

u = NextVe r t e x ( w ) ; }

}

D e a c t i v a t e P o s ( ) ;

delete [] InDegree;

return (i == n);

}

----------------------------------------------

plot(100+t+15*cos(3.05*t),t=0..200,coords=polar,axes=none,scaling=constrained); 2004-5-27 19:40:10

b

等级:职业侠客

文章:470

积分:956

门派:黑客帝国

注册:2003-8-28

第 7 楼

1.3.4 二分覆盖

二分图是一个无向图,它的n

个顶点可二分为集合A和集合B,且同一集合中的任意两个顶点在图中无边相连(即任何一条边都是一个顶点在集合A中,另一个在集合B中)。当且仅当B中的每个顶点至少与A中一个顶点相连时,A的一个子集A'

覆盖集合B(或简单地说,A' 是一个覆盖)。覆盖A' 的大小即为A' 中的顶点数目。当且仅当A' 是覆盖B的子集中最小的时,A'

为最小覆盖。

例1-10 考察如图1 - 6所示的具有1 7个顶点的二分图,A={1, 2, 3, 16, 17}和B={4, 5, 6, 7,

8, 9,10, 11, 12, 13, 14, 15},子集A' = { 1 , 1 6 , 1 7

}是B的最小覆盖。在二分图中寻找最小覆盖的问题为二分覆盖( b i p a r t i t e - c o v e r)问题。在例1

2 - 3中说明了最小覆盖是很有用的,因为它能解决“在会议中使用最少的翻译人员进行翻译”这一类的问题。

二分覆盖问题类似于集合覆盖( s e t - c o v e r)问题。在集合覆盖问题中给出了k 个集合S= {S1 , S2

,., Sk },每个集合Si 中的元素均是全集U中的成员。当且仅当Èi S'Si =U时,S的子集S' 覆盖U,S

'中的集合数目即为覆盖的大小。当且仅当没有能覆盖U的更小的集合时,称S'

为最小覆盖。可以将集合覆盖问题转化为二分覆盖问题(反之亦然),即用A 的顶点来表示S1 , ., Sk

,B中的顶点代表U中的元素。当且仅当S的相应集合中包含U中的对应元素时,在A与B的顶点之间存在一条边。

例1 - 11 令S= {S1,. . .,S5 }, U= { 4,5,. . .,15}, S1 = { 4,6,7,8,9,1

3 },S2 = { 4,5,6,8 },S3 = { 8,1 0,1 2,1 4,1 5 },S

4 = { 5,6,8,1 2,1

4,1 5 },S5 = { 4,9,1 0,11 }。S ' = {S1,S4,S5 }是一个大小为3的覆盖,没有更小的覆盖,

S' 即为最小覆盖。这个集合覆盖问题可映射为图1-6的二分图,即用顶点1,2,3,1 6和1 7分别表示集合S1,S2,S3,S4

和S5,顶点j 表示集合中的元素j,4≤j≤1 5。

集合覆盖问题为N P-复杂问题。由于集合覆盖与二分覆盖是同一类问题,二分覆盖问题也是N

P-复杂问题。因此可能无法找到一个快速的算法来解决它,但是可以利用贪婪算法寻找一种快速启发式方法。一种可能是分步建立覆盖A'

,每一步选择A中的一个顶点加入覆盖。顶点的选择利用贪婪准则:从A中选取能覆盖B中还未被覆盖的元素数目最多的顶点。

例1-12 考察图1 - 6所示的二分图,初始化A' = 且B中没有顶点被覆盖,顶点1和1

6均能覆盖B中的六个顶点,顶点3覆盖五个,顶点2和1 7分别覆盖四个。因此,在第一步往A' 中加入顶点1或1 6,若加入顶点1

6,则它覆盖的顶点为{ 5 , 6 , 8 , 1 2 , 1 4 , 1 5 },未覆盖的顶点为{ 4 , 7 , 9 , 1 0

, 11 , 1 3 }。顶点1能覆盖其中四个顶点( { 4 , 7 , 9 , 1 3 }),顶点2 覆盖一个( { 4 }

),顶点3覆盖一个({ 1 0 }),顶点1 6覆盖零个,顶点1 7覆盖四个{ 4 , 9 , 1 0 , 11

}。下一步可选择1或1 7加入A' 。若选择顶点1,则顶点{ 1 0 , 11} 仍然未被覆盖,此时顶点1,2,1

6不覆盖其中任意一个,顶点3覆盖一个,顶点1 7覆盖两个,因此选择顶点1 7,至此所有顶点已被覆盖,得A' = { 1 6 , 1

, 1 7 }。

图1 - 7给出了贪婪覆盖启发式方法的伪代码,可以证明: 1) 当且仅当初始的二分图没有覆盖时,算法找不到覆盖;2)

启发式方法可能找不到二分图的最小覆盖。

1. 数据结构的选取及复杂性分析

为实现图13 - 7的算法,需要选择A' 的描述方法及考虑如何记录A中节点所能覆盖的B中未覆盖节点的数目。由于对集合A'

仅使用加法运算,则可用一维整型数组C来描述A ',用m 来记录A' 中元素个数。将A' 中的成员记录在C[ 0 :m-1]

中。对于A中顶点i,令N e wi 为i 所能覆盖的B中未覆盖的顶点数目。逐步选择N e wi

值最大的顶点。由于一些原来未被覆盖的顶点现在被覆盖了,因此还要修改各N e wi

值。在这种更新中,检查B中最近一次被V覆盖的顶点,令j 为这样的一个顶点,则A中所有覆盖j 的顶点的N e wi 值均减1。

例1-13 考察图1 - 6,初始时(N e w1 , N e w2 , N e w3 , N e w16 , N e w17 )

= ( 6 , 4 , 5 , 6 , 4 )。假设在例1 - 1 2中,第一步选择顶点1 6,为更新N e wi

的值检查B中所有最近被覆盖的顶点,这些顶点为5 , 6 , 8 , 1 2 , 1 4和1 5。当检查顶点5时,将顶点2和1 6的N

e wi 值分别减1,因为顶点5不再是被顶点2和1 6覆盖的未覆盖节点;当检查顶点6时,顶点1 , 2 ,和1

6的相应值分别减1;同样,检查顶点8时,1,2,3和1 6的值分别减1;当检查完所有最近被覆盖的顶点,得到的N e wi

值为(4,1,0,4)。下一步选择顶点1,最新被覆盖的顶点为4,7,9和1 3;检查顶点4时,N e w1 , N e w2, 和N

e w1 7 的值减1;检查顶点7时,N e w1 的值减1,因为顶点1是覆盖7的唯一顶点。

为了实现顶点选取的过程,需要知道N e wi 的值及已被覆盖的顶点。可利用一个二维数组来达到这个目的,N e

w是一个整型数组,New[i] 即等于N e wi,且c o v为一个布尔数组。若顶点i未被覆盖则c o v [ i ]等于f a

l s e,否则c o v [ i ]为t r u e。现将图1 - 7的伪代码进行细化得到图1 - 8。

m=0; //当前覆盖的大小

对于A中的所有i,New[i]=Degree[i]

对于B中的所有i,C o v [ i ] = f a l s e

while (对于A中的某些i,New[i]>0) {

设v是具有最大的N e w [ i ]的顶点;

C [ m + + ] = v ;

for ( 所有邻接于v的顶点j) {

if (!Cov[j]) {

Cov[j]= true;

对于所有邻接于j的顶点,使其N e w [ k ]减1

} } }

if (有些顶点未被覆盖) 失败

else 找到一个覆盖

图1-8 图1-7的细化

更新N e w的时间为O (e),其中e 为二分图中边的数目。若使用邻接矩阵,则需花(n2 )

的时间来寻找图中的边,若用邻接链表,则需(n+e) 的时间。实际更新时间根据描述方法的不同为O (n2 ) 或O

(n+e)。逐步选择顶点所需时间为(S i z e O f A),其中S i z e O f A=| A |。因为A的所有顶点都有可能被选择,因此所需步骤数为O ( S i z e O f A ),覆盖算法总的复杂性为O ( S i z

e O

f A 2+n2) = O ( n2)或O (S i z e Of A2+n + e)。

2. 降低复杂性

通过使用有序数组N e wi、最大堆或最大选择树(max selection tree)可将每步选取顶点v的复杂性降为( 1

)。但利用有序数组,在每步的最后需对N e wi 值进行重新排序。若使用箱子排序,则这种排序所需时间为(S i z e O f B

) ( S i z e O fB =|B| ) (见3 . 8 . 1节箱子排序)。由于一般S i z e O f B比S i z

e O

f A大得多,因此有序数组并不总能提高性能。

如果利用最大堆,则每一步都需要重建堆来记录N e w值的变化,可以在每次N e w值减1时进行重建。这种减法操作可引起被减的N e

w值最多在堆中向下移一层,因此这种重建对于每次N e w值减1需( 1 )的时间,总共的减操作数目为O

(e)。因此在算法的所有步骤中,维持最大堆仅需O (e)的时间,因而利用最大堆时覆盖算法的总复杂性为O (n2 )或O (n+e)。

若利用最大选择树,每次更新N e w值时需要重建选择树,所需时间为(log S i z e O f

A)。重建的最好时机是在每步结束时,而不是在每次N e w值减1时,需要重建的次数为O (e),因此总的重建时间为O (e log

S i z e OfA),这个时间比最大堆的重建时间长一些。然而,通过维持具有相同N e

w值的顶点箱子,也可获得和利用最大堆时相同的时间限制。由于N e w的取值范围为0到S i z e O f B,需要S i z e

O f B+ 1个箱子,箱子i 是一个双向链表,链接所有N e w值为i 的顶点。在某一步结束时,假如N e w [ 6 ]从1

2变到4,则需要将它从第1 2个箱子移到第4个箱子。利用模拟指针及一个节点数组n o d e(其中n o d e [ i

]代表顶点i,n o d e [ i ] . l e f t和n o d e [ i ] . r i g h

t为双向链表指针),可将顶点6从第1 2个箱子移到第4个箱子,从第1 2个箱子中删除n o d e [ 0

]并将其插入第4个箱子。利用这种箱子模式,可得覆盖启发式算法的复杂性为O (n2

)或O(n+e)。(取决于利用邻接矩阵还是线性表来描述图)。

3. 双向链接箱子的实现

为了实现上述双向链接箱子,图1 - 9定义了类U n d i r e c t e d的私有成员。N o d e Ty p

e是一个具有私有整型成员l e f t和r i g h t的类,它的数据类型是双

向链表节点,程序1 3 - 3给出了U n d i

r e c t e d的私有成员的代码。

void CreateBins (int b, int n)

创建b个空箱子和n个节点

void DestroyBins() { delete [] node;

delete [] bin;}

void InsertBins(int b, int v)

在箱子b中添加顶点v

void MoveBins(int bMax, int ToBin, int v)

从当前箱子中移动顶点v到箱子To B i n

int *bin;

b i n [ i ]指向代表该箱子的双向链表的首节点

N o d e Type *node;

n o d e [ i ]代表存储顶点i的节点

图1-9 实现双向链接箱子所需的U n d i r e c t e d私有成员

----------------------------------------------

plot(100+t+15*cos(3.05*t),t=0..200,coords=polar,axes=none,scaling=constrained); 2004-5-27 19:40:45

b

等级:职业侠客

文章:470

积分:956

门派:黑客帝国

注册:2003-8-28

第 8 楼

程序13-3 箱子函数的定义

void Undirected::CreateBins(int b, int n)

{// 创建b个空箱子和n个节点

node = new NodeType [n+1];

bin = new int [b+1];

// 将箱子置空

for (int i = 1; i <= b; i++)

bin[i] = 0;

}

void Undirected::InsertBins(int b, int v)

{// 若b不为0,则将v 插入箱子b

if (!b) return; // b为0,不插入

node[v].left = b; // 添加在左端

if (bin[b]) node[bin[b]].left = v;

node[v].right = bin[b];

bin[b] = v;

}

void Undirected::MoveBins(int bMax, int ToBin, int v)

{// 将顶点v 从其当前所在箱子移动到To B i n .

// v的左、右节点

int l = node[v].left;

int r = node[v].right;

// 从当前箱子中删除

if (r) node[r].left = node[v].left;

if (l > bMax || bin[l] != v) // 不是最左节点

node[l].right = r;

else bin[l] = r; // 箱子l的最左边

// 添加到箱子To B i n

I n s e r t B i n s ( ToBin, v);

}

函数C r e a t e B i n s动态分配两个数组: n o d e和b i n,n o d e [i ]表示顶点i,

bin[i ]指向其N e w值为i的双向链表的顶点, f o r循环将所有双向链表置为空。如果b≠0,函数InsertBins

将顶点v 插入箱子b 中。因为b 是顶点v 的New 值,b = 0意味着顶点v

不能覆盖B中当前还未被覆盖的任何顶点,所以,在建立覆盖时这个箱子没有用处,故可以将其舍去。当b≠0时,顶点n 加入New 值为b

的双向链表箱子的最前面,这种加入方式需要将node[v] 加入bin[b]

中第一个节点的左边。由于表的最左节点应指向它所属的箱子,因此将它的node[v].left

置为b。若箱子不空,则当前第一个节点的left 指针被置为指向新节点。node[v] 的右指针被置为b i n [ b

],其值可能为0或指向上一个首节点的指针。最后, b i n [ b ]被更新为指向表中新的第一个节点。MoveBins 将顶点v

从它在双向链表中的当前位置移到New 值为ToBin 的位置上。其中存在bMa x,使得对所有的箱子b i n[ j

]都有:如j>bMa x,则b i n [ j ]为空。代码首先确定n o d e [ v

]在当前双向链表中的左右节点,接着从双链表中取出n o d e [ v ],并利用I n s e r t B i n

s函数将其重新插入到b i n [ To B i n ]中。

4. Undirected::BipartiteCover的实现

函数的输入参数L用于分配图中的顶点(分配到集合A或B)。L [i ] = 1表示顶点i在集合A中,L[ i ] =

建立数学模型的方法、步骤、特点及分类

建立数学模型的方法、步骤、特点及分类 [学习目标] 1.能表述建立数学模型的方法、步骤; 2.能表述建立数学模型的逼真性、可行性、渐进性、强健性、可转移性、非 预制性、条理性、技艺性和局限性等特点;; 3.能表述数学建模的分类; 4.会采用灵活的表述方法建立数学模型; 5.培养建模的想象力和洞察力。 一、建立数学模型的方法和步骤 —般说来建立数学模型的方法大体上可分为两大类、一类是机理分析方法,一类是测试分析方法.机理分析是根据对现实对象特性的认识、分析其因果关系,找出反映内部机理的规律,建立的模型常有明确的物理或现实意义.测试分折将研究对象视为一个“黑箱”系统,内部机理无法直接寻求,可以测量系统的输人输出数据、并以此为基础运用统计分析方法,按照事先确定的准则在某一类模型中选出一个与数据拟合得最好的模型。这种方法称为系统辨识(System Identification).将这两种方法结合起来也是常用的建模方法。即用机理分析建立模型的结构,用系统辨识确定模型的参数. 可以看出,用上面的哪一类方法建模主要是根据我们对研究对象的了解程度和建模目的决定的.如果掌握了机理方面的一定知识,模型也要求具有反映内部特性的物理意义。那么应该以机理分析方法为主.当然,若需要模型参数的具体数值,还可以用系统辨识或其他统计方法得到.如果对象的内部机理基本上没掌握,模型也不用于分析内部特性,譬如仅用来做输出预报,则可以系统辩识方法为主.系统辨识是一门专门学科,需要一定的控制理论和随机过程方面的知识.以下所谓建模方法只指机理分析。 建模要经过哪些步骤并没有一定的模式,通常与实际问题的性质、建模的目的等有关,从 §16.2节的几个例子也可以看出这点.下面给出建模的—般步骤,如图16-5所示. 图16-5 建模步骤示意图 模型准备首先要了解问题的实际背景,明确建模的目的搜集建模必需的各种信息如现象、数据等,尽量弄清对象的特征,由此初步确定用哪一类模型,总之是做好建模的准备工作.情况明才能方法对,这一步一定不能忽视,碰到问题要虚心向从事实际工作的同志请教,尽量掌握第一手资料. 模型假设根据对象的特征和建模的目的,对问题进行必要的、合理的简化,用精确的语言做出假设,可以说是建模的关键一步.一般地说,一个实际问题不经过简化假设就很难翻译成数学问题,即使可能,也很难求解.不同的简化假设会得到不同的模型.假设作得不合理或过份简单,会导致模型失败或部分失败,于是应该修改和补充假设;假设作得过分详细,试图把复杂对象的各方面因素都考虑进去,可能使你很难甚至无法继续下一步的工作.通常,作假设的依据,一是出于对问题内在规律的认识,二是来自对数据或现象的分析,也可以是二者的综合.作假设时既要运用与问题相关的物理、化学、生物、经济等方面的知识,又要充分发挥想象力、洞察力和判断力,善于辨别问题的主次,果断地抓住主要因素,舍弃次要因素,尽量将问题线性化、均匀化.经验在这里也常起重要作用.写出假设时,语言要精确,就象做习题时写出已知条件那样.

数学建模知识及常用方法

数学建模知识——之新手上路 一、数学模型的定义现在数学模型还没有一个统一的准确的定义,因为站在不同的角度可以有不同的定义。不过我们可以给出如下定义:“数学模型是关于部分现实世界和为一种特殊目的而作的一个抽象的、简化的结构。”具体来说,数学模型就是为了某种目的,用字母、数学及其它数学符号建立起来的等式或不等式以及图表、图像、框图等描述客观事物的特征及其内在联系的数学结构表达式。一般来说数学建模过程可用如下框图来表明:数学是在实际应用的需求中产生的,要解决实际问题就必需建立数学模型,从此意义上讲数学建模和数学一样有古老历史。例如,欧几里德几何就是一个古老的数学模型,牛顿万有引力定律也是数学建模的一个光辉典范。今天,数学以空前的广度和深度向其它科学技术领域渗透,过去很少应用数学的领域现在迅速走向定量化,数量化,需建立大量的数学模型。特别是新技术、新工艺蓬勃兴起,计算机的普及和广泛应用,数学在许多高新技术上起着十分关键的作用。因此数学建模被时代赋予更为重要的意义。二、建立数学模型的方法和步骤 1. 模型准备要了解问题的实际背景,明确建模目的,搜集必需的各种信息,尽量弄清对象的特征。 2. 模型假设根据对象的特征和建模目的,对问题进行必要的、合理的简化,用精确的语言作出假设,是建模至关重要的一步。如果对问题的所有因素一概考虑,无疑是一种有勇气但方法欠佳的行为,所以高超的建模者能充分发挥想象力、洞察力和判断力,善于辨别主次,而且为了使处理方法简单,应尽量使问题线性化、均匀化。 3. 模型构成根据所作的假设分析对象的因果关系,利用对象的内在规律和适当的数学工具,构造各个量间的等式关系或其它数学结构。这时,我们便会进入一个广阔的应用数学天地,这里在高数、概率老人的膝下,有许多可爱的孩子们,他们是图论、排队论、线性规划、对策论等许多许多,真是泱泱大国,别有洞天。不过我们应当牢记,建立数学模型是为了让更多的人明了并能加以应用,因此工具愈简单愈有价值。 4. 模型求解可以采用解方程、画图形、证明定理、逻辑运算、数值运算等各种传统的和近代的数学方法,特别是计算机技术。一道实际问题的解决往往需要纷繁的计算,许多时候还得将系统运行情况用计算机模拟出来,因此编程和熟悉数学软件包能力便举足轻重。 5. 模型分析 对模型解答进行数学上的分析。“横看成岭侧成峰,远近高低各不同”,能否对模型结果作出细致精当的分析,决定了你的模型能否达到更高的档次。还要记住,不论那种情况都需进行误差分析,数据稳定性分析。例题:一个笼子里装有鸡和兔若干只,已知它们共有 8 个头和 22 只脚,问该笼子中有多少只鸡和多少只兔?解:设笼中有鸡 x 只,有兔 y 只,由已知条件有 x+y=8 2x+4y=22 求解如上二元方程后,得解 x=5,y=3,即该笼子中有鸡 5 只,有兔 3 只。将此结果代入原题进行验证可知所求结果正确。根据例题可以得出如下的数学建模步骤: 1)根据问题的背景和建模的目的做出假设(本题隐含假设鸡兔是正常的,畸形的鸡兔除外) 2)用字母表示要求的未知量 3)根据已知的常识列出数学式子或图形(本题中常识为鸡兔都有一个头且鸡有 2 只脚,兔有 4 只脚) 4)求出数学式子的解答 5)验证所得结果的正确性这就是数学建模的一般步骤三、数模竞赛出题的指导思想传统的数学竞赛一般偏重理论知识,它要考查的内容单一,数据简单明确,不允许用计算器完成。对此而言,数模竞赛题是一个“课题”,大部分都源于生产实际或者科学研究的过程中,它是一个综合性的问题,数据庞大,需要用计算机来完成。其答案往往不是唯一的(数学模型是实际的模拟,是实际问题的近似表达,它的完成是在某种合理的假设下,因此其只能是较优的,不唯一的),呈报的成果是一篇论文。由此可见“数模竞赛”偏重于应用,它是以数学知识为引导计算机运用能力及文章的写作能力为辅的综合能力的竞赛。四、竞赛中的常见题型赛题题型结构形式有三个基本组成部分: 1. 实际问题背景涉及面宽——有社会,经济,管理,生活,环境,自然现象,工程技术,现代科学中出现的新问题等。一般都有一个

贪心算法经典例题

贪心算法经典例题 发布日期:2009-1-8 浏览次数:1180 本资料需要注册并登录后才能下载! ·用户名密码验证码找回密码·您还未注册?请注册 您的账户余额为元,余额已不足,请充值。 您的账户余额为元。此购买将从您的账户中扣除费用0.0元。 内容介绍>> 贪心算法经典例题 在求最优解问题的过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解,这种求解方法就是贪心算法。 从贪心算法的定义可以看出,贪心法并不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。 我们看看下面的例子 例1 均分纸牌(NOIP2002tg) [问题描述] 有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若干张纸牌,然后移动。移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。例如 N=4,4 堆纸牌数分别为: ①9 ②8 ③17 ④ 6 移动3次可达到目的: 从③取 4 张牌放到④(9 8 13 10) -> 从③取 3 张牌放到②(9 11 10 10)-> 从②取 1 张牌放到①(10 10 10 10)。 [输入]:键盘输入文件名。 文件格式:N(N 堆纸牌,1 <= N <= 100) A1 A2 … An (N 堆纸牌,每堆纸牌初始数,l<= Ai <=10000) [输出]:输出至屏幕。格式为:所有堆均达到相等时的最少移动次数。 [输入输出样例] a.in: 4 9 8 17 6 屏慕显示:3 算法分析:设a[i]为第i堆纸牌的张数(0<=i<=n),v为均分后每堆纸牌的张数,s为最小移到次数。 我们用贪心法,按照从左到右的顺序移动纸牌。如第i堆(0

【精选】贪心算法的应用

贪心算法的应用 课程名称:算法设计与分析 院系:计算机科学与信息工程学院 学生姓名:**** 学号:********** 专业班级:********************************** 指导教师:****** 201312-27

贪心算法的应用 摘要:顾名思义,贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。当然,希望贪心算法得到的最终结果也是整体最优的。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。如单源最短路经问题,最小生成树问题等。在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。贪心算法求问题一般具有两个重要性质:贪心选择性质和最优子结构性质。所谓贪心选择性是指所求问题的整体最优解可以通过一系列局部最优解的选择,即贪心选择达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法主要区别。当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。 背包问题是一个经典的问题,我们可以采用多种算法去求解0/1背包问题,比如动态规划法、分支限界法、贪心算法、回溯法。在这里我们采用贪心法解决这个问题。 关键词:贪心法背包问题最优化

目录 第1章绪论 (3) 1.1 贪心算法的背景知识 (3) 1.2 贪心算法的前景意义 (3) 第2章贪心算法的理论知识 (4) 2.1 问题的模式 (4) 2.2 贪心算法的一般性描述 (4) 第3章背包问题 (5) 3.1 问题描述 (5) 3.2 问题分析 (5) 3.3算法设计 (5) 3.4 测试结果与分析 (10) 第4章结论 (12) 参考文献 (13) 附件 (13)

数学建模常用方法

数学建模常用方法 建模常用算法,仅供参考: 1、蒙特卡罗算法(该算法又称随机性模拟算法,是通过计算机仿真来解决问题的算法,同时可以通过模拟可以来检验自己模型的正确性,是比赛时必 用的方法) 2、数据拟合、参数估计、插值等数据处理算法(比赛中通常会遇到大量的数据需要处理,而处理数据的关键就在于这些算法,通常使用M a t l a b作为工具) 3、线性规划、整数规划、多元规划、二次规划等规划类问题(建模竞赛大多数问题属于最优化问题,很多时候这些问题可以用数学规划算法来描述,通 常使用L i n d o、L i n g o软件实现) 4、图论算法(这类算法可以分为很多种,包括最短路、网络流、二分图等算法,涉及到图论的问题可以用这些方法解决,需要认真准备) 5、动态规划、回溯搜索、分治算法、分支定界等计算机算法(这些算法是算法设计中比较常用的方法,很多场合可以用到竞赛中) 6、最优化理论的三大非经典算法:模拟退火法、神经网络、遗传算法(这些问题是用来解决一些较困难的最优化问题的算法,对于有些问题非常有帮助,但是算法的实现比较困难,需慎重使用) 7、网格算法和穷举法(网格算法和穷举法都是暴力搜索最优点的算法,在很多竞赛题中有应用,当重点讨论模型本身而轻视算法的时候,可以使用这种 暴力方案,最好使用一些高级语言作为编程工具) 8、一些连续离散化方法(很多问题都是实际来的,数据可以是连续的,而计 算机只认的是离散的数据,因此将其离散化后进行差分代替微分、求和代替积分等思想是非常重要的) 9、数值分析算法(如果在比赛中采用高级语言进行编程的话,那一些数值分析中常用的算法比如方程组求解、矩阵运算、函数积分等算法就需要额外编写库函数进行调用) 10、图象处理算法(赛题中有一类问题与图形有关,即使与图形无关,论文 中也应该要不乏图片的,这些图形如何展示以及如何处理就是需要解决的问题,通常使用M a t l a b进行处理) 一、在数学建模中常用的方法: 1.类比法 2.二分法 3.量纲分析法 4.差分法 5.变分法 6.图论法 7.层次分析法 8.数据拟合法 9.回归分析法 10.数学规划(线性规划、非线性规划、整数规划、动态规划、目标规划) 11.机理分析 12.排队方法

数学建模常用的十种解题方法

数学建模常用的十种解题方法 摘要 当需要从定量的角度分析和研究一个实际问题时,人们就要在深入调查研究、了解对象信息、作出简化假设、分析内在规律等工作的基础上,用数学的符号和语言,把它表述为数学式子,也就是数学模型,然后用通过计算得到的模型结果来解释实际问题,并接受实际的检验。这个建立数学模型的全过程就称为数学建模。数学建模的十种常用方法有蒙特卡罗算法;数据拟合、参数估计、插值等数据处理算法;解决线性规划、整数规划、多元规划、二次规划等规划类问题的数学规划算法;图论算法;动态规划、回溯搜索、分治算法、分支定界等计算机算法;最优化理论的三大非经典算法:模拟退火法、神经网络、遗传算法;网格算法和穷举法;一些连续离散化方法;数值分析算法;图象处理算法。 关键词:数学建模;蒙特卡罗算法;数据处理算法;数学规划算法;图论算法 一、蒙特卡罗算法 蒙特卡罗算法又称随机性模拟算法,是通过计算机仿真来解决问题的算法,同时可以通过模拟可以来检验自己模型的正确性,是比赛时必用的方法。在工程、通讯、金融等技术问题中, 实验数据很难获取, 或实验数据的获取需耗费很多的人力、物力, 对此, 用计算机随机模拟就是最简单、经济、实用的方法; 此外, 对一些复杂的计算问题, 如非线性议程组求解、最优化、积分微分方程及一些偏微分方程的解⑿, 蒙特卡罗方法也是非常有效的。 一般情况下, 蒙特卜罗算法在二重积分中用均匀随机数计算积分比较简单, 但精度不太理想。通过方差分析, 论证了利用有利随机数, 可以使积分计算的精度达到最优。本文给出算例, 并用MA TA LA B 实现。 1蒙特卡罗计算重积分的最简算法-------均匀随机数法 二重积分的蒙特卡罗方法(均匀随机数) 实际计算中常常要遇到如()dxdy y x f D ??,的二重积分, 也常常发现许多时候被积函数的原函数很难求出, 或者原函数根本就不是初等函数, 对于这样的重积分, 可以设计一种蒙特卡罗的方法计算。 定理 1 )1( 设式()y x f ,区域 D 上的有界函数, 用均匀随机数计算()??D dxdy y x f ,的方法: (l) 取一个包含D 的矩形区域Ω,a ≦x ≦b, c ≦y ≦d , 其面积A =(b 一a) (d 一c) ; ()j i y x ,,i=1,…,n 在Ω上的均匀分布随机数列,不妨设()j i y x ,, j=1,…k 为落在D 中的k 个随机数, 则n 充分大时, 有

贪心算法详解分析

贪心算法详解 贪心算法思想: 顾名思义,贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。当然,希望贪心算法得到的最终结果也是整体最优的。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。如单源最短路经问题,最小生成树问题等。在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。 贪心算法的基本要素: 1.贪心选择性质。所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。 动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。 对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。 2. 当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的 最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。 贪心算法的基本思路: 从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到算法中的某一步不能再继续前进时,算法停止。 该算法存在问题: 1. 不能保证求得的最后解是最佳的; 2. 不能用来求最大或最小解问题; 3. 只能求满足某些约束条件的可行解的范围。 实现该算法的过程: 从问题的某一初始解出发; while 能朝给定总目标前进一步do 求出可行解的一个解元素; 由所有解元素组合成问题的一个可行解; 用背包问题来介绍贪心算法: 背包问题:有一个背包,背包容量是M=150。有7个物品,物品可以分割成任意大小。要 求尽可能让装入背包中的物品总价值最大,但不能超过总容量。

数学建模方法模型

数学建模方法模型 一、统计学方法 1 多元回归 1、方法概述: 在研究变量之间的相互影响关系模型时候用到。具体地说:其可以定量地描述某一现象和某些因素之间的函数关系,将各变量的已知值带入回归方程可以求出因变量的估计值,从而可以进行预测等相关研究。 2、分类 分为两类:多元线性回归和非线性线性回归;其中非线性回归可以通过一定的变化转化为线性回归,比如:y=lnx 可以转化为 y=u u=lnx 来解决;所以这里主要说明多元线性回归应该注意的问题。 3、注意事项 在做回归的时候,一定要注意两件事: (1) 回归方程的显著性检验(可以通过 sas 和 spss 来解决) (2) 回归系数的显著性检验(可以通过 sas 和 spss 来解决) 检验是很多学生在建模中不注意的地方,好的检验结果可以体现出你模型的优劣,是完整论文的体现,所以这点大家一定要注意。 4、使用步骤: (1)根据已知条件的数据,通过预处理得出图像的大致趋势或者数据之间的大致关系; (2)选取适当的回归方程; (3)拟合回归参数; (4)回归方程显著性检验及回归系数显著性检验 (5)进行后继研究(如:预测等)

2 聚类分析 1、方法概述 该方法说的通俗一点就是,将 n个样本,通过适当的方法(选取方法很多,大家可以自行查找,可以在数据挖掘类的书籍中查找到,这里不再阐述)选取 m 聚类中心,通过研究各样本和各个聚类中心的距离 Xij,选择适当的聚类标准,通常利用最小距离法(一个样本归于一个类也就意味着,该样本距离该类对应的中心距离最近)来聚类,从而可以得到聚类结果,如果利用sas 软件或者 spss 软件来做聚类分析,就可以得到相应的动态聚类图。这种模型的的特点是直观,容易理解。 2、分类 聚类有两种类型: (1) Q型聚类:即对样本聚类; (2) R型聚类:即对变量聚类; 通常聚类中衡量标准的选取有两种: (1) 相似系数法 (2) 距离法 聚类方法: (1) 最短距离法 (2) 最长距离法 (3) 中间距离法 (4) 重心法 (5) 类平均法 (6) 可变类平均法 (7) 可变法

数学建模中常见的十大模型

数学建模常用的十大算法==转 (2011-07-24 16:13:14) 转载▼ 1. 蒙特卡罗算法。该算法又称随机性模拟算法,是通过计算机仿真来解决问题的算法,同时可以通过模拟来检验自己模型的正确性,几乎是比赛时必用的方法。 2. 数据拟合、参数估计、插值等数据处理算法。比赛中通常会遇到大量的数据需要处理,而处理数据的关键就在于这些算法,通常使用MA TLAB 作为工具。 3. 线性规划、整数规划、多元规划、二次规划等规划类算法。建模竞赛大多数问题属于最优化问题,很多时候这些问题可以用数学规划算法来描述,通常使用Lindo、Lingo 软件求解。 4. 图论算法。这类算法可以分为很多种,包括最短路、网络流、二分图等算法,涉及到图论的问题可以用这些方法解决,需要认真准备。 5. 动态规划、回溯搜索、分治算法、分支定界等计算机算法。这些算法是算法设计中比较常用的方法,竞赛中很多场合会用到。 6. 最优化理论的三大非经典算法:模拟退火算法、神经网络算法、遗传算法。这些问题是用来解决一些较困难的最优化问题的,对于有些问题非常有帮助,但是算法的实现比较困难,需慎重使用。 7. 网格算法和穷举法。两者都是暴力搜索最优点的算法,在很多竞赛题中有应用,当重点讨论模型本身而轻视算法的时候,可以使用这种暴力方案,最好使用一些高级语言作为编程工具。 8. 一些连续数据离散化方法。很多问题都是实际来的,数据可以是连续的,而计算机只能处理离散的数据,因此将其离散化后进行差分代替微分、求和代替积分等思想是非常重要的。 9. 数值分析算法。如果在比赛中采用高级语言进行编程的话,那些数值分析中常用的算法比如方程组求解、矩阵运算、函数积分等算法就需要额外编写库函数进行调用。 10. 图象处理算法。赛题中有一类问题与图形有关,即使问题与图形无关,论文中也会需要图片来说明问题,这些图形如何展示以及如何处理就是需要解决的问题,通常使用MA TLAB 进行处理。 以下将结合历年的竞赛题,对这十类算法进行详细地说明。 以下将结合历年的竞赛题,对这十类算法进行详细地说明。 2 十类算法的详细说明 2.1 蒙特卡罗算法 大多数建模赛题中都离不开计算机仿真,随机性模拟是非常常见的算法之一。 举个例子就是97 年的A 题,每个零件都有自己的标定值,也都有自己的容差等级,而求解最优的组合方案将要面对着的是一个极其复杂的公式和108 种容差选取方案,根本不可能去求解析解,那如何去找到最优的方案呢?随机性模拟搜索最优方案就是其中的一种方法,在每个零件可行的区间中按照正态分布随机的选取一个标定值和选取一个容差值作为一种方案,然后通过蒙特卡罗算法仿真出大量的方案,从中选取一个最佳的。另一个例子就是去年的彩票第二问,要求设计一种更好的方案,首先方案的优劣取决于很多复杂的因素,同样不可能刻画出一个模型进行求解,只能靠随机仿真模拟。 2.2 数据拟合、参数估计、插值等算法 数据拟合在很多赛题中有应用,与图形处理有关的问题很多与拟合有关系,一个例子就是98 年美国赛A 题,生物组织切片的三维插值处理,94 年A 题逢山开路,山体海拔高度的插值计算,还有吵的沸沸扬扬可能会考的“非典”问题也要用到数据拟合算法,观察数据的

数学建模方法和步骤

数学建模的主要步骤: 第一、模型准备 首先要了解问题的实际背景,明确建模目的,搜集必需的各种信息,尽量弄清对象的特征. 第二、模型假设 根据对象的特征和建模目的,对问题进行必要的、合理的简化,用精确的语言作出假设,是建模至关重要的一步.如果对问题的所有因素一概考虑,无疑是一种有勇气但方法欠佳的行为,所以高超的建模者能充分发挥想象力、洞察力和判断力,善于辨别主次,而且为了使处理方法简单,应尽量使问题线性化、均匀化. 第三、模型构成 根据所作的假设分析对象的因果关系,利用对象的内在规律和适当的数学工具,构造各个量间的等式关系或其它数学结构.这时,我们便会进入一个广阔的应用数学天地,这里在高数、概率老人的膝下,有许多可爱的孩子们,他们是图论、排队论、线性规划、对策论等许多许多,真是泱泱大国,别有洞天.不过我们应当牢记,建立数学模型是为了让更多的人明了并能加以应用,因此工具愈简单愈有价值. 第四、模型求解 可以采用解方程、画图形、证明定理、逻辑运算、数值运算等各种传统的和近代的数学方法,特别是计算机技术.一道实际问题的解决往往需要纷繁的计算,许多时候还得将系统运行情况用计算机模拟出来,因此编程和熟悉数学软件包能力便举足轻重. 第五、模型分析 对模型解答进行数学上的分析."横看成岭侧成峰,远近高低各不?quot;,能否对模型结果作出细致精当的分析,决定了你的模型能否达到更高的档次.还要记住,不论那种情况都需进行误差分析,数据稳定性分析. 数学建模采用的主要方法有: (一)、机理分析法:根据对客观事物特性的认识从基本物理定律以及系统的结构数据来推导出模 型. 1、比例分析法:建立变量之间函数关系的最基本最常用的方法. 2、代数方法:求解离散问题(离散的数据、符号、图形)的主要方法. 3、逻辑方法:是数学理论研究的重要方法,对社会学和经济学等领域的实际问题,在决策,对策等学科中得到广泛应用. 4、常微分方程:解决两个变量之间的变化规律,关键是建立“瞬时变化率”的表达式. 5、偏微分方程:解决因变量与两个以上自变量之间的变化规律. (二)、数据分析法:通过对量测数据的统计分析,找出与数据拟合最好的模型 1、回归分析法:用于对函数f(x)的一组观测值(xi,fi)i=1,2,…,n,确定函数的表达式,由于处理的是静态的独立数据,故称为数理统计方法. 2、时序分析法:处理的是动态的相关数据,又称为过程统计方法. 3、回归分析法:用于对函数f(x)的一组观测值(xi,fi)i=1,2,…,n,确定函数的表达式,由于处理的是静态的独立数据,故称为数理统计方法.

数学建模的基本步骤

数学建模的基本步骤 一、数学建模题目 1)以社会,经济,管理,环境,自然现象等现代科学中出现的新问题为背景,一般都有一个比较确切的现实问题。 2)给出若干假设条件: 1. 只有过程、规则等定性假设; 2. 给出若干实测或统计数据; 3. 给出若干参数或图形等。 根据问题要求给出问题的优化解决方案或预测结果等。根据问题要求题目一般可分为优化问题、统计问题或者二者结合的统计优化问题,优化问题一般需要对问题进行优化求解找出最优或近似最优方案,统计问题一般具有大量的数据需要处理,寻找一个好的处理方法非常重要。 二、建模思路方法 1、机理分析根据问题的要求、限制条件、规则假设建立规划模型,寻找合适的寻优算法进行求解或利用比例分析、代数方法、微分方程等分析方法从基本物理规律以及给出的资料数据来推导出变量之间函数关系。 2、数据分析法对大量的观测数据进行统计分析,寻求规律建立数学模型,采用的分析方法一般有: 1). 回归分析法(数理统计方法)-用于对函数f(x)的一组观测值(xi,fi)i=1,2,…,n,确定函数的表达式。 2). 时序分析法--处理的是动态的时间序列相关数据,又称为过程统计方法。 3)、多元统计分析(聚类分析、判别分析、因子分析、主成分分析、生存数据分析)。 3、计算机仿真(又称统计估计方法):根据实际问题的要求由计算机产生随机变量对动态行为进行比较逼真的模仿,观察在某种规则限制下的仿真结果(如蒙特卡罗模拟)。 三、模型求解: 模型建好了,模型的求解也是一个重要的方面,一个好的求解算法与一个合

适的求解软件的选择至关重要,常用求解软件有matlab,mathematica,lingo,lindo,spss,sas等数学软件以及c/c++等编程工具。 Lingo、lindo一般用于优化问题的求解,spss,sas一般用于统计问题的求解,matlab,mathematica功能较为综合,分别擅长数值运算与符号运算。 常用算法有:数据拟合、参数估计、插值等数据处理算法,通常使用spss、sas、Matlab作为工具. 线性规划、整数规划、多元规划、二次规划、动态规划等通常使用Lindo、Lingo,Matlab软件。 图论算法,、回溯搜索、分治算法、分支定界等计算机算法, 模拟退火法、神经网络、遗传算法。 四、自学能力和查找资料文献的能力: 建模过程中资料的查找也具有相当重要的作用,在现行方案不令人满意或难以进展时,一个合适的资料往往会令人豁然开朗。常用文献资料查找中文网站:CNKI、VIP、万方。 五、论文结构: 0、摘要 1、问题的重述,背景分析 2、问题的分析 3、模型的假设,符号说明 4、模型的建立(局部问题分析,公式推导,基本模型,最终模型等) 5、模型的求解 6、模型检验:模型的结果分析与检验,误差分析 7、模型评价:优缺点,模型的推广与改进 8、参考文献 9、附录 六、需要重视的问题 数学建模的所有工作最终都要通过论文来体现,因此论文的写法至关重要:

贪婪算法在排课问题中分析与应用

贪婪算法在排课问题中分析与应用 摘要:排课问题是教学管理中重要的问题,对教学质量起到十分重要的影响。随着计算机和信息技术的快速发展,通过合理的算法编制排课系统是十分合适的。本文通过排课问题算法的分析,选择贪婪算法来解决排课问题。通过实验表明,目前的算法能够很好的解决排课问题,对问题的解决的复杂度大大降低,使得排课变得十分简单和高效。 关键字:排课,贪婪算法,优先级 1、绪论 在高校日常管理中,教学计划是重要的组成部分。而教学计划的重要体现方式之一就是排课表,其在教学管理中的地位和作用不可低估,课表的管理对教学管理是起到基础和重要的作用。因此排课问题是教学管理中重要的问题,对教学质量起到十分重要的影响。 由于上课约束条件多,课表的编制十分复杂,是一个耗时耗力的工作。目前随着高校人数的越来越多,其很难用手工去编制课表,其工作时间长,工作量大和繁琐的编制过程是一般人很难驾驭的。随着计算机和信息技术的快速发展,通过合理的算法编制排课系统是十分合适的。通过计算机算法的求解来对问题进行抽象和解决。 2、排课算法算法简介 目前对于排课问题的算法较多,主要有蚁群算法、模拟退火算法、遗传算法、整数规划法和贪婪算法等。 (1)蚁群算法 蚁群算法就是将模拟蚂蚁的活动,对参数设置较少。这种算法具备较强的全局搜索能力,但其效率较低,且容易出现停滞[1]。 (2)模拟退火算法 这个算法被较多的学者用来解决排课问题,它是模拟退火的现象,对自然事物进行抽象而来。其比较适合约束条件较少的问题。如果约束条件少,其很快就能获得最优解。但这种算法的参数选择较难,且资源开销大[2]。 (3)遗传算法 遗传算法是基于自然选择和生物遗传的全局优化策略。其优点在于在非线性问题上能够表现出全局最优,可以并行处理而且算法效率相对较高[3]。 但遗传算法本身较为复杂,由于排课问题的约束条件较多,其算法的效率较低,如果排课要求十分严格的话,很有可能造成找不到解。 (4)整数规划法 整数规划法来解决排课问题计算量很大,只适合规模较小排课问题,对于规模较大的,至今都很难找到一个可行算法。 (5)贪婪算法 贪婪算法是指在解决问题的时候,不会考虑整体最优,而是采取局部最优的思想进行最优思想[4]。也就是说,该算法将解决问题分解为每一个步骤,根据其难易程度进行解决,通过满足局部最优的方式来尽可能的获得最满意的解决。虽然在某些情况下,贪婪算法并不能得到最优解,但能得到相对满意的解。 3、排课问题综述 (1)排课原则 排课问题的本质是一个优化问题,是对教师、上课课程、上课时间和上课地点等因素的优化。其目的就是将全校所开设课程在有限的时间和地点下进行合理的安排,确保教学的顺利进行,以达到最优的效果。 为了能够产出一张满意合格的排课表,在排课中要满足一些约束条件。我们将一些约束

贪心算法的应用

从贪心算法的定义可以看出,贪心法并不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。 我们看看下面的例子 例1 均分纸牌(NOIP2002tg) [问题描述] 有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若干张纸牌,然后移动。移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。例如 N=4,4 堆纸牌数分别为: ①9 ②8 ③17 ④6 移动3次可达到目的: 从③取 4 张牌放到④(9 8 13 10) -> 从③取 3 张牌放到②(9 11 10 10)-> 从②取 1 张牌放到①(10 10 10 10)。 [输入]:键盘输入文件名。 文件格式:N(N 堆纸牌,1 <= N <= 100) A1 A2 … An (N 堆纸牌,每堆纸牌初始数,l<= Ai <=10000) [输出]:输出至屏幕。格式为:所有堆均达到相等时的最少移动次数。 [输入输出样例] : 4 9 8 17 6 屏慕显示:3 算法分析:设a[i]为第i堆纸牌的张数(0<=i<=n),v为均分后每堆纸牌的张数,s为最小移到次数。 我们用贪心法,按照从左到右的顺序移动纸牌。如第i堆(0v,则将a[i]-v张纸牌从第I堆移动到第I+1堆; (2)若a[i]

数学建模方法详解--三十四种常用算法

数学建模方法详解--三十四种常用算法 目录 一、主成分分析法 (2) 二、因子分析法 (5) 三、聚类分析 (9) 四、最小二乘法与多项式拟合 (16) 五、回归分析(略) (22) 六、概率分布方法(略) (22) 七、插值与拟合(略) (22) 八、方差分析法 (23) 九、逼近理想点排序法 (28) 十、动态加权法 (29) 十一、灰色关联分析法 (31) 十二、灰色预测法 (33) 十三、模糊综合评价 (35) 十四、隶属函数的刻画(略) (37) 十五、时间序列分析法 (38) 十六、蒙特卡罗(MC)仿真模型 (42) 十七、BP神经网络方法 (44) 十八、数据包络分析法(DEA) (51) 十九、多因素方差分析法()基于SPSS) (54) 二十、拉格朗日插值 (70) 二十一、回归分析(略) (75) 二十二、概率分布方法(略) (75) 二十三、插值与拟合(略) (75) 二十四、隶属函数的刻画(参考《数学建模及其方法应用》) (75) 二十五、0-1整数规划模型(参看书籍) (75) 二十六、Board评价法(略) (75) 二十七、纳什均衡(参看书籍) (75) 二十八、微分方程方法与差分方程方法(参看书籍) (75) 二十九、莱斯利离散人口模型(参看数据) (75) 三十、一次指数平滑预测法(主要是软件的使用) (75) 三十一、二次曲线回归方程(主要是软件的使用) (75) 三十二、成本-效用分析(略) (75) 三十三、逐步回归法(主要是软件的使用) (75) 三十四、双因子方差分析(略) (75)

一、主成分分析法 一)、主成分分析法介绍: 主成分分析(principal components analysis,PCA)又称:主分量分析,主成分回归分析法。旨在利用降维的思想,把多指标转化为少数几个综合指标。它是一个线性变换。这个变换把数据变换到一个新的坐标系统中,使得任何数据投影的第一大方差在第一个坐标(称为第一主成分)上,第二大方差在第二个坐标(第二主成分)上,依次类推。主成分分析经常用减少数据集的维数,同时保持数据集的对方差贡献最大的特征。这是通过保留低阶主成分,忽略高阶主成分做到的。这样低阶成分往往能够保留住数据的最重要方面。但是,这也不是一定的,要视具体应用而定。 二)、主成分分析法的基本思想: 在实证问题研究中,为了全面、系统地分析问题,我们必须考虑众多影响因素。这些涉及的因素一般称为指标,在多元统计分析中也称为变量。因为每个变量都在不同程度上反映了所研究问题的某些信息,并且指标之间彼此有一定的相关性,因而所得的统计数据反映的信息在一定程度上有重叠。在用统计方法研究多变量问题时,变量太多会增加计算量和增加分析问题的复杂性,人们希望在进行定量分析的过程中,涉及的变量较少,得到的信息量较多。主成分分析正是适应这一要求产生的,是解决这类题的理想工具。 同样,在科普效果评估的过程中也存在着这样的问题。科普效果是很难具体量化的。在实际评估工作中,我们常常会选用几个有代表性的综合指标,采用打分的方法来进行评估,故综合指标的选取是个重点和难点。如上所述,主成分分析法正是解决这一问题的理想工具。因为评估所涉及的众多变量之间既然有一定的相关性,就必然存在着起支配作用的因素。根据这一点,通过对原始变量相关矩阵内部结构的关系研究,找出影响科普效果某一要素的几个综合指标,使综合指标为原来变量的线性拟合。这样,综合指标不仅保留了原始变量的主要信息,且彼此间不相关,又比原始变量具有某些更优越的性质,就使我们在研究复杂的科普效果评估问题时,容易抓住主要矛盾。上述想法可进一步概述为:设某科普效果评估要素涉及个指标,这指标构成的维随机向量为。对作正交变换,令,其中为正交阵,的各分量是不相关的,使得的各分量在某个评估要素中的作用容易解释,这就使得我们有可能从主分量中选择主要成分,削除对这一要素影响微弱的部分,通过对主分量的重点分析,达到对原始变量进行分析的目的。的各分量是原始变量线性组合,不同的分量表示原始变量之间不同的影响关系。由于这些基本关系很可能与特定的作用过程相联系,主成分分析使我们能从错综复杂的科普评估要素的众多指标中,找出一些主要成分,以便有效地利用大量统计数据,进行科普效果评估分析,使我们在研究科普效果评估问题中,可能得到深层次的一些启发,把科普效果评估研究引向深入。 例如,在对科普产品开发和利用这一要素的评估中,涉及科普创作人数百万人、科普作品发行量百万人、科普产业化(科普示范基地数百万人)等多项指标。经过主成分分析计算,最后确定个或个主成分作为综合评价科普产品利用和开发的综合指标,变量数减少,并达到一定的可信度,就容易进行科普效果的评估。 三)、主成分分析法的数学模型: 其中:

算法分析与设计选修课-贪心算法应用研究

武汉理工大学 算法设计与分析论文题目:贪心算法应用研究 姓名:吴兵 学院:信息工程 专业班级:电子133 学号: 1409721303131 任课教师:张小梅

目录 摘要 (1) 1.绪论 (2) 2贪心算法的基本知识概述 (3) 2.1 贪心算法定义 (3) 2.2 贪心算法的基本思路及实现过程 (3) 2.3贪心算法的核心 (3) 2.4贪心算法的基本要素 (4) 2.5 贪心算法的理论基础 (6) 2.6 贪心算法存在的问题 (7) 3贪心算法经典应用举例 (8) 3.1删数问题 (8) 3.2 汽车加油问题 (10) 3.3会场安排问题 (12) 4.总结 (16) 5.参考文献 (17)

摘要 在求最优解问题的过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解,这种求解方法就是贪心算法。从贪心算法的定义可以看出,贪心法并不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。贪心算法所作的选择可以依赖于以往所作过的选择,但决不依赖于将来的选择,也不依赖于子问题的解,因此贪心算法与其它算法相比具有一定的速度优势。如果一个问题可以同时用几种方法解决,贪心算法应该是最好的选择之一。本文讲述了贪心算法的含义、基本思路及实现过程,贪心算法的核心、基本性质、特点及其存在的问题。并通过贪心算法的特点举例列出了以往研究过的几个经典问题,对于实际应用中的问题,也希望通过贪心算法的特点来解决。 关键词:贪心算法最小生成树多处最优服务次序问题删数问题

贪婪算法

答:贪婪算法(Greedy algorithm)是一种对某些求最优解问题的更简单、更迅速的设计技术。用贪婪法设计算法的特点是一步一步地进行,常以当前情况为基础根据某个优化测度作最优选择,而不考虑各种可能的整体情况,它省去了为找最优解要穷尽所有可能而必须耗费的大量时间,它采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解,虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪婪法不要回溯。 贪婪算法是一种改进了的分级处理方法。其核心是根据题意选取一种量度标准。然后将这多个输入排成这种量度标准所要求的顺序,按这种顺序一次输入一个量。如果这个输入和当前已构成在这种量度意义下的部分最佳解加在一起不能产生一个可行解,则不把此输入加到这部分解中。这种能够得到某种量度意义下最优解的分级处理方法称为贪婪算法。 对于一个给定的问题,往往可能有好几种量度标准。初看起来,这些量度标准似乎都是可取的,但实际上,用其中的大多数量度标准作贪婪处理所得到该量度意义下的最优解并不是问题的最优解,而是次优解。因此,选择能产生问题最优解的最优量度标准是使用贪婪算法的核心。 一般情况下,要选出最优量度标准并不是一件容易的事,但对某问题能选择出最优量度标准后,用贪婪算法求解则特别有效。最优解可以通过一系列局部最优的选择即贪婪选择来达到,根据当前状态做出在当前看来是最好的选择,即局部最优解选择,然后再去解做出这个选择后产生的相应的子问题。每做一次贪婪选择就将所求问题简化为一个规模更小的子问题,最终可得到问题的一个整体最优解。其有以下特性: ⑴ 有一个以最优方式来解决的问题。为了构造问题的解决方案,有一个候选的对象的集合:比如不同面值的硬币。 ⑵ 随着算法的进行,将积累起其它两个集合:一个包含已经被考虑过并被选出的候选对象,另一个包含已经被考虑过但被丢弃的候选对象。 ⑶ 有一个函数来检查一个候选对象的集合是否提供了问题的解答。该函数不考虑此时的解决方法是否最优。 ⑷ 还有一个函数检查是否一个候选对象的集合是可行的,也即是否可能往该集合上添加更多的候选对象以获得一个解。和上一个函数一样,此时不考虑解决方法的最优性。 ⑸ 选择函数可以指出哪一个剩余的候选对象最有希望构成问题的解。 ⑹ 最后,目标函数给出解的值。

相关文档