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:。