Search for all possible paths of length n in a hexagonal grid

Suppose that the function takes the values s(initial hexagon), f(target hexagon) and n(path length) as parameters and displays a list of all possible paths whose length is n. To visualize the problem, please check the picture below:

enter image description here

Let's say our origin ( s) is the red dotted hex (2, 3), and the target ( f) is the blue dotted (5, 2). We want to reach the blue dotted hex in 5 steps ( n = 5). Also note that if a walk reaches a specific hex, it can remain in this hexadecimal form in the next step. In other words, one of the possible ways could be (3, 2) - (4, 2) - (5, 2) - (5, 2) - (5, 2). It is also considered a 5-long route.

Here are some examples of paths from (2, 3)to (5, 2):

(1, 3) - (2, 3) - (3, 2) - (4, 3) - (5, 2)
(3, 3) - (4, 4) - (5, 4) - (5, 3) - (5, 2)
(2, 3) - (2, 3) - (3, 3) - (4, 3) - (5, 2)

I want to find all these paths in some way. However, I could not determine which algorithm gives the most effective solution to solve this problem. The first thing that comes to mind is to use the depth search, but I'm wondering if there is a more effective alternative in this case.

+4
2

, , , - from to i:

find_paths_from_to_with_length(from, to, i):
    if i == 1:
        if to in neighbors(from) or from == to:
            return [[(from, to)]]
        return []

    all_paths = []
    for node in neighbors(from) + [from]:
        neighbor_all_paths = find_paths_from_to_with_length(node, to, i - 1)
        for path in neigbor_all_paths:
            all_paths.append([(from, node)] + neighbor_path

    return all_paths

, .

+1

enter image description here

:

function dist = manhattan_dist( p, q )

    y1 = p(1);
    y2 = q(1);
    x1 = p(2);
    x2 = q(2);

    du = x2 - x1;
    dv = (y2 - floor(x2 / 2)) - (y1 - floor(x1 / 2));

    if ((du >= 0 && dv >= 0) || (du < 0 && dv < 0))
        dist = abs(du) + abs(dv);

    else
        dist = max(abs(du), abs(dv));
    end

end

:

, , manhattan_dist:

function all_paths = find_paths( from, to, i )

    if i == 1
        all_paths = to;
        return;
    end

    all_paths = [];
    neighbors = neighbor_nodes(from, 8);
    for j = 1:length(neighbors)
        if manhattan_dist(neighbors(j,:), to) <= i - 1
            paths = find_paths(neighbors(j,:), to, i - 1);
            for k = 1:size(paths, 1)
                all_paths = [all_paths; {neighbors(j,:)} paths(k,:)];
            end
        end
    end

end

, , :

function neighbors = neighbor_nodes( node, n )

    y = node(1);
    x = node(2);

    neighbors = [];
    neighbors = [neighbors; [y, x]];

    if mod(x,2) == 1
        neighbors = [neighbors; [y, x-1]];

        if y > 0
            neighbors = [neighbors; [y-1, x]];
        end

        if x < n - 1
            neighbors = [neighbors; [y, x+1]];
            neighbors = [neighbors; [y+1, x+1]];
        end

        neighbors = [neighbors; [y+1, x-1]];

        if y < n - 1
            neighbors = [neighbors; [y+1, x]];
        end

    else
        if y > 0
            neighbors = [neighbors; [y-1, x]];
            neighbors = [neighbors; [y-1, x+1]];
            if x > 0
                neighbors = [neighbors; [y-1, x-1]];
            end
        end

        if y < n
            neighbors = [neighbors; [y+1, x]];
            neighbors = [neighbors; [y, x+1]];    

            if x > 0
                neighbors = [neighbors; [y, x-1]];
            end
        end
    end

end

- node, node n . , (1, 1) (0, 3) (n = 2), , (1, 2), .

+1

Source: https://habr.com/ru/post/1626993/


All Articles