作者:手机用户2602936771 | 来源:互联网 | 2023-05-17 17:25
TheproblemSo,sayoneimaginesa2-darrayofintegervalueswhichrepresentsagridded-map,like
The problem
So, say one imagines a 2-d array of integer values which represents a gridded-map, like this: +-----+------+-----+-----+-----+ | 10 | 2 | 2 | 4 | 656 | +-----+------+-----+-----+-----+ | 234 | 165 | 724 | 759 | 230 | +-----+------+-----+-----+-----+ | 843 | 734 | 999 | 143 | 213 | +-----+------+-----+-----+-----+ | 242 | 2135 | 131 | 24 | 374 | +-----+------+-----+-----+-----+ | 159 | 464 | 155 | 124 | 151 | +-----+------+-----+-----+-----+
所以,假设有人想象一个2-d的整数值数组,它代表一个网格化的地图,如下所示:+ ----- + ------ + ----- + ----- + - ---- + | 10 | 2 | 2 | 4 | 656 | + ----- + ------ + ----- + ----- + ----- + | 234 | 165 | 724 | 759 | 230 | + ----- + ------ + ----- + ----- + ----- + | 843 | 734 | 999 | 143 | 213 | + ----- + ------ + ----- + ----- + ----- + | 242 | 2135 | 131 | 24 | 374 | + ----- + ------ + ----- + ----- + ----- + | 159 | 464 | 155 | 124 | 151 | + ----- + ------ + ------ + ------ + ------ +
The 2d indices represent the coordinates of a cell on the map, and the values in the array represent the relative difficulty to traverse the terrain of that cell - so for example 999 might be thick brambles, while 2,3,4 might be a slightly inclining path... or something.
2d索引表示地图上单元格的坐标,数组中的值表示遍历该单元格地形的相对难度 - 例如999可能是粗荆棘,而2,3,4可能是稍微倾斜的路径...或者其他什么。
Now we want to find the easiest path from [x,y] on the grid to [q,r] on the grid (where the sum of the steps is the lowest possible, in other words)
现在我们想要找到从网格上的[x,y]到网格上的[q,r]的最简单路径(其中步长的总和是最低的,换句话说)
The problem domain
问题领域
This needs to run in a modern browser, where a rather spartan map is rendered, and we'll draw a line from [x,y] to [q,r] through all the interceding vertices, after the user has input [q,r]. Conveniently, [X,Y] is always the same (say [0,0] for simplicity)
这需要在现代浏览器中运行,其中渲染相当简洁的地图,并且在用户输入[q之后,我们将通过所有中间顶点绘制从[x,y]到[q,r]的线。 R]。方便的是,[X,Y]总是相同的(简单来说[0,0])
So use Dijkstra's algorithm or A*!
所以使用Dijkstra的算法或A *!
So my first instinct was to model the array as a graph, apply Dijkstra's algorithm and work from there. And in the above case, with a 5x5 grid, that works fine. I traverse each array index, and use the value, and adjacent values, to generate a node with weighted edges to all of it's neighbours. This builds up a graph which I can then apply Dijkstra's algorithm to.
所以我的第一直觉是将数组建模为图形,应用Dijkstra的算法并从那里开始工作。在上面的例子中,使用5x5网格,工作正常。我遍历每个数组索引,并使用值和相邻值生成一个节点,该节点的所有邻居都有加权边。这构建了一个图表,然后我可以应用Dijkstra的算法。
However, In practice, I will be working with arrays up to 50,000 x 50,000 in size! That's 250 million!
但是,实际上,我将使用最大50,000 x 50,000的阵列!那是2.5亿!
So obviously building a graph on-the-fly to run Dijkstra’s algorithm isn't applicable. My next idea was to pre-compute the paths (The data-set is fixed), store them on the server and do a callback when we get the destination [q,r]...but this is 250,000,000 paths... even if I made it run in less than a second (which i don't think it will) it'll take years to compute all the paths...
因此,显然构建运行Dijkstra算法的图形是不适用的。我的下一个想法是预先计算路径(数据集是固定的),将它们存储在服务器上并在我们到达目的地[q,r]时进行回调...但这是250,000,000个路径...甚至如果我让它在不到一秒的时间内运行(我认为不会这样),那么计算所有路径需要数年时间......
I think I might need to take another approach but I'm not sure, how can I make this work?
我想我可能需要采取另一种方法,但我不确定,我怎样才能做到这一点?
1 个解决方案
8
Don't construct an explicit graph (pointers are expensive) -- use pairs of coordinates to represent nodes in the queue and modify your Dijkstra implementation to operate on your 2d array representation directly.
不构造显式图(指针很昂贵) - 使用坐标对来表示队列中的节点,并修改Dijkstra实现以直接操作您的2d数组表示。
Use an array similar to the costs array to store the (initially tentative) distances calculated by the algorithm.
使用类似于costs数组的数组来存储算法计算的(最初暂定的)距离。
Dijkstra will calculate the costs to all nodes in a single run, so if your starting point is fixed, running it once should be sufficient -- there is no need to run it millions of times.
Dijkstra将计算单次运行中所有节点的成本,因此如果您的起点是固定的,那么运行一次就足够了 - 无需运行数百万次。
P.S.: Created a Jsfiddle running Dijkstra on images: https://goo.gl/5GWwMF
P.S。:在图像上创建了一个运行Dijkstra的Jsfiddle:https://goo.gl/5GWwMF
Computes the distances to all points from a mouse click, where darker pixels are interpreted as more expensive...
通过鼠标单击计算到所有点的距离,其中较暗的像素被解释为更昂贵...
It becomes slower with larger images but didn't manage to crash it so far, but I think for your data it will run out of memory in the browser.
对于较大的图像,它会变慢,但到目前为止还没有成功崩溃,但我认为对于您的数据,它将在浏览器中耗尽内存。
The Dijkstra implementation uses the following interface to access the graph -- I think this should be straight forward to provide on top of your data structure without explicitly generating a "traditional" graph data structure with explicit nodes and edges in memory:
Dijkstra实现使用以下接口来访问图形 - 我认为这应该是直接提供在数据结构之上而不显式生成具有显式节点和内存边缘的“传统”图形数据结构:
/**
* The interface the Dijkstra implementation below uses
* to access the graph and to store the calculated final
* and intermediate distance data.
*
* @Interface
*/
Graph = function() {};
/**
* Returns the current distance for the given node.
* @param {Object} node
* @return {number}
*/
Graph.currentDistance = function(node) {};
/**
* Stores the current distance for the given node.
* @param {Object} node
* @param {number} distance
*/
Graph.setCurrentDistance = function(node, distance) {};
/**
* Returns an array of connected nodes for the given node,
* including the distances.
*
* @param {Object}
* @return {Array<{cost:number, node:Object}>}
*/
Graph.cOnnections= function(node) {};
P.P.S.: Added code to display the shortes path on all clicks after the first click. Also fixed a bug permitting diagonal movement: https://goo.gl/wXGwiv
P.P.S。:添加了代码,以便在第一次单击后显示所有点击的短路径。还修复了允许对角线移动的错误:https://goo.gl/wXGwiv
So in conclusion, while this probably doesn't scale to 50k x 50x in the browser, I think this shows that Dijkstra operating on the arrays directly is worth trying on the server side, and that an array identical in size to the data array is all that is needed to store all shortest paths from a single point.
总而言之,虽然这可能不会在浏览器中扩展到50k x 50x,但我认为这表明直接在阵列上运行的Dijkstra值得在服务器端尝试,并且与数据阵列大小相同的数组是从一个点存储所有最短路径所需的一切。