c++out-of-memorybreadth-first-searchrubiks-cube

Why BFS algorithm doesn't always find solution of rubick's cube?


I'm tring to write rubick's cube solver based on BFS algorithm. It finds way if there's one shuffle done (one wall moved). There's problem with memory when I'm doing more complicated shuffe.

I have written cube, so one can does moves on it, so the moves work well. I'm checking if the cube is solve by comparing it with the new one (not shuffle). I know it's not perfect, but it should work anyway...

theres some code:

void search(Node &problem)
{
    int flag;
    Node *curr;
    Node* mvs[12]; //moves
    std::vector<Cube> explored; //list of position cube's already been in
    std::queue<Node*> Q; //queue of possible ways 
    if (problem.isgoal() == true) return problem.state;
    Q.push(&problem);
    explored.push_back(problem.state);
    while (!Q.empty())
    {
        flag = 0;
        curr = Q.front();
        if (curr->isgoal() == true)
        {
            return curr->state;
        }
        if (std::find(explored.begin(), explored.end(), curr->state)!=explored.end()) //checking if cube's been in curr position
        {
            flag = 1;
            break;
        }
        if (flag == 1) break;
        explored.push_back(Q.front()->state);
        for (int i = 0; i < 12; i++) {
            Q.push(curr->expand(i)); //expand is method that 
                        //spread tree of possible moves from curr node
        }
        Q.pop();
    }
}

Solution

  • TLDR; Too Broad.

    As mentioned by @tarkmeper, rubik's cube have a huge number of combinations.
    A simple shuffling algorithm will not give you an answer. I would suggest you to make algorithms which solve cube based on it's initial state. As I solve the cube myself, there are 2 basic methods:
    1. Solve the cube layer by layer which is beginner's method https://www.youtube.com/watch?v=MaltgJGz-dU
    2. CFOP(Cross F2l(First 2 Layers) OLL PLL(oll, pll are algorithms))
    https://www.youtube.com/watch?v=WzE7SyDB8vA (Pretty advanced)
    There have been machines developed to solve the cube but they take input as images of the cube.

    I think implementing CFOP could actually solve your issue as it does not check for random shuffles of the cube but actually solves it systematically, but it would be very difficult.

    For your implementation it would be much better to take data as a matrix.
    A rubik's cube has 3 parts: 1. Center(1 Color) 2. Edge(2 Color) 3.Corner (3 Color)
    There are 6 centers 12 egdes 8 corners. You would also have to take into account valid initial states as you cannot randomize it.
    What I could think up right now about a problem of this scale is to make 4 algorithms:

    Cross():
    .... which takes the cube and makes the cross which is basically all white edges
    aligned to white center and their 2nd colored center.
    F2L():
    .... to make 2nd layers of the cube with the corner pieces of the first layer,
    this could use backtracking as there are lot of invalid case occurences
    OLL():
    .... based on your state of cube after F2L transformation there is a straight
    forward set of moves, Same for PLL():
    

    Getting to the bare bones of the cube itself:
    You would also need to implement moves which are F, F', R, R', L, L', B, B'.
    These are moves on the cube the ones with " ' " denote moving that face in anticlockwise direction with respect to the current face of the cube you are looking at.
    Imagine you are holding the cube, F is for front in clockwise, R is right in clockwise, L is left in clockwise, B is back in clockwise.