How to caculate the probability of this cell is mine - algorithm

the unknown one blue marked
it's 3/5? 1/3? 2/5? or max value of above, or maybe another(I think this...)?
how to caculate? it confuses me very much...

It's actually 1/2.
Note that there must be at least two mines in the three cells below 3 (because the other two cells are adjacent to a 1 and as such can't have more than 1 mine).
This means that there must be at least one mine between the cell below the 3 and cell to the bottom right of 3. Since both of these are also adjacent to a 1, only one of them can have mine at most. Thus, exactly one of these cells is a mine. The 2 on the right becomes irrelevant at this point.
With that out of the way, is there a general algorithm which can generate results like these?
I can't thing of any polynomial time solutions but it might be possible to simple try all the alternatives while backtracking when a constraint fails.

Related

N queen (algorithm) via array not understanding few lines

http://jeffe.cs.illinois.edu/teaching/algorithms/notes/03-backtracking.pdf
enter image description here
explain the highlighted texted of image
Q[i]=j Q[i]=j+r-i Q[i]=j-r+i
how these statements check if two queen attack in row column or diagonals?
That's a better solution than I came up with many years ago when I beat the obvious algorithm by an order of magnitude.
Fundamentally, what this is doing is instead of maintaining a board and checking the three paths that a queen can move (you only need to look behind the queen--it's the only queen on the row so you know that direction is clear an the queens ahead haven't been placed yet) which requires checking (row - 1) * 3 cells (although some are off the board, it may be cheaper to test the diagonals for bounds first) it's maintaining a one dimensional array of queens and noting what they threaten. This reduces each placement test to 3 squares. (And uses only addition, no multiplication. Irrelevant now, a considerable time savings when I was playing with this.)
I haven't looked over the whole thing to see how they are doing it with one array rather than the three I did it with (column threatened, / diagonal threatened, \ diagonal threatened. The latter arrays are twice as big.)

What can be a possible algorithm for this combinatorics based program?

So, this contest is already over.
I was trying to solve this problem: http://codeforces.com/contest/554/problem/C
I spent like 1 hour to solve this problem. What I thought was, fill the last n positions of the array with one ball of each kind. Then, in the remaining positions, find the permutations by calculating remaining places in array divided by balls of each kind - 1 (since one is fixed at last position). This will obviously miss out on a lot of test cases, since I don't consider cases when 2 largest numbers will be together in the end or 3 largest numbers will be there. Similarly, along with 4 numbers, other similar numbers might be there before them. But I mean, I am not able to think of a approach how should I solve this?
Any inputs will be greatly appreciated. Thanks!
Also, the contest has already ended, so no issues there. :)
Hints
Consider the example given where we have 1,2,3,4 balls of each colour.
Place the first ball: 1 option.
Now consider placing the 2 balls of the next colour. Place one at any position (2 choices - either before or after the first ball), then place the second at the end.
Now consider placing the 3 balls of the next colour. Place two at any position C(1+2+2,2), and the last at the end.
Finally consider placing the 4 balls of the final colour. Place three at any position C(1+2+3+3,3), and the last at the end.
This gives 1680 choices.

Why is the state space the power set of the grid's dimensions? (edX CS 188.1x Artificial Intelligence)

