问题
s o o o o
o o o o o
o o o o o
o o o o o
o o o o e
How can I calculate all possible paths, without using the same square twice, that a person could take to get from s
to e
?
I've created a grid array [[1,1]...[5,5]] but i dont know if that will work.
I've also mapped possible squares, and tried to create a record and check and lots of junk.
Any standard formula I could put to use here?
回答1:
There are quite a few standard path finding algorhythms you could use for this.
This is not related to javascript.
You can use one algorhythm without heuristics, and you should not stop on the first solution.
Here is how you can do it:
The trick is you'll need to store the already visited squares in a list and check if you are revisiting one of them on every step.
The other trick is you need definite order between the adjacent squares. (Like top/right/bottom/left. Which is a really silly algorhythm but fine for this particular case.)
Also you need to be able to identify the squares (it is possible by its position)
Consider a recursive function (for example name it Visit):
function visit(square) {
add the square to the pathlist //pathlist is not a list of paths but a list of squares which is the current path
if (square is the goal) {
add a copy of the pathlist to the goalslist
}
else {
for (each adjacency in square.adjacencies) { // this can be calculated by adding +1 and -1 to the coordinates, and checking if its overflowing (less then one/more than five)
if (adjacency is in pathlist) {
//do nothing we have already been here
}
else {
visit(adjacency)
}
}
}
remove square from the pathlist!!
}
Start this algorythm by visit(start). You get your result in the goallist which is a list of pathlists hopefully.
Also it's only half javascript-half pseudocode but it is easy to write javascript from it.
EDIT: Enjoy the solution:
<script type="text/javascript">
var start = [1,1],
goal = [5,5],
pathList = [],
solutionList = [],
solutionCount = 0,
width = 5,
height = 5;
function squareInArray(square, array) {
var i = 0,
x = square[0],
y = square[1];
for (i = 0; i < array.length; i++) {
if (x == array[i][0] && y == array[i][1]) {
return true;
}
}
return false;
}
function visit(square) {
var i = 0,
x = square[0],
y = square[1],
adjacencies = [[x-1,y],[x+1,y],[x,y+1],[x,y-1]];
pathList.push(square);
if (x == goal[0] && y == goal[1]) {
var solution = pathList.slice(0); //copy trick
solutionList.push(solution);
solutionCount++;
//alert(solution);
}
else {
for (i = 0; i < adjacencies.length; i++) {
if (adjacencies[i][0] < 1 || adjacencies[i][0] > width || adjacencies[i][1] < 1 ||adjacencies[i][1] > height) {
//overflow
}
else {
if (squareInArray(adjacencies[i], pathList)) {
//do nothing we have already been here
}
else {
visit(adjacencies[i]);
}
}
}
}
pathList.pop();
}
visit(start);
alert(solutionCount);
</script>
8512 goals. Also someone should check if my code is right.
Check out this fiddle: http://jsfiddle.net/SoonDead/rd2GN/3/
回答2:
You can use a depth first search with backtracking to find all possible paths. The idea is simple start at S and visit any neighbor of S, then from that neighbor visit any other neighbor all the while marking that vertex as "used" once you backtrack removed the "used" status from the vertex so you can reuse it in another path, etc.... once you reach E you increment the number of paths. Paths have to be restricted so I'm assuming you mean paths that don't use one vertex more than once or you could have infinite cycles.
Frank mentioned the Catalan Numbers and this does work but only for monotonic paths, ie paths that go either only right/down or left/up. Also DP does not work because this is an NP-Hard problem (non polynomial time to find the solution and to verify since essentially you need to find all paths again to make sure they match).
回答3:
For references and bibliography on this problem, as well as a recurrence relation, refer to Self-Avoiding Walk in Weisstein's MathWorld. Very unfortunately, I could not get hold of the Abbott and Hanson's article that discussed this problem.
Rate of growth of the sequence in the size of square is formidable. According to OEIS A007764, the number of self-avoiding walks in a 12×12 square is 182413291514248049241470885236, a 30-digit number!
Thanks for the question, that is indeed a profound and thought-provoking problem.
EDIT: If diagonal steps are allowed, the number grows even quicker. This is the OEIS sequence A140518, due to D. Knuth. It is hard to brute-force even for a 5×5 square (over 400 million paths). There are notes from Knuth's lecture on the technique called ZDD that he used to compute these numbers.
回答4:
if you work in a 5x5 grid there is a simple math solution. Write 1 across the bottom and top of the grid and add the corners till you get to the end, the number in the corner at the end is the number of pathways. This is assuming that you can only move right and down.
Here is an example:
1 1 1 1 1 1 1 1 1 1 1 o o o o o 1 2 3 4 5 6 1 o o o o o --- 1 3 6 10 15 21 1 o o o o o --- 1 4 10 20 35 56 1 o o o o o 1 5 15 35 70 126 1 o o o o o 1 6 21 56 126 252
So the answer is 252
You could also use factorials the formula is (number of grids on each right and downsides)! divided by (left side)! divided by (downside)!= number of pathways.
So your equation would look like 10! divided by 5! divided by 5!= 252
Remember this only works if the guy can go only down and left!
回答5:
2 to the power of how ever big your square is. in your case 2 to the power od 5 is 32. there are therefor thirty two different possible routes. This patterned can be proved using the following example. A square that is 0x0 although impossible, would technically have one possible way to get from A to B, because it would already be there. A square that is 1x1 has two possible routes( if you don't believe me draw it and find out. This pattern is very obvious and even related to PAscal's triangle. Hope I helped.
来源:https://stackoverflow.com/questions/9172053/all-possible-moves-in-a-5x5-grid