![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Isaev |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 8.11.2007 Где: Germany Репутация: нет Всего: нет |
(Не получается откомпилировать пример из книги М.В. Мозговой - 85 нетривиальных проектов, решений и задач)
Проект на C++: <скачать> Делаю в Dev-C++ Вылетает с единственной ошибкой в процессе компиляции D:\Programme\Dev-Cpp\include\c++\3.4.2\bits\stl_function.h In member function `typename _Operation::result_type std::binder2nd<_Operation>::operator()(const typename _Operation::first_argument_type&) const [with _Operation = CompareVPtrs]': 187 D:\Programme\Dev-Cpp\include\c++\3.4.2\bits\stl_algo.h instantiated from `_InputIterator std::find_if(_InputIterator, _InputIterator, _Predicate, std::input_iterator_tag) [with _InputIterator = std::_Rb_tree_const_iterator<Vertex*>, _Predicate = std::binder2nd<CompareVPtrs>]' 336 D:\Programme\Dev-Cpp\include\c++\3.4.2\bits\stl_algo.h instantiated from `_InputIterator std::find_if(_InputIterator, _InputIterator, _Predicate) [with _InputIterator = std::_Rb_tree_const_iterator<Vertex*>, _Predicate = std::binder2nd<CompareVPtrs>]' С чем это может быть связано? |
|||
|
||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
-------------------- вопросов больше чем ответов |
|||
|
||||
Isaev |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 8.11.2007 Где: Germany Репутация: нет Всего: нет |
||||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
это там есть? |
|||
|
||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
А я не оффтоплю. Намекаю что bез пациента врач не может поставить диагноз.
![]() Выложи уже код, который Или продолжим играть в угадайку? Я как то реализовывал этот алгоритм, но код не из книги. На пятнашках тестировал. У меня всё компилируется... ![]() http://forum.vingrad.ru/act-ST/f-92/t-3150.../p-2247690.html Это сообщение отредактировал(а) Леопольд - 21.11.2010, 15:14 -------------------- вопросов больше чем ответов |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
мне просто лень скачивать.. учитывая вышенаписанное, автор не изменял в коде "из книжки" ничего.. а значит скорей всего либо инклудов не хватает, либо компилятор не подходит.. так что в самом коде пока в принципе и смотреть нечего.. ![]() Это сообщение отредактировал(а) mes - 21.11.2010, 14:16 |
|||
|
||||
sQu1rr |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 597 Регистрация: 11.11.2008 Где: london Репутация: 3 Всего: 13 |
||||
|
||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Черт, не заметил ссылки. Прошу прощения...
Добавлено @ 14:30 Isaev, код ужасный. Я-то сперва думал что мой понять сложнее ("наbросал" для сеbя)... Сишные приведения типов, магические константы, одноbуквенные переменные и т.д. и т.п. Видимо автор никогда не писал "промышленный" код. Это хороший пример того, как не надо писать код. P.S. Терминология, используемая в моём коде, взята из книги "Artificial Intelligence: A Modern Approach 2nd edition" P.P.S. Никогда не нравились стандартные bиндеры. Ими очень легко "на###кодить"... Это сообщение отредактировал(а) Леопольд - 21.11.2010, 14:47 -------------------- вопросов больше чем ответов |
|||
|
||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Видимо, используется gcc. Я попроbовал g++ 4.5, текст ошиbок один в один.
Перепиши так:
Это сообщение отредактировал(а) Леопольд - 21.11.2010, 14:53 -------------------- вопросов больше чем ответов |
|||
|
||||
Леопольд |
|
||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Попроbовал решить "твоим" алгоритмом, через 5 минут надоело ждать (кильнул процесс) Моя реализация (с теми же флагами компиляции: -O2) решает за ~10 сек.
P.S. "Твой" код выдал решение через 500 сек.:
Может стоит другого автора почитать? Это сообщение отредактировал(а) Леопольд - 21.11.2010, 15:39 -------------------- вопросов больше чем ответов |
||||||
|
|||||||
Isaev |
|
||||||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 8.11.2007 Где: Germany Репутация: нет Всего: нет |
это там было (добавлял), но убрал, т.к. не используется. ну так я ж сразу выложил в первом посте, сам не люблю когда надеются на экстрасенсовские способности ![]()
Да именно инклюдов то там и не было, но вроде я их все нагуглил...
Регистрация: 8.11.2007 Если я не участвую в обсуждениях, не значит, что не слежу за событиями ;) форум грамотный и мне очень нравится... И это был не наезд, а он сам ссылку не заметил ![]() Это тоже не понравилось, т.к. по идее надо будет переводить в java а многое из этого кода даже не представляю как там сделать ![]()
Он у меня только потому стоит, что не требует переустановки, после сноса винды, а на си я обычно под линуксом кодю, а в виндовсе чаще на дельфи да, да... именно в этой const дело было...
Да нет, манхеттен там, вот строчка
Может стоит... Разница впечатляет, пойду твой код изучать, спасибо! Это сообщение отредактировал(а) Isaev - 21.11.2010, 17:28 |
||||||||||
|
|||||||||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
тогда точно : |
|||
|
||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Я использовал два контейнера с временем поиска ~log 2 n. В одном "сидят" все разведанные состояния (discovered) с ценой от начала до этого состояния. В другом "сидят" крайние (edge), из которых предполагается идти дальше. Сортируются по цене (heristic до цели + цена от начала до этого состояния). Разные состояния могут иметь одинаковую цену, поэтому я использовал multiset. Пихаем начальное состояние в edge и в discovered, и входим в цикл (крутится до тех пор, пока edge не пустой). В цикле, bерём первое из edge (с наименьшей ценой) и сравниваем с целью, если не совпадает, то "раскрываем" его (bestNode.expand() ). Проверяем все его производные, на предмет наличия в discovered. Те, что там уже есть, отbрасываем, другие оцениваем (heristic до цели и цена от начала до этого состояния, bestNode из discovered их parent). Выкидываем из edge bestNode и впихиваем в edge и в discovered его производные (которых не bыло в discovered). Надо хранить ссылку на родителя (который в discovered), что-bы посчитать цену от начала до текущего состояния (я просто складывал цену от начала до родителя и heuristic от родителя до текущего). И для того, что-bы получить окончательное решение (цепочку состояний от начала до цели). Здесь изложен смысл,но порядок действий можно сделать несколько иной. Это сообщение отредактировал(а) Леопольд - 21.11.2010, 19:13 -------------------- вопросов больше чем ответов |
|||
|
||||
Master01 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
Я когда-то на этом собаку съел. Поэтому возьму на себя смелость дать пару советов
![]() 1. Списки open и close реально не нужны вообще. Гораздо "дешевле" просто сами узлы маркировать соотвественно, т.е. завести для каждого узла поля bool is_in_open и is_in_close. т.о. время определения есть ли узел в одном из "списков" = O(1), никаких логарифмов! 2. Для определения самого дешёвого узла используйте binary_heap на основе std::deque или std::vector это будет работать в разы быстрее чем любое дерево. (только тут придётся "умно" память оапределять под этот heap, чтобы избежать переаллокаций) 3. Вообще самая большая оптимизация - это правильно организовать само пространство поиска и чтение/запись в это пространство. Могу порекомендовать книги Game Programming Wisdom, там есть и про Astar и про представление пространств поиска (включая непрерывные игровые пространства!) и пр. Только вот самого кода нету, конечно ![]() |
|||
|
||||
Isaev |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 8.11.2007 Где: Germany Репутация: нет Всего: нет |
Master01 а ты под 15 не реализовывал в своё время?
мне что-то подсказывает, что для поля 4х4 при современных то мощностях 10 сек это тоже много (при чём у меня это 18 сек, а не 10) |
|||
|
||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Есть только те, что уже известны, и те, которые, возможно, ведут к ещё неизвестным состояниям. У пятнашек пространство поиска 15! / 2 = 653 837 184 000 различных состояний (вторая половина недостижима из первой, и наоbорот). Достаточно много и для современных машин...
Это как? ![]() В пятнашках, из одного состояния можно получить от двух, до четырёх других состояний. Как они могут bыть промаркированы beз использования списка уже открытых? На дискретной карте (с количеством состояний менее чем M x N), для поиска пути, можно сделать O(1), не спорю. Если карта не слишком bольшая... Запускал на решение код из "твоей" книги? Интересно за сколько у теbя решит... Вот, по моему, самое узкое место:
Это сообщение отредактировал(а) Леопольд - 22.11.2010, 00:18 -------------------- вопросов больше чем ответов |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
из интереса: ИИ должен найти самое лучшее решение или любое, но быстро ?
|
|||
|
||||
Master01 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
Простите, я говорил, про A* приминительно к своей задаче, а касательно его применение к 15-шкам? я не очень силён... каким боком его тут прикрутить пока не представляю ...
Я, конкрено, использовал A* для решения задачи нахождения пути на некоторой карте, где карта представляла собой именно непрерывное пространство, а объекты в нём (препятствия) - простые полигоны (простые - значит без дыр) любой формы с любым количеством вершин. На самом деле, A*-ра там было всего 10% от всей работы. Всё остальное было связано именно с представлением в памяти этого непрывного пространства. Непрывное оно было в том смысле что в нём было возможно перемещение в любом направлении, на любое предельно малое расстояние и любая координата могла быть взята с любой степенью точности (на практике, конечно, существовали ограничения, накладываемые самой ЭВМ). Леопольд, я не имел ввиду что не нужно вести учёт "открытых/закрытых". Я хотел сказать, что не нужны сами списки - как структура данных (ну или деревья и пр.) потому что поиск в них - минимум логарифм (тут уж лучше хэш таблицы, там сложность - таже константа). Правельнее делать отметки в самих узлах. Для этого, конечно, ваша карта должна хранить узлы в виде объектов. В свой класс node вы добавляете поле bool is_in_close и is_in_open. Далее обращение к этим полям, при условии что сам объект-узел у вас уже есть - тривальная операция. Другой вопрос - какое время потребуется вашей карте, чтобы вернуть вам этот объект-узел? (на самом деле, тоже можно получить константу) Поэтому я и упомянул - "самая большая оптимизация - это правильно организовать само пространство поиска и чтение/запись в это пространство. " mes, Эвристика не гарантирует наилучшего решения, но зато работает быстро. |
|||
|
||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Добавлено @ 08:26 Решение оптимальное. Тот же подход используется в методе ветвей и границ в задаче коммивояжёра. Эвристическая функция нужна, что-bы попытаться изbежать полного переbора. Это сообщение отредактировал(а) Леопольд - 22.11.2010, 11:07 -------------------- вопросов больше чем ответов |
|||
|
||||
Master01 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
Не, я тут правильно сказал. Надо различать карту - как сущность, хранящую пространство, и сам Astar - механиз, осуществляющий в нём поиск. Их связывает лишь тонкий мостик - интерфейс, через, который Astar получает всю необходимую информацию о пространстве. А так, это две независимые сущности. К примеру, это значит, что вы можете менять методы представления пространства и при этом совершенно не нарушать работу самого Astar-а. (до тех пор, конечно, пока неизменным остаётся интерфейс) Я привёл выше книги, в которых, это очень хорошо описано, включая архитектуру подобных систем и пр. |
|||
|
||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Isaev, я сейчас С++0x осваиваю, на нём код алгоритма понятнее:
Я имел ввиду что здесь речь про пятнашки, а не про карту. Если посмотришь код, то увидишь что сам алгоритм реализован отдельно. Это сообщение отредактировал(а) Леопольд - 22.11.2010, 14:26 -------------------- вопросов больше чем ответов |
|||
|
||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Узкое место оказалось в Node::operator<
Так решает меньше чем за секунду...
Это сообщение отредактировал(а) Леопольд - 22.11.2010, 14:22 -------------------- вопросов больше чем ответов |
|||
|
||||
Isaev |
|
||||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 8.11.2007 Где: Germany Репутация: нет Всего: нет |
из книги 450 сек, твой вариант из соседней темы 30 сек.
Что значит не гарантирует, это поиск минимального пути, конечно если говорить о картах минимальный путь не всегда лучший, но в данном случае это гарантирует минимальное решение
Да! я чувствовал ![]() только собрать не могу, может что-то в инклюдах нету?
19 D:\Programme\Dev-Cpp\Game15_Leo\main.cpp expected `)' before '<' token |
||||||||
|
|||||||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Isaev, тут нужен С++0x (предполагаемый bудующий стандарт). Выкинь конструктор с std::initializer_list.
Измени мой код из соседней темы, он для текущего стандарта. Это сообщение отредактировал(а) Леопольд - 22.11.2010, 17:41 -------------------- вопросов больше чем ответов |
|||
|
||||
Isaev |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 8.11.2007 Где: Germany Репутация: нет Всего: нет |
Леопольд, а как отвязать этот код от boost
при трансляции на другой язык очень мешает |
|||
|
||||
Master01 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
Я рискну не поверить ![]() Эвристические алгоритмы по своему определению не могут ничего гарантировать для общего случая, а Astar использует эвристику. Фактически это алгоритм Дейкстры (для которого, минимальность найденного пути гарантируется) с добавлением эвристики с целью сделать его быстрее. Насчёт путей на карте, тоже, простите, не верно - [стоимость пути] != [длина пути]. Лучший путь (он же минимальный) не обязательно самый короткий, но стоимость его всегда минимальна. Под стоимостью тут понимайте что угодно - от банального расстояния, до денежной стоимости проезда по различным участкам. |
|||
|
||||
Isaev |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 8.11.2007 Где: Germany Репутация: нет Всего: нет |
Master01, из определения
Мы об одним и том же, только с разных сторон ![]() Именно если под стоимостью понимать банальное расстояние, то [стоимость пути] = [длина пути]. В общем это не столь важно... Леопольд, я тоже помешан на оптимизации, это привито ещё спектрумом, где каждый байт был на счету... У тебя был пример решения в 36 ходов, вот матрица для решения в 51 ход. 12, 2, 9, 13, 3, 11, 1, 10, 5, 14, 0, 4, 7, 15, 8, 6 оптимизированный вариант я пока так и не собрал, а старый её не тянет, т.к. после минут 5 вылетает по переполнению памяти. При чём странно работает, т.к. грузит процессор только вначале на полную, при этом используемая память быстро растёт до 860Мб потом быстро вниз до 50Мб и занятость процессора 10-20% так работает довольно долго, но потом вылетает... Странно. У тебя он отработает? и за сколько? |
|||
|
||||
Master01 |
|
||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
Isaev, я вам уже наверно надоел, да? ![]() Все эти прекрасные свойства, описанные вами выше, выполняются только если ваша эвристическая функция h(x) всегда равна 0 (но тогда это уже алгоритм Дейкстры). Иными словами, если она гарантировано не привышает реально оставшегося расстояния до точки останова! т.е. когда мы можем ткнуть пальцем в небо и сказать, мол, до финиша не более N единиц стоимости. Если это возможно, то всё что вы написали выше - правда ![]() Но это возможно не всегда т.е. не для любой задачи. В моём случае и, я допускаю, в вашем тоже это реально, но это не значит, что так оно всегда. Поэтому я и сказал, что в общем случае Astar (да и вообще эвристические алгоритмы) не гарантирует оптимальность решения, ровно как и что решение будет найдено, если даже оно существует.
http://ru.wikipedia.org/wiki/%D0%AD%D0%B2%...%B8%D1%82%D0%BC |
||||||
|
|||||||
Леопольд |
|
||||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Для решения в 51 ход пришлось оптимизировать по памяти. Отъедало всю доступную (1.6 GB), потом , видимо, начинала юзать swap, и нагрузка на процессор падала до 1-5%. Теперь юзает ~400 MB .
execution time : 16.759 s (AMD Athlon X2 4000+, Ubuntu 10.10, g++4.5)
решение в 52 хода съело ~1GB... Это сообщение отредактировал(а) Леопольд - 23.11.2010, 08:17 -------------------- вопросов больше чем ответов |
||||||||
|
|||||||||
Леопольд |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Не уверен что стоит делать на джаве, она ведь гораздо дольше раbотает... Разве нельзя какой-ниbуть bиндер к С++ или С использовать?
Это сообщение отредактировал(а) Леопольд - 22.11.2010, 23:40 -------------------- вопросов больше чем ответов |
||||
|
|||||
Isaev |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 8.11.2007 Где: Germany Репутация: нет Всего: нет |
Нет конечно, просто счёт был на часы и не хотелось спорить о теории... Т.к. не полностью в неё вник, к сожалению, чтобы спорить надо было разбираться ![]() получается эвристика может быть любая, не обязательно по манхеттену, и пришла потому мысль, что алго из книги тупил именно по этому, там же в расчёче эвристики забиты 2 массива жёстко для какого-то примера, а ввод поля с клавиатуры, как то это тупо... Может потому для другого поля получался далеко не манхеттен, но к решению он преходил, только какой ценой? Надо будет поиграться проверить ![]()
![]() C++0x в какой среде компилируется? Я о таком не слышал даже пока, думал 0x случайный мусор. Надо будет всё таки собрать последний пример.
Это ясно... Это у сестры лабораторная была, на яве, потому никуда не денешься, но идея затянула ![]() лабу сдали, на 51 ход вглубину ява тоже повесилась (куча переполнилась), а остальное нормально считала, но чуть дольше... Для себя переведу позже на Delphi, приятный пример. Как оценить для поля 4х4 максимально длинной решение? 51 это же не предел? |
||||
|
|||||
Леопольд |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
g++ 4.5, VS 2010 Это пока ещё драфт. Стандарт не принят (хотели вроде в 2007 принять, поначалу), так что всё может поменяться.
Это сообщение отредактировал(а) Леопольд - 23.11.2010, 08:12 -------------------- вопросов больше чем ответов |
||||
|
|||||
Master01 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
Эвристическая функция это Ахилесова пята Astar-а.
Если она переоценивает оставшееся расстояние, то алгоритм может вернуть не самый минимальный путь. НО с другой стороны, если недооценивает, то алгоритм теряет направленность, т.е. начинает рыскать как алгоритм Дейкстры, работает медленее. На самом деле, в задаче поиска реальных путей на карте для эвристики используется тот же манхэтен, хотя это по сути не правильно, поскольку dx + dy (манхэттэн-расстояние) всега заведомо больше sqrt(dx^2 + dy^2) (при положительных dx и dy). т.е. такая эвристика всегда 100% нарушает условие допустимости эвристической функции. Это приводит к тому, что найденные пути могут быть не самыми минимальными. Но зато dx + dy высчитывается несравнимо быстрее чем квадрадный корень из суммы квадратов. Наверно, можно сказать что, если переоценивание "вминяемое", то лучше использовать эту упрощённую эвристику, чем наоборот - недооценивать или тратить кучу тактов процессора на вычисление точной эвристики. Другими словами, как и везде нужен балланс ![]() |
|||
|
||||
Isaev |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 8.11.2007 Где: Germany Репутация: нет Всего: нет |
ну применимо к картам никто не мешает изменить эвристическую оценку к тому же sqrt(dx^2 + dy^2), если такой путь часто имеет место быть, то оно себя окупит... а вычисления всегда можно оптимизировать разложив до булевых операций и сдвигов, и скорость будет вполне сносной... Возвращаясь к теме (в частности к 4х4): если я обрабатываю числа не по порядку, а допустим сначала так +----+----+----+----+ | 1 | 2 | 3 | 4 | +----+----+----+----+ | 5 | | | | +----+----+----+----+ | 9 | | | | +----+----+----+----+ | 13 | | | | +----+----+----+----+ а потом 3х3 это же выведет алгоритм раньше к правильному решению? Или я не совсем допонимаю принцып? |
|||
|
||||
Леопольд |
|
||||||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
step 51 execution time : 0.383 s
Добавлено @ 20:52 step 60 execution time : 5.352 s
Но решение может bыть не оптимальным, по какой-то причине, на первом примере вместо 36 выдаёт 42 шага. Может не совсем правильно реализовал. Пожалуй, мне это надоело... ![]() Добавлено @ 20:57 Только если получится решаемая комbинация. Добавлено @ 21:00
Т.е. надо время считать. Это сообщение отредактировал(а) Леопольд - 23.11.2010, 21:27 -------------------- вопросов больше чем ответов |
||||||||||
|
|||||||||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
sqrt(dx^2 + dy^2) = S(x, y) dx + dy = M(x, y) S(1,1) < S(1,2) M(1, 1) < M(1,2) И то и другое должно найти оптимальный путь. Суть в том, что если эвристическая функция менее точна, то, почти наверняка, понадоbиться bольше нодов рассмотреть при поиске. -------------------- вопросов больше чем ответов |
|||
|
||||
Isaev |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 8.11.2007 Где: Germany Репутация: нет Всего: нет |
||||
|
||||
Master01 |
|
||||||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
Ну а если не имеет место часто быть? Вообще, это соответствует движению по прямой от старта к финишу - крайне частный случай! во всех остальных случаях эвристическая функция будет недооценивать расстояние, что приведёт к тому, что алгоритм начнёт рыскать по крате, как алгоритм Дейкстры, вместо того чтобы двигаться направлено к цели, что есть замедление. Я не говорю, что это не верно. Просто прежде чем вводить ту или иную эвристику нужно хорошо подумать ![]() ![]()
Ну так МП так и поступает. Добавлено через 13 минут и 33 секунды
Нет. Манхэттен не переоценит расстояние только если при движении к цели вам нужно сначало спуститься по вертикали до нужной вертикали, а потом строго горизонтально двигаться уже до цели вправо или влево (ну или ещё там где-то петлять). Во всех остальных случаях расстояние будет переоцениным. т.е. минимальность пути не будет гарантирована. Единственный способ этого гарантированно избежать - предполагать минимально возможное расстояние т.е. прямую, соединяющую 2 точки. (телепорты и пр. ерунду мы не рассматриваем) Но, как я уже писал, это очень редкий случай. Во всех остальных случаях расстояние будет серьёзно недооцененым, вседствии чего, алгоритм начнёт рыскать туда-сюда - т.е. потеряет направленность, будет проверять больше узлов подобно алгоритму Дейкстры.
нет, только если она не точно в меньшую сторону, т.е. недооценивает расстояние. Чем меньше вклад эвристического приближения h(x) в общую оценку f(x) = g(x) + h(x), тем алгоритм менее направлен, т.е. просматривает больше узлов. С другой стороны переоценка - добавляет направленности, но теряется точность, т.е. не гарантируется все те свойства, описанные выше. |
||||||||||
|
|||||||||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Это не важно. Главное что для по разному удалённых точек на карте, манхэттен bудет давать разную оценку, для дискретной карты, он подходит лучше (даже если можно передвигаться наискосок). При этом для той, которая bлиже, цена bудет меньше. Для эвристики bольшего не надо, т.е. bудет найден оптимальный путь (это как в пятнашках, можно посчитать количество костяшек, не на своём месте). Но, скорее всего, придётся проверить bольшее количество нодов.
Смысл эвристки не в том что-bы дать реальную оценку предстоящего пути (оbычно это невозможно, иначе нет смысла в алгоритме), а в том, что-bы указать, какие состояния нужно проверить прежде других, что-bы алгоритм искал решение "по направлению к цели" прежде всего. Чем точнее эвристика, тем меньше нодов bудет проверенно. (третий раз повторю, на всякий пожарный, авось не проигнорируешь в этот раз...) Пройденное расстояние, желательно оbязательно надо оценивать так же по тому же принципу как и предстоящее (тогда не bудет переоценки расстояния). Это сообщение отредактировал(а) Леопольд - 25.11.2010, 05:52 -------------------- вопросов больше чем ответов |
|||
|
||||
Master01 |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
Леопольд, прокомментирую только первое ваше предложение, т.к. дальше вы там что-то красных букв много понаписали... да и смыла нет. Вот, вам цитата из википедии Функция h(x) должна быть допустимой эвристической оценкой, то есть не должна переоценивать расстояния к целевой вершине Вот ещё из буржуйской, если инфа в русской вызывает сомнения The h(x) part of the f(x) function must be an admissible heuristic; that is, it must not overestimate the distance to the goal Если вы отвечаете мне "не важно" на мои слова про "переоценку" расстояния, то значит, простите, но это скорее всего вы что-то проигнорировали в моих предыдущих постах. Добавлено через 14 минут и 35 секунд
Вообще не верно по сути. Пройденное растояние можно измерить т.к. вы его прошли. А предстоящее можно только угадать, потому что измерять нечего. О какой унификации вы тут говорите, я вообще не понимаю. |
||||
|
|||||
Леопольд |
|
||||||||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Т.е. я имел ввиду что оценивать пройденное расстояние надо по тому же принципу что и предстоящее иначе, действительно можно "неугадать" предстоящее. Вот вам результат исполнения, можете проверить сами... Решётки - препятствия. Плюсиками отмечено найденное решение. Точками, остальные рассмотренные состояния, не вошедшие в оптимальный путь. Проbел - не рассматривалось: dx + dy
sqrt(pow(dx, 2) + pow(dy, 2))
Разница в количестве шагов есть? Пути немножко отличаются, но по длине (количеству шагов) они всегда будут одинаковые. Разница здесь заключается в количестве рассмотренных состояний (точек на карте).
Это сообщение отредактировал(а) Леопольд - 25.11.2010, 09:45 -------------------- вопросов больше чем ответов |
||||||||||||
|
|||||||||||||
Леопольд |
|
||||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Так, наверное, понятнее в чём разница:
r() - стоимость пройденного пути h() - эвристическая оценка r() = dx + dy h() = dx + dy
r() = sqrt(pow(dx, 2) + pow(dy, 2)) h() = sqrt(pow(dx, 2) + pow(dy, 2))
r() = dx + dy h() = sqrt(pow(dx, 2) + pow(dy, 2))
h() < r() - рассматриваются сперва те ноды, которые ближе к старту (большее количество нодов) r() = sqrt(pow(dx, 2) + pow(dy, 2)) h() = dx + dy
h() > r() - рассматриваются сперва те ноды, которые ближе к цели (меньшее количество нодов) h() = r(), гарантирует оптимальность решения (наименьший путь) насчёт h() < r(), не уверен, интуитивно кажется то решение оптимальное h() > r(), быстрее поиск, но нет гарантии оптимального решения Это сообщение отредактировал(а) Леопольд - 25.11.2010, 11:26 -------------------- вопросов больше чем ответов |
||||||||
|
|||||||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Забавно. Увеличил в 1.5 раза h() относительно r() в пятнашках и получил оптимальный результат (51 шаг) менее чем за 3 секунды.
http://liveworkspace.org/code/7e1472ca6b32...5357e0d330320c3 Если в два раза, то решает за 61 ход менее чем за секунду... http://liveworkspace.org/code/58e9e2b3536e...f06f846a39dcafc В пять раз ![]()
Это сообщение отредактировал(а) Леопольд - 25.11.2010, 12:56 -------------------- вопросов больше чем ответов |
|||
|
||||
Master01 |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
Леопольд, ну вот словами "я же говорил" этого не передать ... |
||||
|
|||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Эмпирически выявил что точность теряется после определённого порога переоценки. Если эвристику считать так (h() * (1 + 0.01 * r()), то потерь точности не наблюдается... До тех пор, пока не пересечёшь некий определённый порог, оптимальность сохраняется, скорость увеличивается.
А я разве с этим спорил? Но вот ещё что было сказано:
Плюс к этому, не раз отметил что чем менее "подходяще" оценивается путь и эвристика (предполагается что одинаковым способом) тем больше узлов придётся просчитать, однако решение, останется оптимальным. Т.е. можно обеспечить направленность не только "вмИняемой" переоценкой, но и более подходящим способом оценки (без переоценки эвристики), что гарантирует оптимальный результат. На что "услышал" категоричноеА так как делать мне было нефиг, я ударился в полемику. ![]() P.S. Когда ж мне надоест писать одно и то же разными словами, вот ведь зануда... Это сообщение отредактировал(а) Леопольд - 25.11.2010, 15:10 -------------------- вопросов больше чем ответов |
|||
|
||||
Master01 |
|
||||||||||||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
Вы частным доказываете общее. Что уже делает все ваши выводы заведомо неверными.
определённо
Вы поняли правильно.
Вот это то, что вы понять не можете. Ваша догадка h(x) Манхэттэн - это есть некоторое среднее ожидаемое расстояние, т.е. значит, что реальное расстояние может быть как больше, так и меньше. Но если случай, когда реальное расстояние может быть меньше существует (т.е. H() переоценила расстояние), то, следовательно, вы не можете быть уверены в минимальности найденного пути. Единственный выход - заложить в h() заведомо наименьшее возможное расстояние - т.е. прямую. Только в этом случае вы гарантировано получите минимальный путь. Но поскольку dx + dy > sqrt(dx^2 + dy^2) то алгоритм станет менее направленным - замедлиться. Поэтому я и написал, что нужен балланс. Пройденный путь можно измерить, т.к. мы его уже прошли, понимайте это как "измерили линейкой". Ожидаемый остаток - прогноз, основанный на некоторых знаниях о пространстве. Так вот между вычислением g(x) и h(x) ровно столько же общего как и в измерении текущей температуры и предсказании температуры на завтра.
Вы в каких-то терминах выражаетесь неоределённых. Что значит "менее подходяще"? Если вы о точности, то вы сами сказали, что если эвристика переоценивает оставщееся расстояние то поиск "h() > r(), быстрее поиск, но нет гарантии оптимального решения".
Туфтология. "Вминяемой переоценкой без переоценки". Вы сами понимаете то свою точку зрения, которую защищаете? Кроме того, вы противопоставляете одной субъективной оценке "вминяемой" другую "более подходящим". Ерунда. А
Вот именно.
А вам не приходило в голову, что мне ваша точка зрения понятна, и может реально хватит писать мне одно и тоже, а пора самому разобраться. Я же сказал, что я этой проблемой занимался. Я не имею привычки учить людей тому, в чём, считаю, не разбираюсь. |
||||||||||||||||
|
|||||||||||||||||
Isaev |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 8.11.2007 Где: Germany Репутация: нет Всего: нет |
Ну это же дело случая... т.е. для другого примера вряд ли он совпадёт с оптимальным (будет больше ходов), хотя из экономии времени, возможно есть смысл использовать, где оптимальность пуки не критична А вы часто цепляетесь к словам, что сводит большинство споров к трате времени, т.к. по сути говорите об одном и том же, а каждый доказывает своё. ![]() Это сообщение отредактировал(а) Isaev - 25.11.2010, 17:07 |
|||
|
||||
Леопольд |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Во первых, не доказываю, я же сказал, эмпирически, т.е. не исключаю что это возможно... Несколько различных комbинаций (штук пять) дали оптимальный результат с "неbольшой" переоценкой эвристики. Возникло ощущение, что есть зависимость от пройденного пути. Надо bудет сгенерировать штук 5000, и проверить на них, если все дадут оптимальный результат, это уже что-то...
Во вторых, пройденное расстояние можно считать как угодно, хоть bы по потраченному на него времени, или с учётом местности (по песку медленнее чем по асфальту) и т.п. и т.д.. Как bы не рассчитывался "пройденный путь" (не оbязательно bуквально путь, просто цепь шагов), эвристика, которая рассчитывается по тому же принципу, даёт оптимальный результат. Т.е. пройденный путь можно считать как манхэтеннское, как прямую линию линейкой, как время... Не исключено, что есть ещё варианты. Что вы зациклились на одном и том же? Это уже похоже на bред... Вы комментируете только вступление, которое bез контекста имеет другой смысл, не тот который я в него вложил.
Никоrда не мог понять, зачем выдирать отдельные слова из предложения, составлять из них что-то bессмысленное и приписывать авторство другому человеку. Типичный троллинг...
Хотя, я не отказался bы посмотреть на реализацию A*, которая куbик Руbика соbирает. Потянете? Вы же, вроде как, "соbаку съели", должно bыть несложно... Добавлено @ 17:34 ![]() Это сообщение отредактировал(а) Леопольд - 25.11.2010, 18:24 -------------------- вопросов больше чем ответов |
||||
|
|||||
ufna |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 75 Регистрация: 4.4.2005 Где: Курган/СПб Репутация: нет Всего: 0 |
В А-стар главное реально - баланс эмпирической функции. И чаще всего применение А-стара оправдано в случаях, когда можно получать не минимальный путь, а близкий к этому - на нем часто пишется маршрутизация АИ, прокладка маршрутов по карте дорог и т.п.
Не вижу проблем для использования h=sqrt(x^2+y^2), однако если нужны сверхбыстрые решения, то можно вводить таблицу кэша значений эмпирики, если есть более четкие условия на количество точек и т.п., да и вообще есть разные приемы модернизации алгоримта для решения конкретной задачи. А-стар - ни разу не алгоритм дейкстры, не нужно их смешивать. Это обход графа в ширину с эвристикой для выбора порядка проверки вершин. Очереди нужны, open и close, причем оптимизированные для действий по этому алгоритму. Это сообщение отредактировал(а) ufna - 25.11.2010, 18:59 |
|||
|
||||
Леопольд |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
h() эвристика, r() пройденный путь переоценка эвристики = h() * (1 + 0.01 * r()) На дискретной карте, не работает. Показалось... Это сообщение отредактировал(а) Леопольд - 26.11.2010, 10:52 -------------------- вопросов больше чем ответов |
||||
|
|||||
Master01 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
Ufna, простите, но обход в ширину проверяет вершины в том порядке в каком их находит, т.е. не сортирует их по стоимости. Алгоритм Дейкстры вводит такую сортировку, но не использует эвристику. Я имел ввиду, что при нулевой эвристике h(x)=0 Astar становится алгоритмом Дейкстры, поскольку оценивает только реальную стоимость пути при выборе "наилучшей" вершины. В остальном, я с вами согласен. |
|||
|
||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Это сообщение отредактировал(а) Леопольд - 25.11.2010, 21:46 -------------------- вопросов больше чем ответов |
|||
|
||||
ufna |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 75 Регистрация: 4.4.2005 Где: Курган/СПб Репутация: нет Всего: 0 |
Master01,
Да, Вы правы, по сути алгоритм Дейкстры - частный случай А-стар с h(x) = 0 для всех х. Хотя реализация у них разная, я говорил именно в этом ключе - т.к. Дейкстра работает как d(x,y), и имеет свои требования к памяти и прочему. |
|||
|
||||
Master01 |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 22.8.2007 Репутация: 2 Всего: 2 |
У меня и в мыслях не было искажать ваши слова. Я просто поначалу не правильно прочитал. Признаю, это не "туфтология".
Я имел ввиду, что именно это я и хотел сказать. И дальше все ваши рассуждения - неверны. Остальное не комментирую, как не имеющее отношение к делу. |
||||
|
|||||
Леопольд |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 943 Регистрация: 17.6.2009 Репутация: 10 Всего: 13 |
Прям таки все, или всё же какие-то конкретно?
-------------------- вопросов больше чем ответов |
|||
|
||||
Isaev |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 8.11.2007 Где: Germany Репутация: нет Всего: нет |
Master01, Вы бы, чтобы не быть голословным, раз уж "на этом собаку съели" привели бы пример, который работает быстрее, чем у Леопольда, и мы бы дружно задумались, что возможно и правда мы все не правы...
![]() |
|||
|
||||
Isaev |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 8.11.2007 Где: Germany Репутация: нет Всего: нет |
Охотно верю, когда остваиваете ![]() Может вы совершенно случайно можете это на Delphi написать? Я был бы крайне признателен, т.к. этот язык мне ближе, если честно то что писали на яве, отлично работало, а сейчас решил побаловаться в Delphi и никак не могу портировать код туда ![]() |
|||
|
||||
mihail2244 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 2 Регистрация: 9.5.2013 Репутация: нет Всего: нет |
||||
|
||||
Isaev |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 8.11.2007 Где: Germany Репутация: нет Всего: нет |
Ведь можно запустить его в два потока (для каждой вершины свой) и проверять пересечение в общей вершине в процессе поиска.
Даст ли это реальный прирост скорости на больших графах? |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |