Я хотел бы оптимизировать драматический один из моих алгоритмов, я попытаюсь объяснить это наилучшим образом, что я могу.
Объект
Мы находимся в двумерной евклидовой системе в момент времени t = 0. В этой системе есть два объекта: O1 и O2.
O1 и O2 расположены соответственно в точке PA и ПК.
O1 перемещается со скоростью и известной скоростью в направлении точки PB. Объект остановится, когда он достигнет PB.
O2 может двигаться со скоростью и известной скоростью, отличной от O1, в любом направлении. В момент времени 0 O2 имеет нет направления, нам нужно будет найти его для него.
Известные параметры:
- O1: положение, направление, скорость
- O2: положение, скорость
Вот небольшая диаграмма системы.
Мы хотели бы найти точку PI и время ti, для которого: Position of O1 at the time ti = Position of O2 at the time ti = PI
. Затем мы сделаем объект O2 перемещенным в точку PI, чтобы получить O2 direction.
Когда выбрано направление O2 (точка PI), и оба объекта O1 и O2 находятся в движении, объекты никогда не будут останавливаться или ждать друг для друга.
В этом случае результат будет примерно таким (PI отмечен D на этом снимке).
Алгоритм
Вы можете найти рабочий алгоритм, написанный в JS, в jsfiddle, это также отличный способ понять проблему.
В это время я использую простой алгоритм, который работает, но может выполнять много операций, я получаю лучшее время пересечения и получаю позицию пересечения впоследствии.
Чтобы получить это время, я проверю позицию O1 в данный момент и проверьте, может ли O2 в данный момент перейти на эту позицию. Если O2 не смог достичь объекта во времени, мы увеличим время на 150%, однако, если O2 может пересечь линию O1-B в то время, мы уменьшим время на 50%.
В конце концов, после многих приближений мы найдем идеальное время, когда оба объекта могут встретиться.
псевдокод
function getOptimalIntersectionTime time
if distance between O1 and O2 at the time `time` < 1
return time
else if O2 could not reach the object O1 at the time `time`
return getOptimalIntersectionTime time * 1.5
else
return getOptimalIntersectionTime time * 0.5
Почему я беспокоюсь?
Мой алгоритм работает, но в некоторых случаях (например, "Обратный случай" в jsFiddle) для нахождения наилучшей точки потребуется большое количество исчислений.
В этом jsFiddle мы используем небольшие значения для позиции (от -1000 до 1000) и скорости (1-200), но этот алгоритм является более медленным с большими числами.
Я знаю, что преждевременная оптимизация - плохая идея, но я нахожусь в конце проекта (который состоит из вложений/выбора баз данных и анализа данных, включая этот алгоритм, который называется много раз), и этот алгоритм занимает до 80 % от ресурсов системы проекта в некоторых случаях, поэтому улучшение может действительно улучшить стабильность и отзывчивость системы.