LINUX.ORG.RU

Многопоточный поиск пути

 , ,


1

3

Умные люди, помогите, пожалуйста, с алгоритмом:

  • Имеем 7 измерений, по которым можно двигаться, с шагом в 1.
  • Одномоментно можно пройти только по одному измерению.
  • При переходе надо сделать расчет можем ли мы здесь находиться, если можно, ок, идем дальше, нельзя - по этому пути прохода нет.
  • Начальные условия задаются при старте, как далеко можно зайти зависит только от начальных условий

Хочу узнать как далеко можно зайти. Если делать в один поток, то вырисовывается простая рекурсивная функция, которая рано или поздно все обойдет.
Думал как можно распараллелить сие, пока что пришел к мысли хранить контейнер с мьютексом для хранения уже пройденных состояний. При переходе проверять наличие исследуемого элемента в контейнере. Если его нет, тут же добавлять его в контейнер, чтобы другие потоки не делали дублирующую работу.
Вопрос собственно в том, а не фигню ли я придумал?
Интересует есть ли более быстрые/простые способы запускать от 1 до N потоков, чтобы они не делали лишную работу и не мешались друг другу


Ответ на: комментарий от ia666

Если все потоки пишут часто, ты упираешься в один лок, на котором ждут все. С этой стороны вряд ли можно что-то сделать.

Но ты можешь попробовать отсортировать фронт так, чтобы узлы на каждый рабочий поток лежали рядом, как можно меньше соседствовали с задачами других рабочих потоков. Примерно как окружность поделённая координатными линиями на четыре дуги — они пересекаются только в четырёх точках. Тогда можно синхронизироваться раз в ход, а максимум лишней работы будет на границах. Чем больше фронт, тем меньшую долю составляют границы.

i-rinat ★★★★★
()

БД даже на 100 милионах не нужна для 4-х гигов. Но ты не описал задачу. Думаю в 16 байт узлы можно вписать ели немного подумать зная задачу. Даже если в 20 байт всёравно влезет для 100 миллионов. Для пару миллиардов конечно нужна отдельная оптимизация. Я всёравно врядли БД применял. Делил бы на кластеры поля и сохранял бы в файлы.

HIS
()
Ответ на: комментарий от HIS

Ок, давай представим это как заход в гору.
В каждой точке ты можешь узнать насколько метров ты поднимешься, известна начальная высота 1 вершины, с которой начинается обход.
Проходя по любому из 12 измерениям с шагом равным 1, ты повторяешь это же действие и получишь список вершин, причем какие то из них будут максимальные в плане высоты.
Границы, за которые не выйти, есть, могут быть известны заранее, но к теме хранения данных отношения не имеют.
И вот ты имеешь на каждую вершину: 12 координат, от 0 до 0xFFFF, и 2 параметра высоты(начальное и конечное), которые могут расти по мере продвижения фронта, и никогда не уменьшаются

По поводу твоей точки зрения - я согласен и всеми руками за!, что можно поместить в память, но если ужаться. Единственное, что пока что приходит на ум - это сжатие массива из координат, но я таким ни разу не занимался и не знаю будет ли от этого толк.

ia666
() автор топика
Ответ на: комментарий от ia666

по задаче нужно найти самую высокую вершину в 12 мерном пространстве?

HIS
()
Ответ на: комментарий от ia666

Если нужно найти высоту - просто расскажи какое измерение принимается за высоту. В нашем 3-х мерном пространстве обычно принято принимать за высоту измерение Y (к примеру).

HIS
()
Ответ на: комментарий от HIS

А высота в данном случае зависит от точки, от всех 12 координат. Заранее высчитать нельзя. Мб термин «высота» не совсем корректен, правильнее будет - некое значение функции в этой точке, а как оно будет изменятся от точке к точке - фиг его знает.

ia666
() автор топика
Ответ на: комментарий от i-rinat

Мысль интересная. Этот вариант надо хорошенько обдумать, сама идея очень здравая.
Спасибо.

ia666
() автор топика
Ответ на: комментарий от ia666

Расстояние и высота в нашем мире разные понятия.

Определись что тебе нужно и напиши ТЗ.

HIS
()
Ответ на: комментарий от ia666

Обычно все «кончаются» на начале написании ТЗ (Технического Задания). Что характерно для людей не понимающих, что они делают.

HIS
()
Ответ на: комментарий от HIS

Не понял каким боком тут тз. С алгоритмом я определился, тут всё ясно, по нему вопросов нету.
Сейчас есть вопрос можно ли как то сэкономить память при расчетах и собственно:

  • Имеем N пар ключ-значение.
  • Ключ - массив из 12 чисел от 0 до 0xFFFFF, ключи не повторяются.
  • Значения - число от 0 до 0xFFFFFFFF.

Есть ли способ хранить все эти данные в памяти, которая по объему меньше, чем N*(12*2+4) байт?

ia666
() автор топика
Ответ на: комментарий от ia666

Если количество узлов 100 миллионов, то 28 байт на узел + это меньше трёх гигабайт. Должно влезть в оперативку вместе с операционкой на твоём ноуте.

HIS
()
Ответ на: комментарий от ia666

К тому же это смешно решать такие задачи на ноутах с 4-мя шинами памяти :) Можно ещё в тетрадке карандашём в столбик вычислять...

А по существу сейчас нет пробем найти на «свалке» рабочий комп с практически любым объёмом памяти.

Компрессирование-декомпрессирование данных на лету будет жутко тормозить работу алгоритма.

HIS
()
Ответ на: комментарий от HIS

