一种克服距离矩阵 API 带来的元素限制的算法
An algorithm to overcome the elements limit posed by the distance matrix API
首先,我进行了 Whosebug 搜索,所以我知道这是新的。请继续阅读:
所以我有一个包含 9 个位置的字符串数组,需要找出它们之间的距离以输入到算法中。我使用了 Google 的距离矩阵 API 并将这些地方作为起点和终点传递,它返回一个响应,我制作了一个 n x n 方阵,如下所示:
0 3201 4584 4821 1628 1218 1786 4738 4897
3122 0 1400 1638 1797 2756 3323 5310 5472
4523 1400 0 237 3198 4156 4723 6711 6872
4760 1638 237 0 3435 4394 4961 6948 7110
1324 1846 3247 3485 0 958 1525 3931 4093
932 2854 4273 4510 1002 0 567 4873 5034
1499 3422 4840 5078 1569 567 0 5440 5602
5061 5359 6760 6998 4019 4959 5526 0 161
5233 5531 6931 7169 4190 5130 5697 171 0
在此,按行和按列都是地名,即相同顺序的相同位置数组,这就是为什么对角线元素为零(尽管实际上 Google 的响应由于某种原因并不总是 0)因为从它自己去一个地方应该是 0.
现在的问题是 Google 距离矩阵 API 每个请求有 25 个元素的限制,其中起点和终点的总和不应超过 25。所以因为我'm 使用相同的起点和终点,这会将其分解为最多 12 个元素。但是我正在构建的应用程序需要计算超过 12 个地方,所以我在考虑一个解决方法。
一个想法是使用这种逻辑(这不是真正的代码,我写它只是为了显示algorithm/pseudocode):
if(count(places) > 12) {
distanceMatrix = []
for(place in placesArray) {
distanceMatrix[] = apiCall->(place, placesArray); // apiCall(origin, dest)
}
} else {
response = apiCall->(placesArray, placesArray); // apiCall(origin, dest)
distancesMatrix = convertResponseToDistancesMatrix(response)
}
所以基本上在这种情况下,如果地点数超过 12 个地点,它会取而代之的是一个 for 循环,它将一个地点作为起点,所有地点作为目的地。这样我就可以将限制从 12 -> 25 移动,因为它计算 1 个起点和 24 个目的地。问题是仍然超过 24,它就无法工作。那么有没有其他方法可以克服这个问题呢?我知道必须有一些方法可以让我发出多个请求并填充矩阵,我想知道如何,因为我无法想到算法。
我不确定您执行此操作的频率如何,但请注意,随着元素数量的增加,这可能会很快加起来。来自 their site:
"the number of origins times the number of destinations equals the number of elements.",元素起价为 $.01/每个。因此,如果您要处理 25 个起点和 25 个目的地,那么 625 个元素需要 6.25 美元。对于 100,它将是 100 美元。对于 200,它将是 400 美元。对于 1000,这将是 $10,000。
如果您仍想继续,这里有一些伪代码可以告诉您如何执行此操作(假设包括 apiCall 在内的所有内容都是同步的,并且结果在二维数组中):
/**
* @param locations Array of locations you want to consider
*/
var queryDistances = function(locations) {
var locationDistances = [];
var placesToConsiderAtOnce = 12;
//Get the location groups to consider
var locationGroups;
for(var i = 0; i < locations.length; i++){
var locationArraysIndex = Math.floor(i / placesToConsiderAtOnce);
locationGroups[locationArraysIndex] = locationGroups[locationArraysIndex] || [];
locationGroups[locationArraysIndex].push(locations[i]);
}
//Process all combinations of the location groups
for(var i = 0; i < locationGroups.length; i++){
for(var j = 0; j < locationGroups.length; j++){
var originArray = locationGroups[i];
var destinationArray = locationGroups[j];
var results = apiCall(originArray, destinationArray);
for(var k = 0; k < originArray.length; k++){
for(var l = 0; l < destinationArray.length; l++){
var locationDistancesFirstIndex = k + i * placesToConsiderAtOnce;
var locationDistancesSecondIndex = l + j * placesToConsiderAtOnce;
locationDistances[locationDistancesFirstIndex] = locationDistances[locationDistancesFirstIndex] || [];
locationDistances[locationDistancesSecondIndex] = results[k][l];
}
}
}
}
return locationDistances;
};
首先,我进行了 Whosebug 搜索,所以我知道这是新的。请继续阅读:
所以我有一个包含 9 个位置的字符串数组,需要找出它们之间的距离以输入到算法中。我使用了 Google 的距离矩阵 API 并将这些地方作为起点和终点传递,它返回一个响应,我制作了一个 n x n 方阵,如下所示:
0 3201 4584 4821 1628 1218 1786 4738 4897
3122 0 1400 1638 1797 2756 3323 5310 5472
4523 1400 0 237 3198 4156 4723 6711 6872
4760 1638 237 0 3435 4394 4961 6948 7110
1324 1846 3247 3485 0 958 1525 3931 4093
932 2854 4273 4510 1002 0 567 4873 5034
1499 3422 4840 5078 1569 567 0 5440 5602
5061 5359 6760 6998 4019 4959 5526 0 161
5233 5531 6931 7169 4190 5130 5697 171 0
在此,按行和按列都是地名,即相同顺序的相同位置数组,这就是为什么对角线元素为零(尽管实际上 Google 的响应由于某种原因并不总是 0)因为从它自己去一个地方应该是 0.
现在的问题是 Google 距离矩阵 API 每个请求有 25 个元素的限制,其中起点和终点的总和不应超过 25。所以因为我'm 使用相同的起点和终点,这会将其分解为最多 12 个元素。但是我正在构建的应用程序需要计算超过 12 个地方,所以我在考虑一个解决方法。
一个想法是使用这种逻辑(这不是真正的代码,我写它只是为了显示algorithm/pseudocode):
if(count(places) > 12) {
distanceMatrix = []
for(place in placesArray) {
distanceMatrix[] = apiCall->(place, placesArray); // apiCall(origin, dest)
}
} else {
response = apiCall->(placesArray, placesArray); // apiCall(origin, dest)
distancesMatrix = convertResponseToDistancesMatrix(response)
}
所以基本上在这种情况下,如果地点数超过 12 个地点,它会取而代之的是一个 for 循环,它将一个地点作为起点,所有地点作为目的地。这样我就可以将限制从 12 -> 25 移动,因为它计算 1 个起点和 24 个目的地。问题是仍然超过 24,它就无法工作。那么有没有其他方法可以克服这个问题呢?我知道必须有一些方法可以让我发出多个请求并填充矩阵,我想知道如何,因为我无法想到算法。
我不确定您执行此操作的频率如何,但请注意,随着元素数量的增加,这可能会很快加起来。来自 their site:
"the number of origins times the number of destinations equals the number of elements.",元素起价为 $.01/每个。因此,如果您要处理 25 个起点和 25 个目的地,那么 625 个元素需要 6.25 美元。对于 100,它将是 100 美元。对于 200,它将是 400 美元。对于 1000,这将是 $10,000。
如果您仍想继续,这里有一些伪代码可以告诉您如何执行此操作(假设包括 apiCall 在内的所有内容都是同步的,并且结果在二维数组中):
/**
* @param locations Array of locations you want to consider
*/
var queryDistances = function(locations) {
var locationDistances = [];
var placesToConsiderAtOnce = 12;
//Get the location groups to consider
var locationGroups;
for(var i = 0; i < locations.length; i++){
var locationArraysIndex = Math.floor(i / placesToConsiderAtOnce);
locationGroups[locationArraysIndex] = locationGroups[locationArraysIndex] || [];
locationGroups[locationArraysIndex].push(locations[i]);
}
//Process all combinations of the location groups
for(var i = 0; i < locationGroups.length; i++){
for(var j = 0; j < locationGroups.length; j++){
var originArray = locationGroups[i];
var destinationArray = locationGroups[j];
var results = apiCall(originArray, destinationArray);
for(var k = 0; k < originArray.length; k++){
for(var l = 0; l < destinationArray.length; l++){
var locationDistancesFirstIndex = k + i * placesToConsiderAtOnce;
var locationDistancesSecondIndex = l + j * placesToConsiderAtOnce;
locationDistances[locationDistancesFirstIndex] = locationDistances[locationDistancesFirstIndex] || [];
locationDistances[locationDistancesSecondIndex] = results[k][l];
}
}
}
}
return locationDistances;
};