views:

81

answers:

2

I'm trying to create a method (using the A* algorithm) that solves a puzzle and returns the steps to that solution. The solution it's easy.. but I can't return the path to that.

I used a list of Nodes and then every time a push back a new Node I set the parent pointing to the Node which new came;

list<Node> opened;
list<Node> closed;

Node current;

opened.push_back(start);

while( opened.size() !=0 )
{
   current = getLowestCostPath(opened);


   if(IsSolution(current) == true)
       return opened;

   opened.remove(current);

   if( !Has(closed, current))
          closed.push_back(current);


   for( int i = 0; i < static_cast<int>(current.GetBoard().capacity()); i++ ) 
   {   
   xx = current.GetBoard()[i].X();
   yy = current.GetBoard()[i].Y();

       for(int j = 0; j < static_cast<int>(current.GetBoard().capacity()); j++) 
       {
            if( isMovable(current))
            {
                //if found a new node
                Node newNode = Node(newBoard);
                Node *t = &current;

                if(!Has(opened, newNode ) && !Has(closed, newNode ) )
                {
                   newNode.SetParent(t);
                   opened.push_back(newPath);
                }
            }
        }
    }
}

(..)

the class Node it's just this

class Node{

public:
   std::vector<Point> board;
   Path *parent;

   Node();
   Node(std::vector<Point> board)

   virtual std::vector<Point> GetBoard() const;
   virtual Path* GetParent() const;
   virtual void SetParent(Node *p); 

Node::Node(): board(),parent(NULL)
{
}

std::vector<Point> Node::GetBoard() const
{
return board;
}

void Path::SetParent(Node *p)
{
    this->parent = p;
}

Path* Path::GetParent() const
{
    return parent;
}

But then I realized that I can't BUILD the path to solve the puzzle...

I can't even see a single Parent board...

for( list<Node>::iterator it = goal.begin(); it != goal.end(); it++)
{
    if( (*it).GetParent() != NULL ){
        cout << "writing a board" << endl;
        mas::WriteLine( (*it).GetParent()->GetBoard() , "\n");
    }
}

I've searched all over the internet and I can't realize what am I doing wrong :(


I also tried this but it makes VS2005 Crash.

//goal it's the opened list that the method Solve returned....

for(std::list<Node>::iterator it = goal.end(); it->GetParent() != NULL; t->GetParent())
{

    std::cout << "step" << std::endl;
    mas::WriteLine((*it).GetBoard(), "\n");
}
A: 

your volume of code require deeper investigation, but basically what i see that you trace back your way incorrectly. assume n is your final node. then return back like this

for (; n->GetParent() != NULL; n = n->GetParent())
  //do something on each node

after this executes n will be the initial node

Andrey
i tried this... but it makes the VS2005 crash.for(std::list<Path>::iterator it = goal.end(); it->GetParent() != NULL; it->GetParent()){ std::cout << "step" << std::endl; mas::WriteLine((*it).GetBoard(), "\n");}
DanceDisaster
@DanceDisaster: list::end() points one behind the last element of the list. Dereferencing it is undefined behaviour.
pmr
@DanceDisaster: just use the code i wrote and copy-paste errors.
Andrey
std::list<Node>::iterator it = --goal.end();mas::WriteLine( it->GetBoard(), "\n");Using this code I can print the last Node, but I says tha it->GetParent() it's NULL... so the set of the Parent it's wrong!
DanceDisaster
I think that t it's pointing to current... when it should be pointing to the element on the list (which current it's assigned to)... Is this true? I need a little help, please!
DanceDisaster
i don't understand your comments, sorry. please try to explain them
Andrey
My error it's probably on setting the parent. On this particular part of the code: Node newNode = Node(newBoard); Node *t = I think I'm pointing to an temporary variable when it should be pointing to a value on the list open. Is it more clear now? sorry!
DanceDisaster
sorry, not much clearer :)
Andrey
I am going to write an answer... I'm sure it will be more clear.
DanceDisaster
A: 

I'm trying to be more clear and objective. So... see this parts

current = getLowestCostPath(opened);

The value returned by the method getLowestCostPath came from:

Node Solution::getLowestCostPath( std::list<Node> l)
{
    std::list<Node>::reverse_iterator min = l.rbegin();
    int value = 0;
    for(std::list<Node>::reverse_iterator it = l.rbegin(); it != l.rend(); it++)
    {
        if( value < (*it).GetStep())
        {   
            min = it;
            value = (*it).GetStep();
        }
    }
    return *min;
}

after that... on the method Solve.. there is this part of the code

//if found a new node
Node newNode = Node(newBoard);
Node *t = &current;

newPath.SetParent(t);

I think that the ERROR it's on this part, newPath it's pointing to t when it should be pointing to node on the list opened

Is it true? If it is.. how can I fix this?

DanceDisaster