I'm self-learning with the edX course CS 188.1x Artificial Intelligence. Since the course concluded a year ago, it is in "archive mode" and there are no teaching staff to help with the questions. This also means I get no credit for finishing the course, so hopefully asking for help with a "homework" question here is okay.
In the first homework assignment the following question is asked:
Question 9: Hive Minds Lost at Night It is night and you control a single insect. You know the maze, but you do not know what square the
insect will start in. You must pose a search problem whose solution is
an all-purpose sequence of actions such that, after executing those
actions, the insect will be on the exit square, regardless of initial
position. The insect executes the actions mindlessly and does not know
whether its moves succeed: if it uses an action which would move it in
a blocked direction, it will stay where it is. For example, in the
maze below, moving right twice guarantees that the insect will be at
the exit regardless of its starting position.
It then asks the size of the state space. The answer is given as 2^MN, where M and N are the horizontal and vertical dimensions of the maze. Why is the answer the power set of MN? In my mind, the bug can only be in one square at the beginning, and we only have one bug, so I know the number of start states is MN. But the number of start states != state space, and that is where I am confused.
FYI - the cost per move is 1, and the bug can only move 1 square left, right, up, or down at a time. The goal is to get to the X (goal square).
Okay - I think I got it.
Set of all subsets (power set*) is exactly the right way to think about this. The state space is the set of all states.
1) Definition of state:
"A state contains all of the information necessary to predict the effects of an action and to
determine if it is a goal state." (http://artint.info/html/ArtInt_48.html)
The actions in this scenario are simple: left, right, up, down. They are the possible movements a bug could make.
2) Definition of solution:
Solutions are sequences of actions that lead to the goal test being
passed.
If we only permitted MN states, one for each possible starting position the bug was in, then we would have a state space that gave solutions that were valid only for discrete starting positions. But, the solution must be valid regardless of the initial state of the bug. This means the solution must work for scenarios in which the bug could occupy any of the MN available squares.
In other words, the solutions must be valid for each and every subset (combination) of possible starting spaces, which yields the power set of MN, which is 2^MN.
Why? Because solutions that are valid for a given start state may not be valid for all other start states. And the problem requires us to find solutions that are valid for all start states. This is also why the state space is much larger than MN even though in reality our bug only occupies 1 of the MN positions upon initialization. Just because a solution (sequence of moves) works when the bug starts at (1, 1) doesn't mean that solution (sequence of moves) will also work for the bug starting at (2, 1).
Bonus Question: Why isn't the state space just 1, the full set where
each of the MN squares 'has' a bug (and bugs are permitted to move
on top of each other)?
I was tempted to say that just because a sequence of moves gives a goal state when the bug can start at all of the MN possible positions, that doesn't mean that same sequence of moves gives a goal state when the bug starts at (3, 2) or at MN - 1 or MN - 2 etc. possible positions. But by definition it must (a solution over all starting points must be a solution over every finite subset of starting points).
So I think the reason you evaluate starting states other than "all boxes have a bug" is because the solution generated by evaluating only that state may not be optimal. And in fact this interpretation is borne out by what the homework gives as admissible heuristics for this problem:
The maximum of Manhattan distances to the goal from each possible
location the insect could be in.
OR
The minimum of Manhattan distances to the goal from each possible
location the insect could be in.
The case where we just have one starting state with bugs on all the boxes (with the magic ability to be on top of each other) is the relaxed problem we use to define our heuristic. Again by definition of admissibility, since the heuristic must not overestimate the true (arc) cost of an action, and since arc cost is given by Manhattan distances, both the heuristics above are admissible. (The maximum case is admissible because each possible location for the bug is, in fact, possible - thus the max cost is possible).
*If you don't know what power set means, all you need to know is that the power set is the set of all subsets of a given set. It is given by 2^(size of the set).
In other words, if I have a set of three balls {red, blue, green} and I want to know how many different subsets I have, I can calculate it as follows. A subset either has the element in it (1), or it doesn't (0). So {0, 0, 1} would be the subset of only the green ball, {1, 1, 1} would be the subset of all the balls (yes, technically this is a subset) and {0, 0, 0} would be the subset of none of the balls (again, technically a subset). So we see that the number of all subsets is 2^3 = 8. Or in our problem, 2^MN.

Obtaining the minimum number of tails of coin after flipping the entire row or column multiple times

