Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Grid 通过网格的最大路径数公式?_Grid_Graph_Puzzle - Fatal编程技术网

Grid 通过网格的最大路径数公式?

Grid 通过网格的最大路径数公式?,grid,graph,puzzle,Grid,Graph,Puzzle,给定一个开放点网格,并在这些点中放置一定数量的平铺,什么函数f(openSpots,tilesToPlace)将为您提供可以形成的连续路径数 连续路径是瓷砖的放置方式,以便每个瓷砖与另一个瓷砖共享一条边。(只有触角不够好。因此(0,1)和(0,0)是合法的,但是(1,1)和(2,2)不是。) 我已经有一个函数可以找到所有这些路径。然而,它只适用于少数人。对于较大的值,我只需要计算可能存在的值。以下是一些数据: For 1 tiles, there are 1 paths. For 2 tiles

给定一个开放点网格,并在这些点中放置一定数量的平铺,什么函数
f(openSpots,tilesToPlace)
将为您提供可以形成的连续路径数

连续路径是瓷砖的放置方式,以便每个瓷砖与另一个瓷砖共享一条边。(只有触角不够好。因此
(0,1)
(0,0)
是合法的,但是
(1,1)
(2,2)
不是。)

我已经有一个函数可以找到所有这些路径。然而,它只适用于少数人。对于较大的值,我只需要计算可能存在的值。以下是一些数据:

For 1 tiles, there are 1 paths.
For 2 tiles, there are 4 paths.
For 3 tiles, there are 22 paths.
For 4 tiles, there are 89 paths.
For 5 tiles, there are 390 paths.
For 6 tiles, there are 1476 paths.
For 7 tiles, there are 5616 paths.
For 8 tiles, there are 19734 paths.
For 9 tiles, there are 69555 paths.
随着拼图尺寸的增加,计算速度会变得非常慢。我认为我的路径发现解的渐近复杂性是相当糟糕的


如果有
n
tile,网格最多是
n
点长而宽。

您的问题似乎至少和其他问题一样困难。没有已知的快速算法可以做到这一点,而最著名的算法在n=50后会遇到困难。我怀疑有没有快速解决这个问题的方法

我甚至不想假装这是一个最优的解决方案,但它可能是一个有用的参考解决方案。我认为它至少给出了正确的答案,尽管这需要一些时间。它通过查找长度为n-1的所有路径,然后检查所有可能的位置来递归地解决问题,它可以再添加一个磁贴并删除重复的解决方案。它有一个特别难看的部分,它通过将路径转换为字符串并比较字符串来检查重复项,但是它写起来很快

以下是它生成的输出:

n = 1, number of paths found = 1
n = 2, number of paths found = 4
n = 3, number of paths found = 22
n = 4, number of paths found = 113
n = 5, number of paths found = 571
n = 6, number of paths found = 2816
n = 7, number of paths found = 13616
n = 8, number of paths found = 64678
n = 9, number of paths found = 302574
下面是代码:

using System;
using System.Collections.Generic;
using System.Linq;

public struct Tile
{
    public Tile(int x, int y) { X = x; Y = y; }
    public readonly int X;
    public readonly int Y;
    public IEnumerable<Tile> GetNeighbours(int gridSize)
    {
        if (X > 0)
            yield return new Tile(X - 1, Y);
        if (X < gridSize - 1)
            yield return new Tile(X + 1, Y);
        if (Y > 0)
            yield return new Tile(X, Y - 1);
        if (Y < gridSize - 1)
            yield return new Tile(X, Y + 1);
    }
    public override string ToString()
    {
        return string.Format("({0},{1})", X, Y);
    }
}

public class Path
{
    public Path(Tile[] tiles) { Tiles = tiles; }
    public Tile[] Tiles { get; private set; }
    public override string ToString()
    {
        return string.Join("", Tiles.Select(tile => tile.ToString()).ToArray());
    }
}

