回溯法(DFS)

回溯法-DFS搜索

《回溯法(DFS)》

N后问题——经典的DFS

1.背景知识

解空间

  • 子集树
    所给的问题是从n个元素的集合S中找出满足某种性质的子集时,相应的解空间成为子集树。(从集合中选取数据)
    如0-1背包问题,从所给重量、价值不同的物品中挑选几个物品放入背包,使得在满足背包不超重的情况下,背包内物品价值最大。它的解空间就是一个典型的子集树。
  • 排列树
    所给的问题是确定n个元素满足某种性质的排列时,相应的解空间就是排列树。
    如旅行售货员问题,一个售货员把几个城市旅行一遍,要求走的路程最小。它的解就是几个城市的排列,解空间就是排列树。

2.定义

回溯算法也叫试探法,它是一种按深度优先系统地搜索问题的解的方法

3.思路与模板

  • 回溯法思路的简单描述是:把问题的解空间转化成了图或者树的结构表示,然后使用深度优先搜索策略进行遍历,遍历的过程中记录和寻找所有可行解或者最优解。
  • 模板:
void dfs(int i)
{
    if(i==n+1)
    {
        if(a&&a<=b&&b<=c&&a+b>=c)
        {
            long long z=a*10000000+b;//到树末返回;
            s.insert(z);
        }
        return ;
    }
    a+=l[i];dfs(i+1);a-=l[i];
    b+=l[i];dfs(i+1);b-=l[i];//试探,试探完了之后就复原回溯
    c+=l[i];dfs(i+1);c-=l[i];

}

4. 解题步骤:

1.定义一个解空间,它包含问题的解;
2.利用适于搜索的方法组织解空间;(构建解空间树)
3.利用深度优先法搜索解空间;(搜索解空间树)
4.利用限界函数避免移动到不可能产生解的子空间。(缩小搜索的范围)

void dfs(int 当前状态)
    {
          if(当前状态为边界状态)
          {
            记录或输出
            return;
          }
          for(i=0;i<n;i++)      //横向遍历解空间树所有子节点
         {
               //扩展出一个子状态。 ************试探
          {     
               修改了全局变量
               if(子状态满足约束条件)
                {
                  dfs(子状态)
               }
          }
                恢复全局变量//回溯部分 ************试探结束恢复
            }
    }

n后问题的易理解的java代码:

import Java.util.Scanner;


public class Queen {
static int n;// 皇后个数
static long sum;// 当前解个数;
static int[] x;


public static void BackTrack(int t) {
if (t > n) {
sum++;
} else {
for (int i = 1; i <= n; i++) {
x[t] = i;
if (Place(t))
BackTrack(t + 1);
}
}
}


public static boolean Place(int k) {
for (int j = 1; j < k; j++)
if ((Math.abs(k - j) == Math.abs(x[j] - x[k])) || (x[j] == x[k]))  //斜线与同一列;
return false;
return true;


}


public static void main(String[] args) {
// 输入皇后的个数;
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
String str = in.nextLine();
if (str != null) {
n = Integer.parseInt(str);
sum = 0;
x = new int[n + 1];
for (int i = 0; i <= n; i++)
x[i] = 0;
BackTrack(1);
System.out.println(sum);
} else {
System.out.println("请输入正确的数组~");
}


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