Javascript 高级排序算法

Javascript 高级排序算法,javascript,algorithm,google-maps,sorting,Javascript,Algorithm,Google Maps,Sorting,我正在用Javascript编写一个应用程序,它使用谷歌地图(GoogleMaps),并根据最近的腿计算一系列腿之间的完整路线 假设我在地图上有四条腿,每条腿都有一个起点和终点纬度和经度。用户指定哪两条腿是路线的起点和终点。一条腿的每一端只能连接到另一条腿的起点。然后,该腿的末端连接到另一腿的起点,依此类推。代码根据可以找到的最接近的支腿确定开始连接到哪个支腿 例如,类似这样的内容(虚线是腿): 这些将是内腿。然后我将把外部支腿(两条支腿,即整个路线的起点和终点)存储在变量中: var star

我正在用Javascript编写一个应用程序,它使用谷歌地图(GoogleMaps),并根据最近的腿计算一系列腿之间的完整路线

假设我在地图上有四条腿,每条腿都有一个起点和终点纬度和经度。用户指定哪两条腿是路线的起点和终点。一条腿的每一端只能连接到另一条腿的起点。然后,该腿的末端连接到另一腿的起点,依此类推。代码根据可以找到的最接近的支腿确定开始连接到哪个支腿

例如,类似这样的内容(虚线是腿):

这些将是内腿。然后我将把外部支腿(两条支腿,即整个路线的起点和终点)存储在变量中:

var start = {end_lat: X, end_lng: X}
var end = {start_lat: X, start_lng: X}
例如,它可能会以如下方式结束:

start -> array[0] -> array[1] -> end
或者它可能会像这样结束:

start -> array[1] -> array[0] -> end
该算法需要根据起始支腿end_lat,end_lng和末端支腿end_lat,end_lng对阵列进行排序

最终结果将是一条大路线与最短路径连接在一起

我正在努力思考一种编写排序算法的方法,该算法考虑了这些独特的因素

这很难用语言来表达,我也不确定如何才能让它更清楚,但如果我能想出任何有用的补充,我会编辑这篇文章。谢谢

编辑:

下面是我所说的图片:


黑线是支腿,红线是将支腿坐标数组按正确顺序排序后需要生成的连接线。生成连接器不是这个算法的一部分,但它只是我试图实现的一个示例,这样您就可以了解全局。正如您所看到的,腿之间有间隙,没有任何坐标重叠。

您可以这样做:

[
   {start_lat: X, start_lng: X, end_lat: X, end_lng: X},
   {start_lat: X, start_lng: X, end_lat: X, end_lng: X},
]

基本上,我们找到下一个
,它从
开始
结束的地方开始,然后让该
成为下一个
开始
,直到没有匹配为止,在每一步我们都将该点推入
结果

编辑:

这将使用起点和终点的坐标 重叠,但我没有,他们之间的差距很大 我需要在它们之间生成“连接器”

我通过使用欧洲工商管理学院寻找重叠坐标扩展了我的第一个想法

var start={end\u lat:1,end\u lng:1},
end={start_lat:4,start_lng:4},
段=[
{开始时间:2,开始时间:2,结束时间:3,结束时间:3},
{start_lat:1,start_lng:1,end_lat:2,end_lng:2},
{开始时间:3,开始时间:3,结束时间:4,结束时间:4}
];
函数orderedSegments(开始,段){
var结果=[],
段=开始,
我
而((i=indexOfClosestSegment(segment,segments))!=-1){
结果.推(段=段.拼接(i,1)[0]);
}
返回结果;
}
函数indexOfClosestSegment(段,段){
var i=0,
len=段数。长度,
segIndex=-1,
距离,最小距离;
对于(;i

请注意,这些点是地理坐标,您需要使用 球面距离算法,不是琐碎的毕达哥拉斯。我认为通用汽车公司 为其数据结构提供此类辅助函数;当然 该算法仍将在不同的距离下工作 实施–@贝吉


我认为DFS是可以的,并将访问的有序分支列表转移到下一个递归。
在每个递归中,选择最后一个分支,并使用每个未侦听的分支进行递归

不确定您是否需要排序算法或最短路径算法。。。?如果你实现了一个像Dijkstra的最短路径算法,它会吐出最短路径,那么你只需要确保你保持一个对数组中原始位置的引用,以便像你想要的那样“排序”。也许画一张图?我很难理解你想做什么。mdkes我在主帖子中添加了一张图片。WilliamGaul我认为这是两者的结合?这里不需要排序算法。要在支腿之间线性循环,不需要阵列,但需要知道支腿之间的连接。根据您的实际数据,这更接近于旅行推销员的问题,而不是图表搜索。但是,如果最近的开始总是下一个,那么计算起来就很简单了。谢谢plalx,但这并不完全是我想要的。这将工作的起点和终点的坐标重叠,但我没有这样做,他们之间有一个很大的差距,我需要生成他们之间的“连接器”。这里有一张图片试图更好地说明:@andro1d我相应地更新了我的答案。我希望这就是你想要的。非常感谢你,那正是我想要的!你是一个冠军。请注意,这些点是地理坐标,你需要使用a,而不是普通的毕达哥拉斯。我认为GM为他们的数据结构提供了这样的帮助函数;当然,您的算法仍然可以使用不同的
距离来实现。@Bergi是的,我使用的是这个距离公式的一个变体:
start -> array[1] -> array[0] -> end
var start = { end_lat: 1, end_lng: 1 },
    end = { start_lat: 4, start_lng: 4 },
    coordsBetween = [
        { start_lat: 2, start_lng: 2, end_lat: 3, end_lng: 3  },
        { start_lat: 1, start_lng: 1, end_lat: 2, end_lng: 2  },
        { start_lat: 3, start_lng: 3, end_lat: 4, end_lng: 4  }
    ];

function orderedCoords(start, coords) {
    var result = [],
        point = start;

    while (point = coords.filter(function (item) {
        return item.start_lat === point.end_lat
        && item.start_lng === point.end_lng;
    })[0]) {
        result.push(point);
    }   
    return result;
}

console.log(orderedCoords(start, coordsBetween));
var start = { end_lat: 1, end_lng: 1 },
    end = { start_lat: 4, start_lng: 4 },
    segments = [
        { start_lat: 2, start_lng: 2, end_lat: 3, end_lng: 3  },
        { start_lat: 1, start_lng: 1, end_lat: 2, end_lng: 2  },
        { start_lat: 3, start_lng: 3, end_lat: 4, end_lng: 4  }
    ];

function orderedSegments(start, segments) {
    var result = [],
        segment = start,
        i;

    while ((i = indexOfClosestSegment(segment, segments)) !== -1) {
        result.push(segment = segments.splice(i, 1)[0]);
    }

    return result;
}

function indexOfClosestSegment(segment, segments) {
    var i = 0,
        len = segments.length,
        segIndex = -1,
        tempDistance, smallestDistance;

    for (; i < len; i++) {
        if (
            (tempDistance = distanceBetween(segment, segments[i])) < smallestDistance 
            || typeof smallestDistance === 'undefined') {
            smallestDistance = tempDistance;
            segIndex = i;
        }
    }

    return segIndex;        
}

function distanceBetween(segmentA, segmentB) {
    return Math.sqrt(
        Math.pow(segmentB.start_lat - segmentA.end_lat, 2) 
        + Math.pow(segmentB.start_lng - segmentA.end_lng, 2)
    );
}

console.log(orderedSegments(start, segments));