人工智能: 自动寻路算法实现(一、广度优先搜索)

本文介绍了扫地机器人利用广度优先搜索(BFS)算法进行自动寻路的方法,以找到清理灰尘的最短路径。通过建立坐标点、节点类和算法实现类,确保机器人不会走回头路,始终寻找最优解。BFS算法的特点是找到的解一定是最优解,但当深度较大时,空间复杂度较高。下篇文章将探讨深度优先搜索算法。

前言

随着人工智能技术的日益发达,我们的生活中也出现了越来越多的智能产品。我们今天要关注的是智能家居中的一员:扫地机器人。智能扫地机器人可以在主人不在家的情况下自动检测到地面上的灰尘,并且进行清扫。有些更为对路线进行规划,找到可以清理灰尘的最短路径,达到省电的效果。当然,绕过障碍物也是必须拥有的技能。我们今天就来看一下扫地机器人自动寻路的算法的简单实现。这里我们不对机器人如何识别出灰尘进行讨论,我们只讨论发现了灰尘之后,机器人的路径规划进行一个分析。为了简单起见,我们假设机器人所处在的是一个M×N的格子的房间中,其中某些格子是灰尘,某些格子是障碍物,而另外有些格子则是单纯的空地。
我们再抽象一些,设星号(*)表示灰尘,井号(#)表示障碍物,下划线(_)表示空地,而我们的机器人所在的初始格子(当然首先要是一块空地)用at(@)表示。比如如下的图示

*#_*
_*__
_#_@

表示在一个3×4的空间内(俯视图),第一行有两个灰尘和一个障碍物,第二行有一个障碍物,第三行有一个障碍物, 而我们的机器人在右下角这个位置。它的目标就是在不经过任何障碍物的格子的情况下,用尽量少的步数,把房间中的灰尘都清除掉。我们假设机器人每次行动一个格子会消耗一点的行动力,当机器人处在灰尘所在的格子上时,清除这个格子里面的灰尘也消耗一点行动力。

项目下载地址

正文

问题分析

广度优先搜索(breadth-first search)是解决自动寻路功能的算法之一。作为一种常见的图形搜索算法,它也被广泛应用于解决其他各类算法问题。一般情况下,对于一个节点,它的邻居节点的集合被称作open list,而在这个节点被遍历之前,其他所有已经遍历过的节点存于close list中。
算法描述如下:

开始
将顶点入队列
循环  
    当队列为非空时,继续执行,否则算法结束
    出队列取得队列头顶点V;访问并标记为已访问
    查找列头顶点V的所有邻接顶点W1,W2,...Wn
    对于上述的所有每一个顶点Wn
    循环
          若Wn在close list中, 则继续遍历下一个顶点Wn+1
          否则将Wn入队列,并加入到close list

代码

首先我们建立一个坐标点的类,用于表示一个点的坐标。

public class Point {
   
   
    private int X;
    private int Y;

    public Point(int x, int y){
        this.X = x;
        this.Y = y;
    }

    public int getX() {
        return X;
    }
    public void setX(int x) {
        X = x;
    }
    public int getY() {
        return Y;
    }
    public void setY(int y) {
        Y = y;
    }

    //判断两个点是否坐标相同
    public static boolean isSamePoint(Point point1, Point point2){
        if(point1.getX() == point2.getX() && point1.getY() == point2.getY())
            return true;
        return false;
    }

}

接下来就是比较重要的节点类,这里我们用state表示,state的意思为状态,也可以理解为当前屋子里的一个状态,比如当前的节点下我们的机器人的位置、房间内剩余的灰尘格子数量等等。

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

public class State {
   
   
    //机器人位置
    private Point robotLocation;

    //操作,分为N(向上移动一格), S(向下移动一格), W(向左移动一格), E(向右移动一格)以及C(清理灰尘)
    private String operation;

    //当前节点的父节点, 用于达到目标后进行回溯
    private State previousState;

    //灰尘所在坐标的list
    private List<Point> dirtList;

    public Point getRobotLocation() {
        return robotLocation;
    }

    public void setRobotLocation(Point robotLocation) {
        this.robotLocation = robotLocation;
    }

    public String getOperation() {
        return operation;
    }

    public void setOperation(String operation) {
        this.operation = operation;
    }

    public State getPreviousState() {
        return previousState;
    }

    public void setPreviousState(State previousState) {
        this.previousState = previousState;
    }

    public List<Point> getDirtList() {
        return dirtList;
    }

    public void setDirtList(List<Point> dirtList) {
        this.dirtList = new ArrayList<Point>();
        for(Point point : dirtList){
            this.dirtList.add(point);
        }
    }

    //用于判断两个节点是否相同
    public static boolean isSameState(State state1, State state2){
        //若机器人位置不同,则节点不同
        if(!Point.isSamePoint(state1.getRobotLocation(), state2.getRobotLocation()))
            return false;
        //若灰尘列表长度不同, 则节点不同
        else 
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值