public class PathFinder
{
    public IEnumerable<Path> FindPaths(int n, int gridSize)
    {
        if (n == 1)
        {
            for (int x = 0; x < gridSize; ++x)
                for (int y = 0; y < gridSize; ++y)
                    yield return new Path(new Tile[] { new Tile(x, y) });
        }
        else
        {
            Dictionary<string, object> pathsSeen = new Dictionary<string, object>();
            foreach (Path shortPath in FindPaths(n - 1, gridSize))
            {
                foreach (Tile tile in shortPath.Tiles)
                {
                    foreach (Tile neighbour in tile.GetNeighbours(gridSize))
                    {
                        // Ignore tiles that are already included in the path.
                        if (shortPath.Tiles.Contains(neighbour))
                            continue;

                        Path newPath = new Path(shortPath.Tiles
                            .Concat(new Tile[] { neighbour })
                            .OrderBy(t => t.X)
                            .ThenBy(t => t.Y)
                            .ToArray());

                        string pathKey = newPath.ToString();
                        if (!pathsSeen.ContainsKey(pathKey))
                        {
                            pathsSeen[pathKey] = null;
                            yield return newPath;
                        }
                    }
                }
            }
        }
    }

    static void Main()
    {
        PathFinder pathFinder = new PathFinder();
        for (int n = 1; n <= 9; ++n)
        {
            List<Path> paths = pathFinder.FindPaths(n, n).ToList();
            Console.WriteLine("n = {0}, number of paths found = {1}", n, paths.Count);
            //foreach (Path path in paths)
            //    Console.WriteLine(path.ToString());
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
公共结构瓦
{
公共分幅(intx,inty){x=x;y=y;}
公共只读int X;
公共只读信息;
公共IEnumerable GetNeights(int gridSize)
{
如果(X>0)
新瓷砖的收益率(X-1,Y);
if(X0)
新瓷砖的收益率(X,Y-1);
如果(Ytile.ToString()).ToArray());
}
}
公共类探路者
{
公共IEnumerable FindPath(int n,int gridSize)
{
如果(n==1)
{
对于(int x=0;xt.X)
.ThenBy(t=>t.Y)
.ToArray());
string pathKey=newPath.ToString();
如果(!pathssen.ContainsKey(路径键))
{
pathssen[pathKey]=null;
收益-收益新路径;
}
}
}
}
}
}
静态void Main()
{
PathFinder PathFinder=新的PathFinder();

对于(int n=1;n)我们应该假设初始网格无限大(或者至少足够大,可以忽略边)?你确定3个瓷砖有22条路径吗?我只能想到18条。@Mark:澄清,不,我不确定它是22条。我相当确定它是18条。我编写了一个简单的程序,通过递归检查所有可能性来计算它,它也得到18条。如果你愿意,我可以给你我找到的路径列表(每条路径的瓷砖坐标)对于n=9,它也很慢,大约需要30秒。你喜欢源代码吗?我怀疑为了更快,你需要使用一个更智能的算法,但是我不确定什么。是的,我想看看你想出了什么。是否使用一个n位整数,像一个64位整数,加快寻找路径副本?考虑每个瓦片BI。整数中的t,这至少允许您使用一个基本整数为字典生成一个键。对于较小的n,您也可以将该整数直接用于布尔数组,以确定您是否见过它。只是一个想法。这似乎对运行速度较快的小n有帮助,但对于实际运行速度较快的大n则没有帮助问题是。我正在考虑将alg分为两部分:第一部分将确定哪些形状可以不放置它们,第二部分将计算形状可以以多少种不同的方式放置到网格上。第二部分实际上只是基于形状边界框大小的简单乘法。但sinc我们甚至不能同意什么是正确答案,或者“路径”是什么,我现在还不想做任何优化。正确性优先。我认为我上面建议的两部分优化算法的第一部分相当于枚举Polyminos:。