C ++中矩阵的BFS(广度优先搜索)

时间:2016-12-11 18:11:16

标签: c++ matrix queue breadth-first-search

我正在进行以下任务:

编写广度优先搜索软件,从A到B,C,D,E,F并比较算法的特征。

这些字母放在一个矩阵中,由class Matrix制作。 形成矩阵的每个元素都是class Node的对象,以便能够存储信息bool visited,位置int r, int k(分别为行,列)和char value

我甚至可以在矩阵中找到一个字符并返回它的位置,但我不知道如何通过广度优先搜索从字符到字符进行搜索。我的最后一次尝试是在BFS.cpp,但我看到使用队列可能是我应该做的而不是这个。

  

如何以字符矩阵从char A到char B?

以下是代码:(遗憾的是巨额)

  

的main.cpp

#include <iostream>
#include "Matrix.h"
#include "BFS.h"

using namespace std;


int main()
{
    cout << "Hello world!" << endl;

    {

    //make matrix
    Matrix matrix1 ;
    cout<<"matrix1"<<endl<<matrix1<<endl;
    matrix1.findNode('A');
    matrix1.findNode('B');
    BFS bfs1('A',matrix1,0) ;

    }

    cout << "Bye world!" << endl;

    return 0;
}
  

Matrix.h

#ifndef MATRIX_H
#define MATRIX_H
#include "Node.h"
#include <iostream>

using namespace std ;

class Matrix
{
    int size = 6 ;
    Node** matrix ;
    public:
        Matrix();
        virtual ~Matrix();

        friend ostream& operator<<(ostream& out, Matrix &p) ;
        Node& findNode(char _A) ;


    protected:

    private:
};

#endif // MATRIX_H
  

Matrix.cpp

#include "Matrix.h"

Matrix::Matrix()
{
    //ctor
    matrix = new Node*[size];
    for(int r=0; r<size; r++){
            matrix[r] = new Node[size];
    }

    // correct positions of nodes
    for(int r=0; r<size; r++)
    {
        for(int k = 0; k<size;k++)
        {
            matrix[r][k].setPos(r,k) ;
        }
    }
    // Now set characters A t/m F in fixed position
    matrix[2][2].setValue('A') ;
    matrix[0][0].setValue('B') ;
    matrix[0][2].setValue('C') ;
    matrix[4][1].setValue('D') ;
    matrix[5][5].setValue('E') ;
    matrix[5][0].setValue('F') ;
}

Matrix::~Matrix()
{
    //dtor
    for(int r=0; r<size; r++){
        delete [] matrix[r];
    }
    delete [] matrix ;
}

ostream& operator<<(ostream& out, Matrix &p)
{
    for(size_t r=0; r<p.size; r++)
    {
        for(size_t k = 0; k<p.size;k++)
        {
            out<<p.matrix[r][k].getValue()<<"  " ;
        }
        out<<endl ;
    }
    out<<"____________________________"<<endl;
}

Node& Matrix::findNode(char _A)
{
    bool found = false ;
    Node ans ;
    for(int r=0; r<size; r++)
    {
        for(int k = 0; k<size;k++)
        {
            if( matrix[r][k].getValue() == _A )
            {
                ans = matrix[r][k] ;
                found = true ;
                break ;
            }
        }
    }
    cout<<"Search for "<<_A<<" results:";
    if (found)
    {
        cout<<" found: "<<ans<<endl ;
        return ans ;
    }
    else
    {
        cout<<" not found."<<endl ;
    }

}
  

Node.h

#ifndef NODE_H
#define NODE_H
#include <iostream>

using namespace std;

class Node // ctor, dtor, operator=, operator<<, setPos, setState, setValue
{
    int r ; int k ; //row nr and column nr,  because used in BFS
    bool visited ;
    char value ;
    public:
        Node(int _r = 0, int _k = 0,char _value = '_', bool _visited = false);
        virtual ~Node();
        Node& operator=(const Node &p);

        friend ostream& operator<<(ostream& out, Node &p);

        void setPos(int _r, int _k);
        void setState(bool _visited);
        void setValue(char _value);
        char getValue();

    protected:

    private:
};


#endif // NODE_H
  

Node.cpp

#include "Node.h"

// all this code is integrated in Node.h

Node::Node(int _r, int _k,char _value, bool _visited)
{
    //ctor
    // defaults specified in Node.h : 0 0 _ false
    r = _r ; k = _k ; value = _value ; visited = _visited ;
}

Node::~Node()
{
    //dtor
}

Node& Node::operator=(const Node &p)
{
    r = p.r ; k = p.k ; value = p.value ; visited = p.visited ;
};

