Первое, что вы хотите сделать, - это уменьшить количество операций, которые вы выполняете в циклах for
. Итак, давайте начнем с анализа этого сначала, но с алгоритмической точки зрения.
В текущей реализации вы в основном вычисляете декартово произведение на наборе из 90 значений, чтобы получить новый набор, состоящий из 8100 значений.
Однако в этом наборе результатов есть ряд избыточных значений, таких как:
Набор результатов включает вычисления, в которых оба адреса используются в качестве начальногои конечное местоположение.
Расстояние между двумя адресами рассчитывается дважды;такой, что адрес A является начальным адресом, а адрес B является конечным адресом, а в другой итерации адрес A является конечным адресом, а адрес B является начальным адресом.
ПРЕДУПРЕЖДЕНИЕ: Яделая предположение, что вы проходите одно и то же расстояние во время транзита между двумя адресами независимо от направления транзита (т. е. A-to-B или B-to-A). Это может быть не так в вашем сценарии.
Вы можете устранить эти избыточности с помощью области дискретной математики, называемой комбинаторикой;более конкретно, используя эту прекрасную формулу:
Если мы допустим n = 90 и r = 2 мы получаем следующее:
Это означает, что в нашем наиболее оптимальном случае нам нужен алгоритм, который производит не более 4005 пар адресов.
С этой целью [щелкает пальцами] пришло время написать более оптимальный алгоритм! Но для наглядности и в целях краткости давайте используем меньший размер выборки из 4 адресов, состоящих из одной буквы. Следующего массива должно быть достаточно:
var addresses = ['a', 'b', 'c', 'd'];
Используя вышеупомянутую формулу, мы выводим, что есть 6 уникальных пар адресов, которые мы можем представить следующим образом:
ab bc cd
ac bd
ad
Так, как генерировать этипары?
Если вы посмотрите на приведенное выше представление, вы заметите несколько вещей:
- Количество столбцов на единицу меньше количества адресов в массиве
- В каждом последующем столбце (слева направо) количество пар адресов в столбце уменьшается на 1;то есть. Есть 3 пары, которые начинаются с «a», 2, которые начинаются с «b», 1, который начинается с «c».
- Также обратите внимание, что при переходе от одного столбца к следующему в последовательных столбцах не будет пар с начальным символом предыдущих столбцов;то есть. во втором столбце нет пар, начинающихся с «а», а в третьем столбце нет пар, начинающихся с «а» или «b»
Обобщим эти наблюдения. Учитывая массив из n адресов, мы можем сгенерировать n - 1 столбцов. Длина каждого столбца уменьшается на 1, так что в первом столбце есть пары n - 1 , во втором столбце - n - 2 пары, 3-й столбец n - 3 пары и т. д., где каждый столбец состоит из парных комбинаций, в которых пропускаются адреса из предыдущих столбцов.
На основе этих правил мы можемнастройте цикл for
следующим образом (запустите скрипт, и он сгенерирует коллекцию объектов, чьи свойства start и end представляют уникальные пары адресов):
var addresses = ['a', 'b', 'c', 'd'];
var pairs = [];
var numColumns = addresses.length - 1;
var columnHeight;
var columnIndex;
var rowIndex;
for (columnIndex = 0; columnIndex < numColumns; columnIndex++) {
columnHeight = numColumns - columnIndex;
for (rowIndex = 0; rowIndex < columnHeight; rowIndex++) {
pairs.push({
"start":addresses[columnIndex],
"end":addresses[columnIndex + rowIndex + 1]
});
}
}
console.log(pairs);
Таким образом, вышеприведенное обрабатывает алгоритмическую оптимизацию, вам нужно настроить ее для использования с вашей реализацией, но это должно послужить хорошей отправной точкой. Однако, хотя генерирование 4005 пар адресов является относительно быстрым, обработка этих пар адресов для определения расстояния, пройденного с помощью API-интерфейса Map, вероятно, будет занимать много времени.
В случае, если вам все еще удается исчерпать 30-минутную квоту выполнения сценария, вы можете рассмотреть возможность использования методов пакетной обработки, когда вы настраиваете свое приложение для выполнения вычислений на меньших пакетах пар адресов, по одному пакету за разв течение определенного периода. Вы даже можете обрабатывать несколько пакетов одновременно, если вы правильно настроили приложение. Но это пост в другой раз.