在网格中查找具有特定值的连接块
我无法找到解决我的问题的算法。
我有一个 8x8 块的网格,每个块的值范围从 0 到 9。我想找到与总值匹配的连接块的集合,例如 15。我的第一个方法是从边界开始,即工作得很好。但是当从网格中间开始时,我的算法就会丢失。
有人知道一个简单的算法可以使用吗?或者你能给我指出正确的方向吗?
谢谢!
I'm having trouble finding an algorithm for my problem.
I have a grid of 8x8 blocks, each block has a value ranging from 0 to 9. And I want to find collections of connected blocks that match a total value of for example 15. My first approach was to start of at the border, that worked fine. But when starting in the middle of the grid my algorithm gets lost.
Would anyone know a simple algorithm to use or can you point me in the right direction?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
据我所知,没有简单的算法可以解决这个问题。至于为您指明正确的方向,8x8 网格实际上只是图的一个特例,所以我将从图遍历算法开始。我发现在这种情况下,有时思考如何解决较小网格(例如 3x3 或 4x4)的问题,然后看看您的算法是否可以扩展到“完整尺寸”会有所帮助。
编辑:
我提出的算法是改进的深度优先遍历。要使用它,您必须将网格转换为图表。该图应该是无向的,因为连接的块在两个方向上均等连接。
每个图节点代表一个块,包含该块的值和一个
visited
变量。边权重代表其边对被跟随的抵抗力。通过对它们连接的节点的值求和来设置它们。根据您正在寻找的总和,您也许可以通过删除肯定会失败的边缘来优化这一点。例如,如果您要查找 15,则可以删除权重为 16 或更大的所有边。算法的其余部分将执行与块数相同的次数,每个块作为起始块一次。通过跟随当前节点的最低权重边来遍历图,除非这会将您带到访问过的节点。将每个访问过的节点推入堆栈并将其
visited
变量设置为true
。为所遵循的每条路径保留一个运行总和。visited
设置为 false 并将当前节点从堆栈中弹出来回溯。在分析了从给定起始节点开始的每条可能路径后,就找到了包含该节点的每个答案。因此,删除所有接触起始节点的边并选择一个新的起始节点。
我还没有完全分析这个算法的效率/运行时间,但是......它不好。 (考虑在包含全零的图中要搜索的路径数量。)也就是说,它比纯粹的蛮力要好得多。
As far as I know, no simple algorithm exists for this. As for pointing you in the right direction, an 8x8 grid is really just a special case of a graph, so I'd start with graph traversal algorithms. I find that in cases like this, it sometimes helps to think how you would solve the problem for a smaller grid (say, 3x3 or 4x4) and then see if your algorithm scales up to "full size."
EDIT :
My proposed algorithm is a modified depth-first traversal. To use it, you'll have to convert your grid into a graph. The graph should be undirected, since connected blocks are connected equally in both directions.
Each graph node represents a single block, containing the block's value and a
visited
variable. Edge weights represent their edges' resistance to being followed. Set them by summing the values of the nodes they connect. Depending on the sum you're looking for, you may be able to optimize this by removing edges that are guaranteed to fail. For example, if you're looking for 15, you can delete all edges with weight of 16 or greater.The rest of the algorithm will be performed as many times as there are blocks, with each block serving as the starting block once. Traverse the graph by following the lowest-weighted edge from the current node, unless that takes you to a visited node. Push each visited node onto a stack and set its
visited
variable totrue
. Keep a running sum for every path followed.visited
to false and popping the current node off the stack.After every possible path from a given starting node is analyzed, every answer that includes that node has been found. So, remove all edges touching the starting node and choose a new starting node.
I haven't fully analyzed the efficiency/running time of this algorithm yet, but... it's not good. (Consider the number of paths to be searched in a graph containing all zeroes.) That said, it's far better than pure brute force.