从地址列表中存储可能的旅行路径

时间:2014-08-20 13:54:55

标签: javascript recursion

我有一个地址列表,我们可以称之为A-Z。我使用Google Maps api对这些进行地理编码,然后找到它们之间的行程时间以获得26x26矩阵。我想提出一个函数,它接受地址列表,矩阵,目标节点(我将称之为@)和时间限制,并返回一个可以从A到@实现的所有可能的旅行路径的列表。不同的非重复目的地的数量,并在达到时限之前返回到A.

我认为递归函数可能是最好的方法,但我只是在理论上了解它们并且不知道它是否会起作用。

到目前为止,我的想法是这样的:

var duration = 0;
var path = [];

function getPath(addList, matrix, targetNode, currentNode, timeLimit){
    if(duration+matrix[matrix.indexOf(currentNode), matrix.indexOf(A)]>=timeLimit{
        path[path.length-1] = A;
        // (1) add path to the list of possible paths
    }
    else{
        var tempList = addList;
        tempList.splice(tempList.indexOf(currentNode), 1);
        for(int i = 0; i < tempList.length; i++){
            // (2) increase duration by matrix[matrix.indexOf(currentNode), matrix.indexOf(tempList[i])];
            getPath(tempList, matrix, targetNode, tempList[i], timeLimit);
        }
    }
}

我认为如果我能弄清楚它会起作用:

(1)当我进入递归时,我应该如何存储路径(A,@,...,A)?我不能使用单个变量,因为每个函数都会改变它。我正在考虑使用像xml文件这样的东西作为树,但这似乎超过顶部。

(2)在一个类似的问题中,我将如何继续增加每条可能路径的持续时间?

最后一点,这只会给我从A到@到其他节点并返回A的最长路径。我希望包含较短的路径作为选项。例如,如果我的路径是{A,@,B,C,D,A},那么我还想包括以下路径{A,@,A},{A,@,B,A}和{A ,@,B,C,A}。如果我停在那里,递归会提前停止,所以我认为应该在getPath函数完全解析后作为后续处理。

任何指针,想法,帮助或评论都将不胜感激!提前谢谢!

更新:我只想到使用JSON对象来处理我的问题。它可能看起来像:

var jsonPaths = [
    {
        index: 1,
        path: [A,@,A],
        duration: 187
    },
    { .... },
    { .... }
];

我可以推送它并在每次函数调用时引用它。

1 个答案:

答案 0 :(得分:1)

您可以通过创建目标路径的数组,距离小于最大允许距离减去目标最短路径的距离来实现。

我会分两步完成:

首先,遍历并计算从每个节点到目标的最短路径。在节点上保存每条最短路径及其距离。

计算完所有最短路径后,您就可以开始创建可能的部分路径数组和一系列可能的路径。为了成为可能的部分路径,路径的总距离加上从路径中的最后一个节点到目标的最短路径的距离小于最大路径长度。可能的路径是从a@的路径小于最大路径长度。

您可以遍历可能的部分路径数组,在每个步骤中移除第一个可能的部分路径,并且可以从当前节点移动到所有节点,检查是否将该节点添加到当前路径可能是部分路径路径。如果是这样,请将其添加到可能的部分路径数组中。 “您可以前往的节点”将表示您尚未访问的节点已连接到当前节点。

现在,看起来您已将所有节点连接到所有其他节点。这可能会有问题,因为从a@,它最多可以提供4.0329146e + 26(a.k.a 26!)的可能路径。通常,对于这些类型的问题,您将节点限制为只能连接到附近的节点以避免大量的缩放问题,但您仍可能生成大量路径。所有可能的路径都可能很大。

我会建议不要递归,因为你要生成很多东西的列表。只需创建一系列可能性并不断删除它/向它添加内容直到它为空。

编辑:由于所有节点都连接到所有其他节点,因此可以通过添加目标节点从任何可能的潜在路径创建路径。就查找路径而言,这简化了事情。

要查找可能的路径,请考虑任何可能的路径是另一个可能的路径加一个节点。如果您知道ABC是可能的路径,您可以检查ABCD,ABCE,ABCF等,以及将ABC @添加到半路径数组中。

同样,如果ABD不是可能的路径,则不需要考虑以该路径开头的任何其他内容。要想出从A到@的所有路径,您可以从数组[A]开始。

你的功能看起来像这样:

var partialPaths = [A],
    nodes = [/*this contains all of your nodes*/],
    paths = [],
    maxDistance = totalDistance - distance([A@]), 
      //max distance of any path between A and @
    currentPath;

while(partialPaths.length > 0){
    currentPath = partialPaths.pop();

    paths.push(currentPath.concat([@]); //Adds the current path plus @

    nodes.forEach(function(node){
        if(distance(currentPath + node + @) < maxDistance &&
          (node not in current path){
            partialPaths.push(currentPath + node);
        }
    });
}

在此之后,您将拥有从A到@的所有路径的数组。只需将每条路径与长度减去总长度减去最大长度的所有路径组合,即可获得所有往返路径。