迷宫解决matlab中的广度优先搜索算法

时间:2015-10-09 22:17:29

标签: matlab matrix breadth-first-search

我正在尝试实施广度优先算法,它解决了迷宫问题。作为输入,我有一个n * m二进制矩阵,其中' 1'代表障碍物/墙壁和' 0'对于路径/自由细胞。

我在如何在matlab中存储和处理信息方面苦苦挣扎。所以基本上我从我的起始单元开始,并检查所有它的直接邻居的障碍。如果它们是空闲的,我将它们标记为潜在路径,然后我再次对所有这些单元格进行相同的处理。

如果有人有想法,请帮助我。

1 个答案:

答案 0 :(得分:0)

听起来你已经知道如何实现算法,但请查看Djikstra的算法,找出解决问题的简单方法。

对于MATLAB,我只使用一系列矩阵来表示每个单元格的信息。使用Djikstra算法,您可以从单个开放节点开始,检查其邻居并计算每个节点的路径成本,然后以最低成本转移到邻居。诀窍是将您访问过的节点设置为关闭,设置您已检查打开的邻居,并将未经检查的节点保留为未知。

这是我的代码,它基于障碍物的图像运行,其中自由细胞是白色的,障碍细胞是黑色的。因此,您可以打开一个简单的绘图程序,如MSPaint,并非常容易地绘制地图。然后只需相应地更改代码顶部的文件名。

您可以看到变量open_map的使用,其中包含每个节点的值,可以是:

1 - 打开

0 - 未经访问

-1 - 关闭

-2 - 障碍物(在算法方面与-1相同,但-2对绘图很方便)

% read map file
map_file = 'obstacle_map.png';
obstacleMap = imread(map_file);
obstacleMap = 1 - obstacleMap(:,:,1)';

% get map size
Ni = size(obstacleMap,1);
Nj = size(obstacleMap,2);

% set initial position node
i0 = 1;
j0 = 1;

% set target position node
iTrg = Ni;
jTrg = Nj;

% initialize open node map, and close obstacle nodes
open_map = zeros(Ni,Nj);
open_map = open_map - 2*double(obstacleMap);

% initialize best score map
f_score = 0*ones(Ni,Nj);

% initialize previous node maps
Iprev = zeros(Ni,Nj);
Jprev = zeros(Ni,Nj);

% start open map with initial position node open
open_map(i0,j0) = 1;
is_open = 1;

% skip this many frames during plotting
Ngtf = 100;

% keep searching while there are open nodes
count = 0;
while is_open > 0;

    % loop counter
    count = count + 1;

    % find open node with the lowest score
    F_score = f_score + (1e9)*(open_map ~= 1);      % take the scores and add some big number to nodes that aren't open
    [ic,jc] = find(F_score == min(min(F_score)));

    % we might have more than one with the lowest score, so just take the
    % first candidate
    ic = ic(1);
    jc = jc(1);    

    % exit if we reach the target node
    if (ic == iTrg) && (jc == jTrg);
        break;
    end

    % set the current node to be closed
    open_map(ic,jc) = -1;

    % for each neighbour of the current node
    for i = (ic-1):(ic+1);

        % don't try checking neighbours out of bounds
        if i < 1 || i > Ni;
            continue;
        end

        for j = (jc-1):(jc+1);

            % don't try checking neighbours out of bounds
            if j < 1 || j > Nj;
                continue;
            end

            % skip if the neighbour has already been visited (i.e., it is
            % closed)
            if open_map(i,j) < 0;
                continue;
            end

            % compute the new best score to the neighbour (the best
            % score to the current node plus the distance to the neighbour
            % node from the currend node)
            f_score_new = f_score(ic,jc) + sqrt((i - ic)^2 + (j - jc)^2);

            % if the new best score is less than the previous best score
            % for the neighbour node, or the neighbour node has never been
            % checked
            if open_map(i,j) ~= 1 || f_score_new < f_score(i,j);

                % set the previous node indices (keep track of the actual
                % path)
                Iprev(i,j) = ic;
                Jprev(i,j) = jc;

                % update the new score
                f_score(i,j) = f_score_new;

                % set the neighbour node to be open
                open_map(i,j) = 1;
            end

        end
    end

    % plotting
    curr_map = open_map;
    curr_map(ic,jc) = 2;
    if mod(count,Ngtf) == 0;
        clf;
        surf(curr_map,'edgealpha',0);
        axis equal
        view(2)
        getframe;
    end

    % check how many nodes are open
    is_open = sum(sum(open_map == 1));

end

% final plotting map
final_map = open_map;

% final node
iF = ic;
jF = jc;

% backtrack through the list of previous nodes to construct the final path
ipath = [];
jpath = [];
while 1;
    final_map(iF,jF) = 2;
    if iF == i0 && jF == j0;
        break;
    end
    iprev = Iprev(iF,jF);
    jprev = Jprev(iF,jF);
    ipath = [iprev ipath];
    jpath = [jprev jpath];
    iF = iprev;
    jF = jprev;     
end


clf;
surf(final_map,'edgealpha',0);
hold on;
plot3(jpath,ipath,100000*ones(size(ipath)),'k.-');
axis equal
view(2)