算法之回溯法学习笔记

本文探讨了回溯法在解决一系列问题中的应用,包括0/1背包问题、八皇后问题、迷宫问题和旅行商问题。通过将问题转化为图或树结构,如子集树、排列树和四叉树,回溯法能搜索所有可能的解。对于旅行商问题,增加了记录路径、最佳路径长度和当前路径长度等概念,并引入了约束条件和限界条件来优化搜索过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

把问题得解空间转化为图或树:
1.子集树:集合中满足条件的子集等,N叉树
2.排列树:确定n个元素满足某种性质的排列,“排列树”并不是N叉树,不能重复选择

0/1背包问题<——>二叉树(0,1)<——>子集树 backtrack(t) ——> 找到t层以下的所有解(每一层代表选不选该货物,0代表不选,1代表选)
O
0/ \1
O O
0 / 1 \ /0 \1
O OO O

if(t > N)
   if(cur_value > best_value)
       print && record
else{
   for(int i = 0; i <= 1; i++){
       x(t) = i;
       if(i == 0) backtrack(t+1);
       else{
           if(cur_wight + w(t) <= total_wight){ //约束函数
               cur_wight += w(t);
               cur_value += v(t);
               backtrack(t+1);     //递归
               cur_wight -= w(t);
               cur_value -= v(t);  //回溯
           }
       }
   }
}

八皇后问题<——>八叉树<——>子集树问题:backtrack(t) ==>找到t层以下的所有解
在这里插入图片描述

board[8][8]
bool isOK(board[][], raw, col)   //判断是否符合要求
if(t > N)
   print board;
else{
   for(int i = 0; i < 8; i++){
       if(isOK(board[][],t,i)){ //约束条件
           board[t][i] = 1; // 进入下层分支
           backtrack(t+1);  // 递归
           board[t][i] = 0; // 回溯
       }
   }
}

迷宫问题<——>四叉树<——>子集树问题:backtrack(x,y)==>从x,y走到x_end,y_end的所有情况

在这里插入图片描述

问题描述,例如此图,确定一组(x_end, y_end)(假设恰好为右下角),从(x,y)到(x_end,y_end)的所有通路,其中0代表墙,无法通过,如果不能到达,返回false。
在这里插入图片描述

Maze[4][6]
bool isOK(Maze[][], x, y)   //判断是否符合要求 return Maze[x][y] != 0;
if(x == x_end && y == y_end)
   print and record;
else{
   path.push_back({x,y});
   Maze[x][y] = 0;
   if(isOK(Maze,x-1,y)) backtrack(x-1,y);
   if(isOK(Maze,x+1,y)) backtrack(x+1,y);
   if(isOK(Maze,x,y-1)) backtrack(x,y-1);
   if(isOK(Maze,x,y+1)) backtrack(x,y+1); //相当于for循环
   Maze[x][y] = 1;
   path.pop_back();  //回溯
}

旅行商问题<——>有先后之分,不去同一个城市两次<——>排列数
root
1 2 3 4
2 3 4 |1 3 4 |1 2 4 |1 2 3 不是一个N叉树

backtrack(t)
{
   if(t > n)
       print
   else{
       for(int i = t; i <= n; i++){
           swap(x[t],x[i]);
           backtrack(t+1);
           swap(x[t],x[i]);
       }
   }
}

旅行商问题只是多了record,best_path_length和cur_path_length以及约束条件和限界条件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值