Оспадетыбожемой.

Да напиши ты функцию поиска максимума, которая принимает указатель на целевую функцию, раз такой умный. ТС подставит туда своё, и задача будет решена. Там же ты и сможешь продемонстрировать свои крутые алгоритмы на деле.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Опять пришёл командовать и приказывать.

Ты же у нас тут самый умный. Демонстрируй.

Я уже сказал, что волновой алгоритм самое оно. Но его тоже нужно понять как применить и подпилить под задачу. Задача не описана. Потому куда пилить я не знаю.

Умнег великий тут нашёлся.

HIS
()
Ответ на: комментарий от i-rinat

Спасибо, проблему я решил, и с памятью вроде тоже
Большое спасибо всем, кто участвовал в обсуждении. Я узнал много нового.

P.S. Если знаешь по LMDB, подскажи, безопасно ли использовать mdb_dbi_open в режиме MDB_NOLOCK(или с стандартом) с учетом того, что у каждого потока своя база и он единственный кто будет работать с этой базой
Документация говорит, что данная функция вообще не должна одновременно вызываться больше 1 раза на весь процессс и все транзакции. Это слегка смущает, не ясно это ограничение на отдельную базу или вообще на MDB_env целиком.

ia666
() автор топика
Ответ на: комментарий от ia666

Насколько я понял текст, там нет ограничения на количество вызовов. Только сказано, что транзакции, в которых вызывается mdb_dbi_open, не должны пересекаться во времени.

В документации у них есть минус: чтобы её понять, нужно читать код. Без этого тяжело, формулировки там не всегда удачные.

Например, если открыть два раза базу (одинаковые имена), то закрывать нужно только один раз, потому что mdb_dbi_open возвращает один и тот же MDB_dbi, и число ссылок не подсчитывает. Вообще об этом сказано, но многие с первого раза понимают неправильно.

у каждого потока своя база

Кажется, лок на запись там общий на весь environment, так что отдельные базы могут оказаться бессмысленными.

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от i-rinat

Нашел рассылку:

*Opening* a DBI handle can only be done by one transaction. *Using* an open DBI handle can be done by any transactions.

Вопрос снят, формулировки у них там дествительно не очень.
Судя по коду, похоже ты прав, блокировка на запись идет на environment целиком. Еще раз спасибо!

ia666
() автор топика
Ответ на: комментарий от Einstok_Fair

Виртуальность вершин графа не мешает алгоритму A*

алгоритму А* мешать может отсутствие внятной эвристики. Без нее это просто волновой алгоритм (поиск в ширину), который при большом количестве генерируемых узлов засрёт память. Если эвристика есть (ну тоесть можно предсказывать насколько далеко заведет тот или иной выбор), есть надежда, что расход памяти будет значительно меньше размера графа.

q0tw4 ★★★★
()
Ответ на: комментарий от q0tw4

алгоритму А* мешать может отсутствие внятной эвристики. Без нее это просто волновой алгоритм (поиск в ширину), который при большом количестве генерируемых узлов засрёт память.

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

Может ты просто не понимаешь как этот алгоритм работает?

HIS
()
Ответ на: комментарий от HIS

Всего на одну размерность меньше, чем граф. Тоесть в седьмом измерении будет поверхность с 6 измерениями. Наверно многовато будет. Поиск в глубину тратит всего одно измерение на стек возвратов, тоесть корень шестой степени от затрат волны .

q0tw4 ★★★★
()
Ответ на: комментарий от q0tw4

Нет. Волновой алгоритм работает в самом графе и просто проставляет индексы. В простом виде в целочисленном. Ты подучи немного опять. Да?

Да. Я «перепридумал» этот метод, которым можно оптимизировать пути в реальном 3Д мире. Всёравно там на порядок меньше данных в алгоритме по отношению к системе в которой ищется путь.

HIS
()
Ответ на: комментарий от q0tw4

А узел может быть описан в «энных» измерениях кучами безразмерных чисел.

HIS
()
Ответ на: комментарий от HIS

в моём алгоритме только одно значение — дистанция для каждого узла

А хранить ты их в астрале будешь, ага.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Тогда совсем не оптимально получается, из астрала можно сразу лучший путь получить за O(1)

slaykovsky ★★★
()
Ответ на: комментарий от i-rinat

Для умощнения моей версии.

В 3Д нашего пространства. Расстояние — это одно число. А не все 3 числа координат.

Будешь спорить?

HIS
()
Ответ на: комментарий от HIS

Ты не понял вопроса, придумал вместо него другой, и пытаешься отвечать на этот свой вопрос. Обсуждение не имеет смысла, пока ты не вникнешь в суть высказанных аргументов.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Я обосновал, что волновой алгоритм занимает меньше места чем сама задача.

Ты можешь внятно сказать что тебе не так?

HIS
()
Ответ на: комментарий от i-rinat

А то что расстояние (в нормальной задаче) - это просто кратчайший путь от одного узла к другому ты не подумал?.

HIS
()
Ответ на: комментарий от i-rinat

В любом случае кучи «непонтных» дополнительных состовляющих будут точно на порядки больше чем нужды на поиск по алгоритму.

HIS
()
Ответ на: комментарий от HIS

Волновой алгоритм работает в самом графе и просто проставляет индексы

Дак графа нету. Он не влезет в память. Есть только функция, которая берет на вход узел и выдает на выходе соседний узел. Вот я и пытаюсь сделать алгоритм, тратящий O(n^(1/7)) памяти. Если бы нас устроил O(n), то можно было бы не париться.

q0tw4 ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.