回溯法(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("请输入正确的数组~");
}


}
}
}
### DFS 深度优先搜索与路径回溯法 #### 定义与特性 DFS(深度优先搜索)是一种用于遍历或搜索树或图的算法,其特点在于沿着树的深度方向尽可能深入地遍历节点[^5]。一旦到达叶节点或是遇到无法继续前进的情况,则会退回到最近的一个未完全探索过的节点并继续探索其他分支。 #### 算法实现逻辑 为了更好地理解和实现DFS及其路径回溯功能,在编程实践中可以采用递归方法来简化代码编写: 1. **初始化** - 设置初始状态作为起点。 2. **选择操作** - 对于每一个可选动作,尝试执行该动作,并将其加入当前路径中。 3. **递归调用** - 如果选择了新的位置,则对该新位置再次应用相同的流程;如果达到了结束条件则保存结果。 4. **撤销选择(回溯)** - 当前路径不再可行时,移除最后的选择恢复之前的状态以便测试下一个选项。 以下是Python中的具体实现例子: ```python def dfs(graph, start, visited=None): if visited is None: visited = set() stack = [(start, [start])] while stack: (vertex, path) = stack.pop() if vertex not in visited: if check_goal_condition(vertex): # 自定义的目标检测函数 print(f"Found solution: {path}") break visited.add(vertex) for neighbor in reversed(sorted(graph[vertex])): if neighbor not in visited: stack.append((neighbor, path + [neighbor])) ``` 此段代码展示了如何利用栈结构模拟递归来完成非递归版本的DFS以及路径追踪。`graph`参数表示要搜索的数据结构,比如邻接表形式存储的地图;`check_goal_condition()`是一个假设存在的辅助函数用来判断是否找到了符合条件的结果。 #### 关键点说明 - 使用列表代替显式的递归能够有效防止因递归层数过多而导致程序崩溃的问题。 - `reversed(sorted())`确保每次迭代总是先处理较小编号的邻居顶点,从而使得输出更加有序美观。 - 记录完整的访问历史(`path`)有助于分析最终得到的答案是如何构成的。 #### 应用实例 上述提到的方法适用于解决诸如迷宫求解、连通分量查找等问题。对于更复杂的场景如八数码游戏或者N皇后问题,则需引入额外机制来进行有效的剪枝以提高效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值