Вопрос

It's a homework. I have to design and lights out game using backtracking description is below.

The game consists of a 5-by-5 grid of lights; when the game starts, a set of these lights (random, or one of a set of stored puzzle patterns) are switched on. Pressing one of the lights will toggle it, and the four lights adjacent to it, on and off. (Diagonal neighbours are not affected.) The game provides a puzzle: given some initial configuration where some lights are on and some are off, the goal is to switch all the lights off, preferably in as few button presses as possible.

My approach is go from 1 to 25 and check if all the lights are off or not. If not then I will check for 1 to 24 and so on until I reach 1 or found solution. No if there is no solution then I will start from 2 to 24 and follow the above process till I reach 2 or found solution.

But through this I am not getting the result ? for example light at (0,0) (1,1) (2,2) (3,3) (4,4) are ON?

If any one need code I can post it.

Can any one tell me correct approach using backtracking to solve this game ?

Thanks.

Это было полезно?

Решение

There is a standard algorithm for solving this problem that is based on Gaussian elimination over GF(2). The idea is to set up a matrix representing the button presses a column vector representing the lights and then to use standard matrix simplification techniques to determine which buttons to press. It runs in polynomial time and does not require any backtracking.

I have an implementation of this algorithm that includes a mathematical description of how it works available on my personal site. I hope you find it useful!

Edit: If you are forced to use backtracking, you can use the following facts to do so:

  • Any solution will never push the same button twice, since doing so would cancel out a previous move.
  • Any solution either pushes the first button or does not.

Given this approach, you could solve this using backtracking using a simple recursive algorithm that keeps track of the current state of the board and which buttons you've already made decisions about:

  • If you've decided about each button, then return whether the board is solved or not.
  • Otherwise:
    • Try pushing the next button and seeing if the board is recursively solvable from there.
    • If so, return success.
    • Otherwise, try not pushing the next button and seeing if the board is recursively solvable from there.
    • If so, return success. If not, return failure.

This will explore a search space of size 225, which is about 32 million. That's big, but not insurmountably big.

Hope this helps!

Другие советы

Backtracking means:

Incrementally build a solution, throwing away impossible solutions.

Here is one approach using the fact that there is locality of inputs and outputs (pressing a button affects square around it).

problem = GIVEN
solutions = [[0],[1]] // array of binary matrix answers (two entries, a zero and a one)
for (problemSize = 1; problemSize <= 5; problemSize++) {
    newSolutions = [];
    foreach (solutions as oldSolution) {
        candidateSolutions = arrayOfNByNMatriciesWithMatrixAtTopLeft(min(5,problemSize+1), oldSolution);
        // size of candidateSolutions is 2^((problemSize+1)^2 - problemSize^2)
        // except last round candidateSolutions == solutions
        foreach (candidateSolutions as candidateSolution) {
            candidateProblem = boardFromPressingButtonsInSolution(candidateSolution);
            if (compareMatrix(problem, candidateProblem, 0, 0, problemSize, problemSize)==0)
                newSolutions[] = candidateSolution;
        }
    }
    solutions = newSolutions;
}
return solutions;

As already suggested, you should first form a set of simultaneous equations.

First thing to note is that a particular light button shall be pressed at most once because it does not make sense to toggle the set of lights twice.

Let Aij = Light ij Toggled { Aij = 0 or 1 }

There shall be 25 such variables.

Now for each of the lights, you can form an equation looking like

summation (Amn) = 0. { Amn = 5 light buttons that toggle the light mn }

So you will have 25 variables and 25 unknowns. You can solve these equations simultaneously.

If you need to solve it using backtracking or recursion you can solve the equations that way. Just assume an initial value of variables, see if they satisfy all the equations. If not, then back track.

The Naive Solution

First, you're going to need a way to represent the state of the board and a stack to store all of the states. At each step, make a copy of the board, changed to the new state. Compare that state to all states of the board you've encountered so far. If you haven't seen it, push that state on top of the stack and move on to the next move. If you have seen it, try the next move. Each level will have to try all possible 64 moves before popping the state from the stack (backtracking). You will want to use recursion to manage the state of the next move to check.

There are at most 264 possible board configurations, meaning you could potentially go on a very long chain of unique states and still run out of memory. (For reference, 1 GB is 230 bytes and you need a minimum of 8 bytes to store the board configuration) This algorithm is not likely to terminate in the lifetime of the known universe.

You need to do something clever to reduce your search space...

Greedy-First Search

You can do better by searching the states that are closest to the solved configuration first. At each step, sort the possible moves in order from most lights off to least lights off. Iterate in that order. This should work reasonably well but is not guaranteed to get the optimal solution.

Not All Lights-Out Puzzles Are Solvable

No matter what algorithm you use, there may not be a solution, meaning you might search forever (or several trillion years, at least) without finding a solution.

You will want to check the board for solvability (which is a much faster algorithm as it turns out) before wasting any time trying to find a solution.

I made a concise optimizing solver using Answer Set Programming. See: https://github.com/jachymb/lights-out

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top