探讨Java深搜算法的学习笔记

大家好,我是 V 哥。深度优先搜索(DFS)是一种图遍历算法,它优先深入到某条路径的尽头,再回溯到前一个节点继续探索其他路径,直到找到目标或遍历完整个图。DFS的应用场景广泛,可以用于路径搜索、连通性判断、迷宫求解等。以下是一个典型的DFS实现示例以及分析它在不同业务场景中的应用。

1. 先来看一个案例

以下为一个Java实现的DFS算法示例,用于在一个二维矩阵中寻找从起点到终点的路径。该矩阵中1表示可以通过的点,0表示障碍物。目标是找到从起点(0,0)到终点(m-1,n-1)的路径。

public class DFSMazeSolver {
    private static final int[] DX = {-1, 1, 0, 0}; // 行移动方向:上,下
    private static final int[] DY = {0, 0, -1, 1}; // 列移动方向:左,右

    public boolean dfs(int[][] maze, int x, int y, boolean[][] visited) {
        int rows = maze.length;
        int cols = maze[0].length;

        // 边界条件与目标判断
        if (x < 0 || y < 0 || x >= rows || y >= cols || maze[x][y] == 0 || visited[x][y]) {
            return false;
        }

        // 到达终点
        if (x == rows - 1 && y == cols - 1) {
            return true;
        }

        // 标记当前位置已访问
        visited[x][y] = true;

        // 递归地探索四个方向
        for (int i = 0; i < 4; i++) {
            int newX = x + DX[i];
            int newY = y + DY[i];
            if (dfs(maze, newX, newY, visited)) {
                return true;
            }
        }

        // 回溯
        visited[x][y] = false;
        return false;
    }

    public boolean canSolveMaze(int[][] maze) {
        int rows = maze.length;
        int cols = maze[0].length;
        boolean[][] visited = new boolean[rows][cols];
        return dfs(maze, 0, 0, visited);
    }

    public static void main(String[] args) {
        int[][] maze = {
                {1, 0, 0, 0},
                {1, 1, 0, 1},
                {0, 1, 0, 0},
                {1, 1, 1, 1}
        };

        DFSMazeSolver solver = new DFSMazeSolver();
        if (solver.canSolveMaze(maze)) {
            System.out.println("路径可达");
        } else {
            System.out.println("无可行路径");
        }
    }
}

代码说明

  1. DFS主逻辑dfs方法用于在当前位置(xy)开始深度优先搜索。
  2. 边界条件:包括是否越界、是否遇到障碍物以及是否已经访问。
  3. 终点判断:当到达矩阵右下角终点(rows-1cols-1)时,返回true
  4. 回溯处理:在搜索过程中,为了避免重复访问,将访问过的位置标记为已访问,若搜索失败则回溯重置。

2. 业务场景分析

  1. 迷宫或地图导航:DFS可用于迷宫或地图路径导航,寻找从起点到终点的路径。在实际应用中,可以在机器人路径规划、无人机飞行路径规划中使用类似的DFS算法。

  2. 权限和连通性检测:在网络安全中,DFS可以用于检测用户权限或系统连通性,例如检测某用户在权限网络中的访问路径,确保系统关键资源安全。

  3. 社交网络分析:在社交网络中,DFS可以用于分析用户关系连通性,例如寻找两个人之间的关系链路、推荐相似好友。

  4. 数据爬取:DFS算法也可用于数据爬取,从起始页面开始深度爬取相关页面信息。

在机器人路径规划和无人机飞行路径规划中,DFS算法可以用来寻找从起点到目标点的可行路径。DFS适合在地图较小且需要找到任意一条可行路径的场景。以下是一个在网格地图上实现DFS的完整Java代码示例,模拟机器人或无人机在二维平面上寻找从起点到目标点的路径。

如何实现无人机飞行路径规划

假设网格中的0表示障碍物,1表示可通行区域。目标是从起点(0, 0)到终点(m-1, n-1)找到一条通路。

import java.util.ArrayList;
import java.util.List;

public class RobotPathPlanner {
    // 定义四个方向:上,下,左,右
    private static final int[] DX = {-1, 1, 0, 0};
    private static final int[] DY = {0, 0, -1, 1};
    private static final String[] DIRECTION = {"Up", "Down", "Left", "Right"};

    // 存储路径
    private List<String> path = new ArrayList<>();

    // 深度优先搜索算法
    public boolean dfs(int[][] grid, int x, int y, boolean[][] visited) {
        int rows = grid.length;
        int cols = grid[0].length;

        // 边界条件:检查是否越界,是否遇到障碍物,是否已访问
        if (x < 0 || y < 0 || x >= rows || y >= cols || grid[x][y] == 0 || visited[x][y]) {
            return false;
        }

        // 如果到达终点位置,路径规划成功
        if (x == rows - 1 && y == cols - 1) {
            path.add("(" + x + "," + y + ")");
            return true;
        }

        // 标记当前节点为已访问
        visited[x][y] = true;
        path.add("(" + x + "," + y + ")");

        // 遍历四个方向进行递归搜索
        for (int i = 0; i < 4; i++) {
            int newX = x + DX[i];
            int newY = y + DY[i];
            if (dfs(grid, newX, newY, visited)) {
                path.add(DIRECTION[i]);
                return true;
            }
        }

        // 回溯:撤销当前路径点的访问
        path.remove(path.size() - 1);
        visited[x][y] = false;
        return false;
    }

    public List<String> findPath(int[][] grid) {
        int rows = grid.length;
        int cols = grid[0].length;
        boolean[][] visited = new boolean[rows][cols];

        if (dfs(grid, 0, 0, visited)) {
            return path;
        } else {
            path.add("No Path Found");
            return path;
        }
    }

    public static void main(String[] args) {
        int[][] grid = {
                {1, 0, 0, 0},
                {1, 1, 0, 1},
                {0, 1, 1, 0},
                {1, 0, 1, 1}
        };

        RobotPathPlanner planner = new RobotPathPlanner();
        List<String> path = planner.findPath(grid);

        System.out.println("规划路径:");
        for (String step : path) {
            System.out.println(step);
        }
    }
}

来解释一下代码

  1. 方向定义DXDY分别代表在网格上移动的方向数组,DIRECTION数组用于记录方向名称,便于输出路径。
  2. DFS递归搜索dfs方法从指定位置(x, y)开始搜索,检查越界、障碍物和访问状态。
  3. 终点判断:到达终点时返回true,并将路径记录到path列表。
  4. 回溯:如果当前路径无效,则回溯并撤销该路径点的访问状态。
  5. 路径输出:主函数findPath调用dfs,并根据DFS结果返回路径或“未找到路径”的提示。

机器人路径规划:在仓储物流中,机器人需要规划从起点到指定位置的路径,避开障碍物(如货架),通过DFS可以找到一条可行的路径。

无人机飞行路径规划:在室内或复杂地形中,无人机可以通过DFS找到安全飞行路线,避开障碍物,确保抵达目的地。DFS适用于场地相对较小且只需找到一条路径的场景。

3. 最后的注意事项

  1. 性能:在较大区域或复杂地形中,DFS可能导致大量回溯。可以用A*或Dijkstra等启发式算法优化。
  2. 障碍动态性:如果障碍物可能移动,可以定期重新规划路径。

关注威哥爱编程,编码路上V哥陪你不寂寞。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容