ostream& operator<<(ostream& out, Node &p)
{
    out<<"["<<p.r<<"]["<<p.k<<"] has value '"<<p.value<<"'" ;
};

void Node::setPos(int _r, int _k)
{
    r = _r ; k = _k ;
};

void Node::setState(bool _visited)
{
    visited = _visited ;
};

void Node::setValue(char _value)
{
    value = _value ;
};

char Node::getValue()
{
    return value ;
};
  

BFS.h

#ifndef BFS_H
#define BFS_H
#include <vector>
#include "Matrix.h"
#include "Node.h"

    //BFS algorithm:
    /*
    Step 1: Push the root node in the Stack.
Step 2: Loop until stack is empty.
Step 3: Peek the node of the stack.
Step 4: If the node has unvisited child nodes, get the unvisited child node, mark it as traversed and push it on stack.
Step 5: If the node does not have any unvisited child nodes, pop the node from the stack.

    */

    // object of class BFS should be the queue of nodes to be checked

//class Node ; class Matrix ;

class BFS
{
    //queue<Node> queueNodes;
    vector<Node> fronts ;

    public:
        BFS(char _start, Matrix _matrix, int _distance);
        virtual ~BFS();

        friend bool& isPresent(vector<Node> _vector , Node& _n) ;

    protected:

    private:
};

#endif // BFS_H
  

BFS.cpp

#include "BFS.h"


BFS::BFS(char _start, Matrix _matrix, int _distance)
{
    //ctor; form que
    //determine startpoint
    vector<Node> newfronts ;

    fronts.push_back(_matrix.findNode(_start)) ;

    cout<<"BFS made"<<endl;
    for(int i = 0 ; i < _distance ; i++)
    {
        // determine the new fronts
        for(size_t f = 0 ; f < sizeof(fronts) ; f++)
        {
            // do only if new item is not in newfronts OR fronts yet AND if does not exceed matrix dimensions
            if ( fronts[f].r - 1 !< 0 )
            {
                Node up = _matrix[fronts[f].r - 1][fronts[f].k] ;
                if ( ! isPresent(fronts, up) && ! isPresent(newfronts, up) )
                {
                    newfronts.push_back(up) ;
                }

            }
            if ( fronts[f].r + 1 !> _matrix.size )
            {
                Node down = _matrix[fronts[f].r + 1][fronts[f].k] ;
                newfronts.push_back(down) ;
            }
            if ( fronts[f].k + 1 !> _matrix.size )
            {
                Node right = _matrix[fronts[f].r][fronts[f].k + 1] ;
                newfronts.push_back(right) ;
            }
            if ( fronts[f].k - 1 !< 0 )
            {
                Node left = _matrix[fronts[f].r][fronts[f].k - 1] ;
                newfronts.push_back(left) ;
            }
       }

    }
}

BFS::~BFS()
{
    //dtor
}

bool isPresent(vector<Node> _vector , Node& _n)
{
    bool present = false ;
    for(size_t i = 0 ; i < sizeof(_vector) ; i++)
    {
        if( _vector[i] == _n)
            present = true ;
    }

    return present ;
}

如果你一直管理到这里,已经感谢你的时间了。 : - )

1 个答案:

答案 0 :(得分:0)

你是对的,你需要一个广度优先搜索队列,以及深度优先搜索的堆栈,这是两者之间的主要区别。

首先,我个人会在你的矩阵中添加一个名为get neighbors的函数来获取一个单元格的邻居,然后像这样编码BFS。

使用它你可以简单地写一个BFS函数。

BFS::BFS(char _start, char goal, Matrix _matrix, int _distance)
{
    Queue<Node> Frontier ;

    Frontier.push_back(_matrix.findNode(_start));

    cout << "BFS beginning" << endl;

    int count = 0;

    while(count < _distance)
    {
        Node lCurrent = Frontier.front();
        Frontier.pop();

        if( lCurrent.getValue() == goal )
        {
            cout << "Goal Found" << endl;
            cout << "Number of steps taken: "  << count << endl;
            return;
        }

        vector<node> currentNeighbors() = lCurrent.getNeighbors();

        for (size_t i = lNeighbours.size(); i > 0; i--)
        {
            Frontier.push(lNeighbours[i-1]);
        }

    }  
    cout << "Maximum distance of " << _distance << " with no    solution found, BFS aborted." << endl;


}

您可能需要稍微调整一下以适应您的程序,并注意此解决方案不会维护受访节点的列表,因此您可以跳过已经评估过的一些节点。