If coins are placed on a grid and only an entire row or column can be flipped, how can we flip the coins to obtain the minimum number of tails.
I tried to using the greedy solution, in which I flip the row or column where the number of tails are greater than heads and repeat the process until there exists no change on the number. But I found that this approach does not give me an optimal solution in some times.
HHT
THH
THT
For example, if the coins are placed like the above and I flip the coins in below manner, the obtained value is 3 but actually the answer is 2.
1. Flip the row 3
HHT
THH
HTH
2. Then there exists no row or column where the number of tails are greater than that of heads.
3. But if I flip the column 3, row 3, column 1, there exists a solution whose value is 2.
THH
HHT
HHH
So, I think the above algorithm doesn't work. What approach and what algorithm should I use?
First let us notice that there is no point in flipping the same row or column twice or more (a better solution is always either flipping the row/column zero or one time), and the order we flip the rows or columns is irrelevant, so we can describe a solution as a bit array of length 2N. One bit per row and one bit per column. On if we flip that row/column once, off if we flip it zero times.
So we need to search 2^(2N) possible solutions, prefering solutions with more zeros.
Secondly let us notice that for one solution there are four possible states of a coin:
The coin was not flipped (0 flips)
The coin was flipped by its row (1 flip)
The coin was flipped by its column (1 flip)
The coin was flipped by both its row and column (2 flips)
Notice that state 1 and 4 result in the original value of the coin
Also notice that state 2 and 3 result in the opposite of the original value of the coin
Start by expressing the original state of the coins as a binary matrix (B). The 2N-bit field as 2 binary vectors (R, C), and the total number of tails as a function of this f(B, R, C), and the total number of bits as a function g(V_1, V_2)
So your goal is to make f >= minimum while minimizing g.
Think that if we first fix our R configuration (which rows we will flip), how can we solve the problem just for C (which columns we will flip)? Put another way, consider the simpler problem of only being allowed to flip columns, and not being allowed to flip rows. How would you solve this? (hint: DP) Can you extend this stategy back to the full problem now?
Not sure about the complete algorithm, but one thing you should definitely try exploit here are the large number of symmetries in your problem.
A lot of different coin configurations will actually be equivalent, so you can rotate, mirror your configuration without altering the problem. Most importantly, since you can reverse the whole set by flipping all rows, looking for the minimum number of tails is equivalent to looking for the minimum number of heads.
In your case, it would be
HHT
THH
THT
HTT
TTH
TTT
By flipping the middle column, and you're done (you then have to flip everything of course if you really need it).
An obvious solution is to try all possibilities of flipping a row or a column. There are O(2^(2N)) such possibilities. However, we can solve the problem in O(N^2 * 2^N) with a combination of greedy + brute force.
Generate all possibilities of flipping the rows (O(2^N)) and for each of these, flip each column that has more tails than heads. Take the solution that gives you the minimum tails.
This should work. I will add more details about why a bit later.
One approach would be to use http://en.wikipedia.org/wiki/Branch_and_bound, alternately considering new vertical lines and new horizontal lines. There is also some symmetry you can remove - if you flip all the horizontal lines and all the vertical line, you will end up back where you started, so with branch and bound you might as well arbitrarily assume that the leftmost vertical line is never flipped.
HHT
THH
THT
In this example, if we assume that the leftmost vertical line is not flipped, then if we branch on the lowest horizontal line we know the value of the leftmost lowest coin, so we have two possible partial solutions - one in which that single known coin is fixed at tails, and one in which it is fixed at heads. If we recurse first to try and extend the partial solution in which the single known coin is heads and find that we can extend this to a solution that produces no tails, then we can discard all the partial solutions produced by extending the other, because all its descendants must have at least one tail.
I would next branch on the leftmost but one vertical line, which will give us another known coin, and continue branching alternately horizontally and vertically.
This will be a feasible way of finding an exact solution if there is a nearly perfect solution or if the table is very small. Otherwise you will have to stop it early or have it skip credible solutions to get the problem finished in a reasonable time, and you will probably not get the exact best answer.

What to use for flow free-like game random level creation?

