晓强Deep Learning的读书分享会,先从这里开始,从大学开始。大家好,我是晓强,计算机科学与技术专业研究生在读。我会不定时的更新我的文章,内容可能包括深度学习入门知识,具体包括CV,NLP方向的基础知识和学习的论文;网络表征学习的相关论文解读。当然我每天的读书心得也会分享给大家,可能涉及我们生活各个方面的书籍。我也会不定时回答大家的问题与大家一同进步,共同交流,互相监督,结交更多的朋友。希望大家多留言,多交流,多多关照。我在这里等你一同学习,如果需要相关资料也可以私信我,进入我们的群大家庭。
【晓白】今天正值高考,给大家加油。还是要坚持下去的,努力终会有收获,只为了追求那个曾经的优秀的自己。所以今天中午抽时间写了一篇分支限界法的文章。希望大家点赞,关注,支持一下。谢谢精神合伙人的支持和鼓励。如果有准备秋招的同学,也可以来看一下,对大家很有帮助。有任何疑问可以私信,获得我们大家庭的联系方式,多多沟通,共同进步。如果高考结束以后大家对计算机学习有一定兴趣,或者家长朋友和考生希望以后报考计算机,学习计算机的,也可以关注我,看更多文章;详情私信,了解更多。可以咨询,辅导入门。今天更新第六章的前面先补充一下回溯法的效率。
第五章回溯法的效率分析:
一个回溯算法的效率在很大程度上依赖于以下几个因素:
(1)产生X[k]的时间
(2)满足显约束的x[k]值的个数
(3)计算约束函数Constraint的时间
(4)计算上界函数Bound的时间
(5)满足约束函数和上界函数约束的所有x[k]的个数,在选择约束函数时通常存在着生成结点数与约束函数计算量之间的折衷
重排原理:
解空间的结构一经选定,影响回溯法效率的前四个因素就可以确定,只剩下生成结点的数目是可变的,它将随问题的具体内容以及结点的不同生成方式而变动。
对于一个问题的具体实例,我们很难预测回溯法的算法行为。特别是我们很难估计出回溯法在解这一具体实例时所产生的结点数。这是我们在分析回溯法效率时遇到的主要困难。
蒙特卡罗方法:
估计回溯法将要产生的结点数目。主要思想是在解空间树上产生一条随机的路径,然后沿此路径来估算解空间树中满足约束条件的结点总数。
算法Estimate从解空间树的根结点开始选取一条随机路径,计算回溯法生成的结点总数m。
Estimate (int n, Type *x)
{ int m=1,r=1,k=1;
while (k<=n)
{
SetType T=x[k]的满足约束的可取值集合;
if (Size(T)==0)return m;
r*= Size(T); // Size(T)得到集合T大小
m+=r;
x[k]=Choose(T); //Choose(T) 从集合T随机地选一个元素
k++;
}
return m;
}
当用回溯法求解某一具体问题时,可用算法Estimate估算回溯法生成的结点数。
若要估算得更精确些,可选取若干条不同的随机路径(通常不超过20条),分别对各随机路径估计结点总数,然后再取这些结点总数的平均值,得到m的估算值。
例:8后问题
利用显约束排除那些有2个皇后在同一行或同一列的方法,也有8!种不同的方法。8后问题的解空间树的结点总数是:
回溯法产生的结点数m是解空间树的结点总数的1.55%左右。说明回溯法的效率大大高于穷举法。
第六章 分支限界法
分支限界法类似于回溯法,也是一种在问题的解空间树T上搜索解的算法。但是,分支限界法与回溯法有不同的求解目标:回溯法的求解目标是找出T中满足约束条件的所有解,或任意一个解;分支限界法的求解目标则是找出T中使得某一目标函数值达到极小或极大的解,即问题在某种意义下的最优解。
由于求解目标不同, 导致分支限界法与回溯法在解空间树T上搜索的算法有两点不同:
(1)回溯法以深度优先的方式搜索解空间树T;分支限界法以广度优先或最小耗费优先的方式搜索解空间树T。
(2)回溯法一般只通过约束条件,而分支限界法不仅通过约束条件,而且通过目标函数的限界来减少无效搜索,提高求解效率。
分支限界法的搜索策略是:
在扩展结点处,先生成其所有儿子结点(使其变为活结点),然后再从当前的活结点表中选择下一个扩展结点。为了有效地选择下一个扩展结点,以加速搜索的进程,在每一活结点处,计算一个函数值(限界),并根据这些已计算出的函数值,从当前活结点表中选择一个最有利的结点作为扩展结点,使搜索朝着解空间树上有最优解的分支推进,以便尽快地找出一个最优解。这种方法就称为分支限界法。
一、分支限界法的基本思想
从活动结点表选择下一个扩展结点的原则体现在对活结点表的组织方式(即,数据结构)之中。常见的活结点表的组织方式有以下二种:
队列式(FIFO)
优先队列式(PQ, Prioroty Queue)---优先队列可用堆实现
所以,常见的分支限界法分为:
(1)队列式(FIFO)分支限界法
(2)优先队列式(PQ)分支限界法
用队列式分支限界法求解单源最短路径问题
按队列式分支限界法求解单源最短路径的算法:
SSShortestPaths(v)
{ E.i=v;
E.length=0;
dist[v]=0; //源点V到源点V的最近距离
INSERT (Q, E); //Q是一个队列
while(!Empty(Q))
{ E=DELETE(Q);
if(dist[E.i]<E.length) continue; //源点V到顶点i的当前最近距离
for(j=1; j<=n; j++)
if ((c[E.i][j]<inf)&&(E.length+c[E.i][j]<dist[j]))
{ dist[j]=E.length+c[E.i][j];
prev[j]=E.i;
N.i=j;
N.length=dist[j];
INSERT(Q,N);
}
}
}
用优先队列式分支限界法求解单源最短路径问题
(1) 按队列式分支限界法求解多段图最短路径的算法:
ShortestPath(v)
{E.i=v; E.length=0;
Bound=inf; //也可用贪心法先确定一个初始界限
INSERT (Q, E); //Q是队列
while(!Empty(Q))
{ E=DELETE(Q);
if(Bound<E.length) continue;
for (j=1; j<=n; j++)
{ if ((c[E.i][j]<inf)&&(E.length+c[E.i][j]<Bound))
{ prev[j]=E.i;
if(j是终点)
{Bound=E.length+c[E.i][j];continue; }
N.i=j;
N.length= E.length+c[E.i][j];
INSERT(Q,N);
}
}
}
}
按优先队列式分支限界法求解多段图问题的算法:
template <class Type>
void graph <Type> :: ShortestPath(int v)
{MinHeap <MinHeapNode <Type> > H(1000); //定义小根堆的容量为1000
MinHeapNode <Type> E;
E.i=v; E.length=0; //定义源为初始扩展结点
Bound=inf; //开始搜索问题的解空间
while(true)
{ if(E.length<Bound)
for(j=1; j<=n; j++)
if ((c[E.i][j]<inf)&&(E.length+c[E.i][j]<Bound))
{ prev[j]=E.i;
if(j是终点)
{Bound=E.length+c[E.i][j];continue; }
MinHeapNode <Type> N;
N.i=j; N.length= E.length+c[E.i][j];
H.Insert(N);
}
try { H.DeleteMin(E);} //从优先队列取下一个扩展结点
catch (OutOfBound) {break;} // 优先队列空
}
}
今天算法设计分析的第六章更新完毕,明天我会继续更新对于第五章,和第六章的补充知识,敬请期待。当然,后续我也打算给小伙伴们更新一下计算理论的介绍以便大家全面的学习。7.7-7.10是高考的日子,我也会继续更新,希望与大家一起坚持下去。祝顺利,金榜题名都圆大学梦。莘莘学子们,如果对计算机学习感兴趣也可以私信留言咨询,学习,推荐资料,一对一辅导交流都可以。加入大家庭,一起学习。感兴趣,关注我,阅读更多文章。连接如下,
晓强DL:第五章 回溯法(Backtrack)zhuanlan.zhihu.com