数学建模常用算法--编程交流
数学建模吧
全部回复
仅看楼主
level 9
雪狼冥灵 楼主
声明:该文档均经整理来自论坛,相应的算法设计与思路,应用等均可在百度中详细查询。这里都大概在竞赛要求的理解范围内提一下。
https://tieba.baidu.com/p/1764603543 (该网址来源于精品贴,新人必读吧主整理的十大经典算法)。
这里简要介绍下一些常用算法的设计思路,对大家的建模成长作用很大。在任何时候,这些算法的的光芒始终耀眼。
1,概率算法(也可以是monto carlo算法的思想)
2,贪婪算法
3,模拟退火算法
4,组合算法
5,分治算法
6,规划算法(这里主要动态规划)
7,神经网络算法
8,遗传算法
9,搜索算法,排序算法,floyd算法等
2014年10月25日 14点10分 1
level 9
雪狼冥灵 楼主
9,排序算法在组合算法中已写。其他的参阅数据结构即可。
floyd算法,matlab编写,十分简单
%floyd.m
%采用floyd算法计算图a中每对顶点最短路
%d是矩离矩阵
%r是路由矩阵
function [d,r]=floyd(a)
n=size(a,1);
d=a;
for i=1:n
for j=1:n
r(i,j)=j;
end
end
r
for k=1:n
for i=1:n
for j=1:n
if d(i,k)+d(k,j)<d(i,j)
d(i,j)=d(i,k)+d(k,j);
r(i,j)=r(i,k)
end
end
end
k
d
r
end
2014年10月25日 15点10分 12
level 9
雪狼冥灵 楼主
三、A*算法
 A*算法中更一般的引入了一个估价函数f,其定义为f=g+h。其中g为到达当前节点的耗费,而h表示对从当前节点到达目标节点的耗费的估计。其必须满足两个条件:
1、h必须小于等于实际的从当前节点到达目标节点的最小耗费h*。
2、f必须保持单调递增。
 A*算法的控制结构与广度搜索的十分类似,只是每次扩展的都是当前待扩展节点中f值最小的一个,如果扩展出来的节点与已扩展的节点重复,则删去这个节点。如果与待扩展节点重复,如果这个节点的估价函数值较小,则用其代替原待扩展节点,具体算法描述如下:
范例:一个3*3的棋盘中有1-8八个数字和一个空格,现给出一个初始态和一个目标态,要求利用这个空格,用最少的步数,使其到达目标态。
问题分析:预期值定义为h=|x-dx|+|y-dy|。
     估价函数定义为f=g+h。
<Type>
 Node(节点类型)=Record
 Situtation:TSituation(当前节点状态);
 g:Integer;(到达当前状态的耗费)
 h:Integer;(预计的耗费)
 f:Real;(估价函数值)
 Last:Integer;(父节点)
End
<Var>
 List(节点表):Array[1..Max(最多节点数)] of Node(节点类型);
 open(总节点数):Integer;
  close(待扩展节点编号):Integer;
 New-S:Tsituation;(新节点)
<Init>
 List<-0;
 open<-1;
 close<-0;
 List[1].Situation<- 初始状态;
 <Main Program>
 While (close<open(还有未扩展节点)) and
  (open<Max(空间未用完)) and
  (未找到目标节点) do
 Begin
  Begin
   close:=close+1;
   For I:=close+1 to open do (寻找估价函数值最小的节点)
   Begin
    if List[i].f<List[close].f then
    Begin
     交换List[i]和List[close];
    End-If;
   End-For;
  End;
 For I:=1 to TotalExpendMethod do(扩展一层子节点)
 Begin
  New-S:=ExpendNode(List[close].Situation,I)
  If Not (New-S in List[1..close]) then
   (扩展出的节点未与已扩展的节点重复)
   Begin
    If Not (New-S in List[close+1..open]) then
    (扩展出的节点未与待扩展的节点重复)
    Begin
     open:=open+1;
     List[open].Situation:=New-S;
     List[open].Last:=close;
     List[open].g:=List[close].g+cost;
     List[open].h:=GetH(List[open].Situation);
     List[open].f:=List[open].h+List[open].g;
    End-If
    Else Begin
     If List[close].g+cost+GetH(New-S)<List[same].f then
      (扩展出来的节点的估价函数值小于与其相同的节点)
     Begin
      List[same].Situation:= New-S;
      List[same].Last:=close;
      List[same].g:=List[close].g+cost;
      List[same].h:=GetH(List[open].Situation);
      List[same].f:=List[open].h+List[open].g;
     End-If;
   End-Else;
  End-If
 End-For;
End-While;
 对A*算法的改进--分阶段A*:
 当A*算法出现数据溢出时,从待扩展节点中取出若干个估价函数值较小的节点,然后放弃其余的待扩展节点,从而可以使搜索进一步的进行下去。
