Алгоритм, чтобы найти, что большинство эффективных перемещений прибывает в данную точку

(Это не точно проблема, которую я имею, но это изоморфно, и я думаю, что это объяснение будет самым легким для других понять.)

Предположим, что у меня есть ряд точек в n-мерном пространстве. Используя 3 размера, например:

A : [1,2,3]
B : [4,5,6]
C : [7,8,9]

У меня также есть ряд векторов, которые описывают возможные перемещения в этом пространстве:

V1 : [+1,0,-1]
V2 : [+2,0,0]

Теперь, учитывая точку dest, я должен найти начальную точку p и ряд перемещений векторов, которые принесут мне к dest самым эффективным способом. Эффективность определяется как "наименьшее количество количества перемещений", не обязательно "наименьшее количество линейного расстояния": допустимо выбрать p, который это далее от dest, чем другие кандидаты, если набор перемещения таков, что можно добраться там в меньшем количестве перемещений. Векторы в перемещениях должны быть строгим подмножеством доступных векторов; Вы не можете использовать тот же вектор несколько раз, если это не появляется несколько раз во входном наборе.

Мой вход содержит ~100 начальных точек и возможно ~10 векторов, и мое количество размеров ~20. Начальные точки и доступные векторы будут зафиксированы в течение времени жизни приложения, но я буду находить пути для многих, многих различных точек dest. Я хочу оптимизировать для скорости, не памяти. Приемлемо для алгоритма не удаться (не найти возможные пути к dest).

Обновите w/Принятое Решение

Я принял решение, очень похожее на то, отмеченное ниже, как "принято". Я выполняю итерации по всем точкам и векторам и создаю список всех достижимых точек с маршрутами для достижения их. Я преобразовываю этот список в хеш <dest, p+vectors>, выбирая самый короткий набор векторов для каждого пункта назначения. (Существует также определенная оптимизация для размера хэша, который не релевантен здесь.) Последующие dest поиски происходят в постоянное время.

8
задан JSBձոգչ 25 January 2010 в 21:57
поделиться

6 ответов

На самом деле, учитывая, что у вас есть около 10 векторов, вы можете, для данного dest точка, рассчитайте только 1024 "целей" из подмножества векторов - например, каждый Достижимое пространство, с информацией о том, какой набор движений попадает там. Это может быть «медленным» или «быстрым» в зависимости от контекста (он не абсурдно быстро, если это реализуется на параллельном вычислительном устройстве, такое как GPU).

Наличие всех наборов, которые попадают туда, вы можете рассчитать дорожки намного быстрее, тогда вы можете выбрать точку, от которого можно добраться до DEST в не менее низких ходах, выбирая из подмножества те, которые либо ваш запрос, либо дальше.

(Благодаря Стринцу)

6
ответ дан 5 December 2019 в 08:52
поделиться
-- 2648644-

Я считаю, что вы сможете сделать обобщенное применение алгоритма поиска агоритма пути поиска A * (AKKA a aka Star). Нет причин, почему это не может быть сделано в Nth Space. Он Gaurateess самый оптимальный путь, если вы можете описать стоимость каждого движения.

http://en.wikipedia.org/wiki/a*_search_algorithm

5
ответ дан 5 December 2019 в 08:52
поделиться

Итак, вы хотите найти подмножество вашего набора векторов, так что подмножество суммирует до заданного значения. В 1 измерении это называется проблемой подмножества и является NP-Complete.

К счастью, у вас есть только ~ 10 векторов, поэтому ваш размер проблем на самом деле довольно маленький и увлекательный. Начните, просто попробовав все 2 ^ 10 комбинации перемещения для каждой отправной точки и выбирая лучший. Затем работайте оттуда ищет простых оптимизаций.

Некоторые легкие оптимизации, которые могут работать:

  • приоритеты приоритеты присяжных подмножеств, включая векторы, указанные в правильном направлении.
  • встречаются в середине. Используйте хэш-таблицу для хранения всех точек, доступных с использованием подмножеств первой половины вашего набора движения, и посмотрите, сможете ли вы ударить любой, используя вторую половину вашего движения, начиная с конца.
  • Вернитесь назад. У вас есть только одна конечная точка, поэтому HASH все доступные начать точки оттуда, затем проверяют все возможные пунты запуска.
  • Согласимость
5
ответ дан 5 December 2019 в 08:52
поделиться
protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
  string currentUrl = HttpContext.Current.Request.Path.ToLower();
  if(currentUrl.StartsWith("http://mydomain"))
  {
    Response.Status = "301 Moved Permanently";
    Response.AddHeader("Location", currentUrl.Replace("http://mydomain", "http://www.mydomain"));
    Response.End();
  }
}
-121--4180387-

Учитывая, что у вас есть начальные точки и фиксированный набор векторов, можете ли вы вычислить список всех доступных пунктов назначения, а затем просто найти заданный пункт назначения?

2
ответ дан 5 December 2019 в 08:52
поделиться

Как государства Корнел, у вас есть максимум 2 ^ 10 = 1024 доступных направлений. Таким образом, вы могли бы просто генерировать все достижимые места назначения в 2 ^ N Time (где n - количество векторов) простым рекурсивным поколением. Это будет достаточно быстро, конечно. Тем не менее, давайте предположим, что вы хотели растянуть его.

Вы можете оптимизировать его до (2 ^ (N / 2 + 1)), используя решение для среднего значения. Вы разделяете вектор, установленный на два подмножества и генерируете все достижимые места назначения для каждого подмножества независимо. Затем вы повторяете через один набор доступных направлений, и для каждого местоположения найдите разницу между ним и целевым назначением. Если этот векторный вектор находится в другом наборе доступных направлений, у вас есть решение: объединить два, и вы закончите. Трудность здесь находится в эффективном запросе, если у вас есть необходимый вектор в другом наборе: это можно сделать в O (1) время с помощью хеш-таблица.

Это o (2 ^ (N / 2)) Время на подмножество, раз два подмножества дают O (2 ^ (N / 2 + 1)). Чтобы присоединиться к двум, это O (2 ^ (N / 2)) время. Так что дает нам o (2 ^ (N / 2 + 1)) время в целом.

1
ответ дан 5 December 2019 в 08:52
поделиться
protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
  string currentUrl = HttpContext.Current.Request.Path.ToLower();
  if(currentUrl.StartsWith("http://mydomain"))
  {
    Response.Status = "301 Moved Permanently";
    Response.AddHeader("Location", currentUrl.Replace("http://mydomain", "http://www.mydomain"));
    Response.End();
  }
}
-121--4180387-

Я только что понял, что есть и более прямой ответ:

x = 5

def test():
    print 'x' in globals()

if __name__ == "__main__":
    test()

Итак, если «variablename» в глобалах (): оператор является присвоением иначе оператор является объявлением

-121--2878623-
  1. Начало в начале.
  2. Сделайте некоторое время
  3. Получите расстояние до места назначения
  4. Проверьте все возможные ходы и выберите тот, который находится ближе всего к месту назначения за один ход.
  5. end do

Это может колебаться вокруг пункта назначения, но приблизит вас.

0
ответ дан 5 December 2019 в 08:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: