回溯与分支限界算法-学习笔记



1、基本概念


解空间:搜索问题的解所在的集合,又称为搜索空间。解空间通常可以安排成树形结构,常用解空间有子集树,排列树等。


回溯算法:遵照某种搜索策略搜索解空间从而找出解的过程。常用的搜索策略有:深度优先、宽度优先、规则优先等。


分支限界算法:回溯算法的一种特例。在回溯算法运行过程中,为加快算法的速度,尽可能多地在解空间中进行剪枝,设立新的约束条件——代价函数和界。

(对于最大化问题)当代价函数小于界的时候即进行剪枝,这种回溯算法叫做分支限界算法。


代价函数:以搜索树的任何的结点v开始搜索以v为根的子树,在这个范围可能得到可行解,代价函数f(v)表示在该子树中可行解的目标函数值的一个上界(对于最大化问题)


界函数:函数在搜索树中某个结点的函数值是算法搜索到该结点时,已经得到的可行解的目标函数的最大值。


注意:使用回溯算法需要问题本身满足多米诺性质,即:P(x1,x2,……,x(i+1))为真蕴含P(x1,x2,……,xi)为真。


2、典型回溯算法

  • n皇后问题的回溯算法;
  • 0-1背包问题的回溯算法;
  • 货郎问题(TSP)的回溯算法;
  • 装载问题的回溯算法;
  • 图的m着色问题;
  • 最大团问题的分支限界算法;
  • 货郎问题(TSP)的分支限界算法;
  • 图排列问题的分支限界算法;
  • 连续邮资问题的回溯算法;


3、子集树与排列树

当所给问题是从n个元素的集合S中找出满足某种性质的子集时,解空间称为子集树。

例如:0-1背包问题。这类子集树通常有2^n个节叶结点。所需要的时间复杂度是O(2^n);


当所给问题是从n个元素的集合S中找出满足某种性质的排列时,解空间为排列树。

例如:旅行售货员问题。排列树有n!个叶结点。因此遍历该树所用的时间复杂度是O(n!)


子集树代码描述:

void Backtrack(int in)
{
   if(in>n) 
	outpux(x);  
   else
     for(int i=0;i<=1;i++)
       x[in]=i;

    if(legal(t))
        Backtrack(in+1);
}

</span>

排列树代码描述:

void Backtrack(int in){
  if(in>n)   outpux(x); 
  else
     for(int i=in;i<=n;i++)
       swap(x[in],x[i]);

     if(legal(t))
        Backtrack(in+1);
     swap(x[in],x[i]);
}




    原文作者:分支限界法
    原文地址: https://blog.csdn.net/tommyzht/article/details/45848969
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