1

Given this question, what about the special case when the start point and end point are the same?

Another change in my case is that we must move at every step. How many such paths can be found and what would be the most efficient approach? I guess this would be a random walk of some sort?

My think so far is, since we must always return to our starting point, thinking about n/2 might be easier. At every step, except at step n/2, we have 6 choices. At n/2 we have a different amount of choices depending on if n is even or odd. We also have a different amount of choices depending on where we are (what previous choices we made). For example if n is even and we went straight out, we only have one choice at n/2, going back. But if n is even and we didn't go straight out, we have more choices.

It is all the cases at this turning point that I have trouble getting straight.

Am I on the right track?

To be clear, I just want to count the paths. So I guess we are looking for some conditioned permutation?

Skillzore
  • 748
  • 7
  • 21

1 Answers1

2

This version of the combinatorial problem looks like it actually has a short formula as an answer. Nevertheless, the general version, both this and the original question's, can be solved by dynamic programming in O (n^3) time and O (n^2) memory.

Consider a hexagonal grid which spans at least n steps in all directions from the target cell. Introduce a coordinate system, so that every cell has coordinates of the form (x, y).

Let f (k, x, y) be the number of ways to arrive at cell (x, y) from the starting cell after making exactly k steps. These can be computed either recursively or iteratively: f (k, x, y) is just the sum of f (k-1, x', y') for the six neighboring cells (x', y').

The base case is f (0, xs, ys) = 1 for the starting cell (xs, ys), and f (0, x, y) = 0 for every other cell (x, y).

The answer for your particular problem is the value f (n, xs, ys).

The general structure of an iterative solution is as follows:

let f be an array [0..n] [-n-1..n+1] [-n-1..n+1] (all inclusive) of integers
f[0][*][*] = 0
f[0][xs][ys] = 1
for k = 1, 2, ..., n:
    for x = -n, ..., n:
        for y = -n, ..., n:
            f[k][x][y] =
                f[k-1][x-1][y] +
                f[k-1][x][y-1] +
                f[k-1][x+1][y] +
                f[k-1][x][y+1]
answer = f[n][xs][ys]

OK, I cheated here: the solution above is for a rectangular grid, where the cell (x, y) has four neighbors. The six neighbors of a hexagon depend on how exactly we introduce a coordinate system. I'd prefer other coordinate systems than the one in the original question. This link gives an overview of the possibilities, and here is a short summary of that page on StackExchange, to protect against link rot. My personal preference would be axial coordinates.

Note that, if we allow standing still instead of moving to one of the neighbors, that just adds one more term, f[k-1][x][y], to the formula. The same goes for using triangular, rectangular, or hexagonal grid, for using 4 or 8 or some other subset of neighbors in a grid, and so on. If you want to arrive to some other target cell (xt, yt), that is also covered: the answer is the value f[n][xt][yt]. Similarly, if you have multiple start or target cells, and you can start and finish at any of them, just alter the base case or sum the answers in the cells. The general layout of the solution remains the same.

This obviously works in n * (2n+1) * (2n+1) * number-of-neighbors, which is O(n^3) for any constant number of neighbors (4 or 6 or 8...) a cell may have in our particular problem.

Finally, note that, at step k of the main loop, we need only two layers of the array f: f[k-1] is the source layer, and f[k] is the target layer. So, instead of storing all layers for the whole time, we can store just two layers, as we don't need more: one for odd k and one for even k. Using only two layers is as simple as changing all f[k] and f[k-1] to f[k%2] and f[(k-1)%2], respectively. This lowers the memory requirement from O(n^3) down to O(n^2), as advertised in the beginning.


For a more mathematical solution, here are some steps that would perhaps lead to one.

First, consider the following problem: what is the number of ways to go from (xs, ys) to (xt, yt) in n steps, each step moving one square north, west, south, or east?

To arrive from x = xs to x = xt, we need H = |xt - xs| steps in the right direction (without loss of generality, let it be east). Similarly, we need V = |yt - ys| steps in another right direction to get to the desired y coordinate (let it be south). We are left with k = n - H - V "free" steps, which can be split arbitrarily into pairs of north-south steps and pairs of east-west steps. Obviously, if k is odd or negative, the answer is zero.

So, for each possible split k = 2h + 2v of "free" steps into horizontal and vertical steps, what we have to do is construct a path of H+h steps east, h steps west, V+v steps south, and v steps north. These steps can be done in any order. The number of such sequences is a multinomial coefficient, and is equal to n! / (H+h)! / h! / (V+v)! / v!. To finally get the answer, just sum these over all possible h and v such that k = 2h + 2v. This solution calculates the answer in O(n) if we precalculate the factorials, also in O(n), and consider all arithmetic operations to take O(1) time.

For a hexagonal grid, a complicating feature is that there is no such clear separation into horizontal and vertical steps. Still, given the starting cell and the number of steps in each of the six directions, we can find the final cell, regardless of the order of these steps. So, a solution can go as follows:

  • Enumerate all possible partitions of n into six summands a1, ..., a6.
  • For each such partition, find the final cell.
  • For each partition where the final cell is the cell we want, add multinomial coefficient n! / a1! / ... / a6! to the answer.

Just so, this takes O(n^6) time and O(1) memory. By carefully studying the relations between different directions on a hexagonal grid, perhaps we can actually consider only the partitions which arrive at the target cell, and completely ignore all other partitions. If so, this solution can be optimized into at least some O(n^3) or O(n^2) time, maybe further with decent algebraic skills.

Gassa
  • 8,546
  • 3
  • 29
  • 49
  • For completion, what would be the short formula to solve the combinatorial problem? Kudos on the detailed answer! – Skillzore Apr 18 '18 at 20:09
  • @Skillzore The math part looks way easier with a rectangular grid. I added what I have to the answer, but there is still plenty of room for improvement. – Gassa Apr 18 '18 at 20:57
  • Thank you! A very complete answer. I will leave some time for more answers, but will probably accept yours in the end anyway. – Skillzore Apr 18 '18 at 21:18