2014年10月25日 15点10分 15
level 9
雪狼冥灵 楼主
6,动态规划;这里面是运筹学的知识,很多整数规划,线性规划等都已经在上面提供了很多思路,继续讲解都是赘述,大家可以看看书或者查阅相关资料。
引言
动态规划的基本概念
动态规划的基本定理和基本方程
动态规划的适用条件
动态规划的基本思想
动态规划的基本步骤
动态规划的实例分析
动态规划的技巧
动态规划实现中的问题
动态规划与其他算法的比较
动态规划的理论基础
其他资料
2014年10月25日 15点10分 17
level 9
雪狼冥灵 楼主
5,分治算法
分治法的基本思想
任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。问题的规模越小,越容易直接求解,解题所需的计算时间也越少。例如,对于n个元素的排序问题,当n=1时,不需任何计算。n=2时,只要作一次比较即可排好序。n=3时只要作3次比较即可,…。而当n较大时,问题就不那么容易处理了。要想直接解决一个规模较大的问题,有时是相当困难的。
分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
如果原问题可分割成k个子问题,1<k≤n ,且这些子问题都可解,并可利用这些子问题的解求出原问题的解,那么这种分治法就是可行的。由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。这自然导致递归过程的产生。分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。
分治法的适用条件
分治法所能解决的问题一般具有以下几个特征:
该问题的规模缩小到一定的程度就可以容易地解决;
该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。
利用该问题分解出的子问题的解可以合并为该问题的解;
该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。
上述的第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;第二条特征是应用分治法的前提,它也是大多数问题可以满足的,此特征反映了递归思想的应用;第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑贪心法或动态规划法。第四条特征涉及到分治法的效率,如果各子问题是不独立的,则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好。
分治法的基本步骤
分治法在每一层递归上都有三个步骤:
分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;
解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题;
合并:将各个子问题的解合并为原问题的解。
它的一般的算法设计模式如下:
Divide-and-Conquer(P)1. if |P|≤n0 2. then return(ADHOC(P))3. 将P分解为较小的子问题 P1 ,P2 ,...,Pk4. for i←1 to k 5. do yi ← Divide-and-Conquer(Pi) △ 递归解决Pi6. T ← MERGE(y1,y2,...,yk) △ 合并子问题7. return(T)
其中|P|表示问题P的规模;n0为一阈值,表示当问题P的规模不超过n0时,问题已容易直接解出,不必再继续分解。ADHOC(P)是该分治法中的基本子算法,用于直接解小规模的问题P。因此,当P的规模不超过n0时,直接用算法ADHOC(P)求解。算法MERGE(y1,y2,...,yk)是该分治法中的合并子算法,用于将P的子问题P1 ,P2 ,...,Pk的相应的解y1,y2,...,yk合并为P的解。
根据分治法的分割原则,原问题应该分为多少个子问题才较适宜?各个子问题的规模应该怎样才为适当?这些问题很难予以肯定的回答。但人们从大量实践中发现,在用分治法设计算法时,最好使子问题的规模大致相同。换句话说,将一个问题分成大小相等的k个子问题的处理方法是行之有效的。许多问题可以取k=2。这种使子问题规模大致相等的做法是出自一种平衡(balancing)子问题的思想,它几乎总是比子问题规模不等的做法要好。
分治法的合并步骤是算法的关键所在。有些问题的合并方法比较明显,如下面的例1,例2;有些问题合并方法比较复杂,或者是有多种合并方案,如例3,例4;或者是合并方案不明显,如例5。究竟应该怎样合并,没有统一的模式,需要具体问题具体分析。
2014年10月25日 15点10分 18
level 9
雪狼冥灵 楼主
@中国人看好中国
虽然写得乱七八糟,但是主要思想,脉络都是很清晰,这些算法的思想很常用。不影响大局,请申精。
2014年10月25日 15点10分 20
我一般无聊的时候把这些东西当电子书看~~~@中国人看好中国
2014年10月25日 15点10分
level 12
过来支持下
2014年10月28日 11点10分 22
谢谢来顶。近期一直在弄计量经济学和arma模型,回复晚了,见谅
2014年11月07日 04点11分
level 5
支持一下!
2014年10月29日 11点10分 23
谢谢
2014年11月07日 04点11分
level 7
楼主,求加好友
2014年10月29日 13点10分 24
能干什么啊――
2014年11月07日 04点11分
回复 雪狼冥灵 :问问经验啊,求大神随时指点
2014年11月07日 04点11分
回复 雪狼冥灵 :好的,求QQ
2014年11月07日 05点11分
回复 雪狼冥灵 :楼主,求加好友。最近快被数学建模虐哭了[泪]
2014年12月18日 01点12分
level 11
真心要说谢谢哦,直到最近看见数学建模,上网对我不在只是堕落的地方了
2014年11月07日 02点11分 25
哦,你也可以加些论坛看看。数学中国就可以。平时多关注身边事物,多思考,做点有关优化的事情
2014年11月07日 04点11分
个签出自[吐舌]
2015年08月23日 15点08分
level 6
还可以吧,不错
2014年11月07日 08点11分 27
level 6
网络上的东西像这样真不多。。。。。。
2014年11月07日 08点11分 28
level 1
楼主实在太厉害了,这一回俺学到了好多
2014年11月16日 06点11分 29
level 10
问下楼主。第一次参加应该看什么书提前准备呢?
2014年11月17日 01点11分 30
level 1
辛苦了,谢谢。
2014年12月06日 03点12分 31
level 11

2015年03月05日 04点03分 32
level 7
楼主有电子版吗?要是有的话可以发一下吗?我是刚刚接触建模还请多多指教!谢谢啦!
2015年03月06日 11点03分 33
level 11

2015年03月12日 08点03分 34
level 6

2015年04月17日 00点04分 36
level 8
lz
能给个word文档吗?想打印出来,谢谢
2015年04月17日 02点04分 37
1 2 尾页