I need some advice. I'm developing a game similar to Flow Free wherein the gameboard is composed of a grid and colored dots, and the user has to connect the same colored dots together without overlapping other lines, and using up ALL the free spaces in the board.
My question is about level-creation. I wish to make the levels generated randomly (and should at least be able to solve itself so that it can give players hints) and I am in a stump as to what algorithm to use. Any suggestions?
Note: image shows the objective of Flow Free, and it is the same objective of what I am developing.
Thanks for your help. :)
Consider solving your problem with a pair of simpler, more manageable algorithms: one algorithm that reliably creates simple, pre-solved boards and another that rearranges flows to make simple boards more complex.
The first part, building a simple pre-solved board, is trivial (if you want it to be) if you're using n flows on an nxn grid:
For each flow...
Place the head dot at the top of the first open column.
Place the tail dot at the bottom of that column.
Alternatively, you could provide your own hand-made starter boards to pass to the second part. The only goal of this stage is to get a valid board built, even if it's just trivial or predetermined, so it's worth keeping it simple.
The second part, rearranging the flows, involves looping over each flow, seeing which one can work with its neighboring flow to grow and shrink:
For some number of iterations...
Choose a random flow f.
If f is at the minimum length (say 3 squares long), skip to the next iteration because we can't shrink f right now.
If the head dot of f is next to a dot from another flow g (if more than one g to choose from, pick one at random)...
Move f's head dot one square along its flow (i.e., walk it one square towards the tail). f is now one square shorter and there's an empty square. (The puzzle is now unsolved.)
Move the neighboring dot from g into the empty square vacated by f. Now there's an empty square where g's dot moved from.
Fill in that empty spot with flow from g. Now g is one square longer than it was at the beginning of this iteration. (The puzzle is back to being solved as well.)
Repeat the previous step for f's tail dot.
The approach as it stands is limited (dots will always be neighbors) but it's easy to expand upon:
Add a step to loop through the body of flow f, looking for trickier ways to swap space with other flows...
Add a step that prevents a dot from moving to an old location...
Add any other ideas that you come up with.
The overall solution here is probably less than the ideal one that you're aiming for, but now you have two simple algorithms that you can flesh out further to serve the role of one large, all-encompassing algorithm. In the end, I think this approach is manageable, not cryptic, and easy to tweek, and, if nothing else, a good place to start.
Update: I coded a proof-of-concept based on the steps above. Starting with the first 5x5 grid below, the process produced the subsequent 5 different boards. Some are interesting, some are not, but they're always valid with one known solution.
Starting Point
5 Random Results (sorry for the misaligned screenshots)
And a random 8x8 for good measure. The starting point was the same simple columns approach as above.
Updated answer: I implemented a new generator using the idea of "dual puzzles". This allows much sparser and higher quality puzzles than any previous method I know of. The code is on github. I'll try to write more details about how it works, but here is an example puzzle:
Old answer:
I have implemented the following algorithm in my numberlink solver and generator. In enforces the rule, that a path can never touch itself, which is normal in most 'hardcore' numberlink apps and puzzles
First the board is tiled with 2x1 dominos in a simple, deterministic way.
If this is not possible (on an odd area paper), the bottom right corner is
left as a singleton.
Then the dominos are randomly shuffled by rotating random pairs of neighbours.
This is is not done in the case of width or height equal to 1.
Now, in the case of an odd area paper, the bottom right corner is attached to
one of its neighbour dominos. This will always be possible.
Finally, we can start finding random paths through the dominos, combining them
as we pass through. Special care is taken not to connect 'neighbour flows'
which would create puzzles that 'double back on themselves'.
Before the puzzle is printed we 'compact' the range of colours used, as much as possible.
The puzzle is printed by replacing all positions that aren't flow-heads with a .
My numberlink format uses ascii characters instead of numbers. Here is an example:
$ bin/numberlink --generate=35x20
Warning: Including non-standard characters in puzzle
35 20
....bcd.......efg...i......i......j
.kka........l....hm.n....n.o.......
.b...q..q...l..r.....h.....t..uvvu.
....w.....d.e..xx....m.yy..t.......
..z.w.A....A....r.s....BB.....p....
.D.........E.F..F.G...H.........IC.
.z.D...JKL.......g....G..N.j.......
P...a....L.QQ.RR...N....s.....S.T..
U........K......V...............T..
WW...X.......Z0..M.................
1....X...23..Z0..........M....44...
5.......Y..Y....6.........C.......p
5...P...2..3..6..VH.......O.S..99.I
........E.!!......o...."....O..$$.%
.U..&&..J.\\.(.)......8...*.......+
..1.......,..-...(/:.."...;;.%+....
..c<<.==........)./..8>>.*.?......#
.[..[....]........:..........?..^..
..._.._.f...,......-.`..`.7.^......
{{......].....|....|....7.......#..
And here I run it through my solver (same seed):
$ bin/numberlink --generate=35x20 | bin/numberlink --tubes
Found a solution!
┌──┐bcd───┐┌──efg┌─┐i──────i┌─────j
│kka│└───┐││l┌─┘│hm│n────n┌o│┌────┐
│b──┘q──q│││l│┌r└┐│└─h┌──┐│t││uvvu│
└──┐w┌───┘d└e││xx│└──m│yy││t││└──┘│
┌─z│w│A────A┌┘└─r│s───┘BB││┌┘└p┌─┐│
│D┐└┐│┌────E│F──F│G──┐H┐┌┘││┌──┘IC│
└z└D│││JKL┌─┘┌──┐g┌─┐└G││N│j│┌─┐└┐│
P──┐a││││L│QQ│RR└┐│N└──┘s││┌┘│S│T││
U─┐│┌┘││└K└─┐└─┐V││└─────┘││┌┘││T││
WW│││X││┌──┐│Z0││M│┌──────┘││┌┘└┐││
1┐│││X│││23││Z0│└┐││┌────M┌┘││44│││
5│││└┐││Y││Y│┌─┘6││││┌───┐C┌┘│┌─┘│p
5││└P│││2┘└3││6─┘VH│││┌─┐│O┘S┘│99└I
┌┘│┌─┘││E┐!!│└───┐o┘│││"│└─┐O─┘$$┌%
│U┘│&&│└J│\\│(┐)┐└──┘│8││┌*└┐┌───┘+
└─1└─┐└──┘,┐│-└┐│(/:┌┘"┘││;;│%+───┘
┌─c<<│==┌─┐││└┐│)│/││8>>│*┌?│┌───┐#
│[──[└─┐│]││└┐│└─┘:┘│└──┘┌┘┌┘?┌─^││
└─┐_──_│f││└,│└────-│`──`│7┘^─┘┌─┘│
{{└────┘]┘└──┘|────|└───7└─────┘#─┘
I've tested replacing step (4) with a function that iteratively, randomly merges two neighboring paths. However it game much denser puzzles, and I already think the above is nearly too dense to be difficult.
Here is a list of problems I've generated of different size: https://github.com/thomasahle/numberlink/blob/master/puzzles/inputs3
The most straightforward way to create such a level is to find a way to solve it. This way, you can basically generate any random starting configuration and determine if it is a valid level by trying to have it solved. This will generate the most diverse levels.
And even if you find a way to generate the levels some other way, you'll still want to apply this solving algorithm to prove that the generated level is any good ;)
Brute-force enumerating
If the board has a size of NxN cells, and there are also N colours available, brute-force enumerating all possible configurations (regardless of wether they form actual paths between start and end nodes) would take:
N^2 cells total
2N cells already occupied with start and end nodes
N^2 - 2N cells for which the color has yet to be determined
N colours available.
N^(N^2 - 2N) possible combinations.
So,
For N=5, this means 5^15 = 30517578125 combinations.
For N=6, this means 6^24 = 4738381338321616896 combinations.
In other words, the number of possible combinations is pretty high to start with, but also grows ridiculously fast once you start making the board larger.
Constraining the number of cells per color
Obviously, we should try to reduce the number of configurations as much as possible. One way of doing that is to consider the minimum distance ("dMin") between each color's start and end cell - we know that there should at least be this much cells with that color. Calculating the minimum distance can be done with a simple flood fill or Dijkstra's algorithm.
(N.B. Note that this entire next section only discusses the number of cells, but does not say anything about their locations)
In your example, this means (not counting the start and end cells)
dMin(orange) = 1
dMin(red) = 1
dMin(green) = 5
dMin(yellow) = 3
dMin(blue) = 5
This means that, of the 15 cells for which the color has yet to be determined, there have to be at least 1 orange, 1 red, 5 green, 3 yellow and 5 blue cells, also making a total of 15 cells.
For this particular example this means that connecting each color's start and end cell by (one of) the shortest paths fills the entire board - i.e. after filling the board with the shortest paths no uncoloured cells remain. (This should be considered "luck", not every starting configuration of the board will cause this to happen).
Usually, after this step, we have a number of cells that can be freely coloured, let's call this number U. For N=5,
U = 15 - (dMin(orange) + dMin(red) + dMin(green) + dMin(yellow) + dMin(blue))
Because these cells can take any colour, we can also determine the maximum number of cells that can have a particular colour:
dMax(orange) = dMin(orange) + U
dMax(red) = dMin(red) + U
dMax(green) = dMin(green) + U
dMax(yellow) = dMin(yellow) + U
dMax(blue) = dMin(blue) + U
(In this particular example, U=0, so the minimum number of cells per colour is also the maximum).
Path-finding using the distance constraints
If we were to brute force enumerate all possible combinations using these color constraints, we would have a lot less combinations to worry about. More specifically, in this particular example we would have:
15! / (1! * 1! * 5! * 3! * 5!)
= 1307674368000 / 86400
= 15135120 combinations left, about a factor 2000 less.
However, this still doesn't give us the actual paths. so a better idea would be to a backtracking search, where we process each colour in turn and attempt to find all paths that:
doesn't cross an already coloured cell
Is not shorter than dMin(colour) and not longer than dMax(colour).
The second criteria will reduce the number of paths reported per colour, which causes the total number of paths to be tried to be greatly reduced (due to the combinatorial effect).
In pseudo-code:
function SolveLevel(initialBoard of size NxN)
{
foreach(colour on initialBoard)
{
Find startCell(colour) and endCell(colour)
minDistance(colour) = Length(ShortestPath(initialBoard, startCell(colour), endCell(colour)))
}
//Determine the number of uncoloured cells remaining after all shortest paths have been applied.
U = N^(N^2 - 2N) - (Sum of all minDistances)
firstColour = GetFirstColour(initialBoard)
ExplorePathsForColour(
initialBoard,
firstColour,
startCell(firstColour),
endCell(firstColour),
minDistance(firstColour),
U)
}
}
function ExplorePathsForColour(board, colour, startCell, endCell, minDistance, nrOfUncolouredCells)
{
maxDistance = minDistance + nrOfUncolouredCells
paths = FindAllPaths(board, colour, startCell, endCell, minDistance, maxDistance)
foreach(path in paths)
{
//Render all cells in 'path' on a copy of the board
boardCopy = Copy(board)
boardCopy = ApplyPath(boardCopy, path)
uRemaining = nrOfUncolouredCells - (Length(path) - minDistance)
//Recursively explore all paths for the next colour.
nextColour = NextColour(board, colour)
if(nextColour exists)
{
ExplorePathsForColour(
boardCopy,
nextColour,
startCell(nextColour),
endCell(nextColour),
minDistance(nextColour),
uRemaining)
}
else
{
//No more colours remaining to draw
if(uRemaining == 0)
{
//No more uncoloured cells remaining
Report boardCopy as a result
}
}
}
}
FindAllPaths
This only leaves FindAllPaths(board, colour, startCell, endCell, minDistance, maxDistance) to be implemented. The tricky thing here is that we're not searching for the shortest paths, but for any paths that fall in the range determined by minDistance and maxDistance. Hence, we can't just use Dijkstra's or A*, because they will only record the shortest path to each cell, not any possible detours.
One way of finding these paths would be to use a multi-dimensional array for the board, where
each cell is capable of storing multiple waypoints, and a waypoint is defined as the pair (previous waypoint, distance to origin). The previous waypoint is needed to be able to reconstruct the entire path once we've reached the destination, and the distance to origin
prevents us from exceeding the maxDistance.
Finding all paths can then be done by using a flood-fill like exploration from the startCell outwards, where for a given cell, each uncoloured or same-as-the-current-color-coloured neigbour is recursively explored (except the ones that form our current path to the origin) until we reach either the endCell or exceed the maxDistance.
An improvement on this strategy is that we don't explore from the startCell outwards to the endCell, but that we explore from both the startCell and endCell outwards in parallel, using Floor(maxDistance / 2) and Ceil(maxDistance / 2) as the respective maximum distances. For large values of maxDistance, this should reduce the number of explored cells from 2 * maxDistance^2 to maxDistance^2.
I think you'll want to do this in two steps. Step 1) find a set of non-intersecting paths that connect all your points, then 2) Grow/shift those paths to fill the entire board
My thoughts on Step 1 are to essentially perform Dijkstra like algorithm on all points simultaneously, growing together the paths. Similar to Dijkstra, I think you'll want to flood-fill out from each of your points, chosing which node to search next using some heuristic (My hunch says chosing points with the least degrees of freedom first, then by distance, might be a good one). Very differently from Dijkstra though I think we might be stuck with having to backtrack when we have multiple paths attempting to grow into the same node. (This could of course be fairly problematic on bigger maps, but might not be a big deal on small maps like the one you have above.)
You may also solve for some of the easier paths before you start the above algorithm, mainly to cut down on the number of backtracks needed. In specific, if you can make a trace between points along the edge of the board, you can guarantee that connecting those two points in that fashion would never interfere with other paths, so you can simply fill those in and take those guys out of the equation. You could then further iterate on this until all of these "quick and easy" paths are found by tracing along the borders of the board, or borders of existing paths. That algorithm would actually completely solve the above example board, but would undoubtedly fail elsewhere .. still, it would be very cheap to perform and would reduce your search time for the previous algorithm.
Alternatively
You could simply do a real Dijkstra's algorithm between each set of points, pathing out the closest points first (or trying them in some random orders a few times). This would probably work for a fair number of cases, and when it fails simply throw out the map and generate a new one.
Once you have Step 1 solved, Step 2 should be easier, though not necessarily trivial. To grow your paths, I think you'll want to grow your paths outward (so paths closest to walls first, growing towards the walls, then other inner paths outwards, etc.). To grow, I think you'll have two basic operations, flipping corners, and expanding into into adjacent pairs of empty squares.. that is to say, if you have a line like
.v<<.
v<...
v....
v....
First you'll want to flip the corners to fill in your edge spaces
v<<<.
v....
v....
v....
Then you'll want to expand into neighboring pairs of open space
v<<v.
v.^<.
v....
v....
v<<v.
>v^<.
v<...
v....
etc..
Note that what I've outlined wont guarantee a solution if one exists, but I think you should be able to find one most of the time if one exists, and then in the cases where the map has no solution, or the algorithm fails to find one, just throw out the map and try a different one :)
You have two choices:
Write a custom solver
Brute force it.
I used option (2) to generate Boggle type boards and it is VERY successful. If you go with Option (2), this is how you do it:
Tools needed:
Write a A* solver.
Write a random board creator
To solve:
Generate a random board consisting of only endpoints
while board is not solved:
get two endpoints closest to each other that are not yet solved
run A* to generate path
update board so next A* knows new board layout with new path marked as un-traversable.
At exit of loop, check success/fail (is whole board used/etc) and run again if needed
The A* on a 10x10 should run in hundredths of a second. You can probably solve 1k+ boards/second. So a 10 second run should get you several 'usable' boards.
Bonus points:
When generating levels for a IAP (in app purchase) level pack, remember to check for mirrors/rotations/reflections/etc so you don't have one board a copy of another (which is just lame).
Come up with a metric that will figure out if two boards are 'similar' and if so, ditch one of them.

Resources