Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 31.05.2012, 19:05   #1
mrbadge
Пользователь
 
Регистрация: 26.01.2011
Сообщений: 48
По умолчанию Поиск пути на карте

Постановка задачи:
есть несколько bmp (визуальная карта, карта трений и карта высот), все они грузятся программой, цвета пикселей задают соответственно трение и высоту. По визуальной карте движется объект (в зависимости от высоты и от трения на него действуют соответствующие силы), управление стрелками, настройки - правая кнопка мыши. Цель: доехать до красного кружка на карте. Exe прилагается, при необходимости выложу конкретные части кода.

Собственно вопрос:
необходимо сделать автоматическое движение объекта до цели по оптимальному пути (наименьший перепад высот, наименьшее трение). Для этого хотел использовать алгоритм Дейкстры. На небольших графах работает хорошо, но здесь не могу представить карту в виде матрицы смежности: просто не хватает памяти. (Вершины графа - пиксели карты, каждый пиксель-вершина связана с соседними пикселями). Структура "двумерный массив, где в каждой ячейки хранится восемь записей типа: с кем есть связь, ее цена" для карты 800х600 занимает >70 мб, полноценная матрица смежности - более двух ГБ.

Возможно, стоить использовать для этой цели другой алгоритм?

Буду рад любому совету, заранее благодарен.
Вложения
Тип файла: zip МКБ.zip (529.8 Кб, 21 просмотров)
mrbadge вне форума Ответить с цитированием
Старый 31.05.2012, 20:10   #2
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

Р какой матрице смежности Вы говорите?
Ячейка квадратной сетки имеет либо 4 либо 8 соседей в зависимости от введенной метрики.
800х600 - это полмиллиона ячеек. Для карты проходимости достаточно пол 4 байта на ячейку - 2 Мбайта.
Пусть даже для совсем уж скрупулезного учета нам требуется еще добавить проходимость ребер - еще 4 Мб.
Итого 6 Мб.

По собственному опыту при надлежащей реализации карта 256х256 полностью просчитывается за 30 мс на процессоре с тактовой частотой 166 МГц.
s-andriano вне форума Ответить с цитированием
Старый 01.06.2012, 07:29   #3
crazy horse
ios developer
Старожил
 
Аватар для crazy horse
 
Регистрация: 16.11.2007
Сообщений: 2,885
По умолчанию

Еще два дополнения:
1. Делать ячейку величиной в пиксель - маразм. Обычно карта местности, в конечном итоге, строится исходя из сетки.
2. Вроде бы как необязательно держать в памяти сразу все вершины с весами. Можно карту разбить на куски, согласуясь с эвристикой. Тем более, если персонаж двигается не из левого верхнего угла в правый нижний, - нет никакого смысла сразу генерировать сетку для всей карты.
Делайте что хотите, но чтобы через полчаса в лесу было светло, сухо и медведь!
crazy horse вне форума Ответить с цитированием
Старый 01.06.2012, 11:39   #4
mrbadge
Пользователь
 
Регистрация: 26.01.2011
Сообщений: 48
По умолчанию

Цитата:
Сообщение от s-andriano Посмотреть сообщение
Р какой матрице смежности Вы говорите?
Матрица смежности. Имеем 800*600=480 000 вершин. В МС будет 480 000*480 000=очень много вершин. Кроме того, вес перехода - число типа Real.

Цитата:
Сообщение от s-andriano Посмотреть сообщение
По собственному опыту при надлежащей реализации карта 256х256 полностью просчитывается за 30 мс на процессоре с тактовой частотой 166 МГц.
Какой алгоритм Вы использовали?

Смотрел реализации волнового алгоритма, но везде клетки карты не связаны между собой (т.е., например, лес имеет цену прохода 10, вода - препятствие и т.д.). У меня же такого нет, цену имеет переход из одной ячейки в другую (подъем в гору, спуск). Из-за этого приходится (другого пока не придумал) использовать граф.

Цитата:
Сообщение от crazy horse Посмотреть сообщение
1. Делать ячейку величиной в пиксель - маразм. Обычно карта местности, в конечном итоге, строится исходя из сетки.
Да, думаю, попробую так: размеры объекта 32х32, получится примерно четверть миллиона ячеек в МС. Но тут другая проблема: препятствия могут быть небольшими по сравнения с размерами такой ячейки(белая полоса на карте - высокий подъем), если считать некоторую среднюю цену перехода, то либо эта клетка станет совсем недоступной, либо объект упрется в это препятствие.

Цитата:
Сообщение от crazy horse Посмотреть сообщение
2. Вроде бы как необязательно держать в памяти сразу все вершины с весами. Можно карту разбить на куски, согласуясь с эвристикой.
Но ведь нет гарантии, что оптимальный путь найдется на квадратной части карты, где один угол - объект, противоположный - цель, возможно, придется возвращаться назад, объезжая какую-то "горную цепь"
mrbadge вне форума Ответить с цитированием
Старый 01.06.2012, 12:23   #5
mrbadge
Пользователь
 
Регистрация: 26.01.2011
Сообщений: 48
По умолчанию

Алгоритм А* выглядит довольно привлекательным для этой цели. Не могли бы Вы помочь разобраться с эвристической оценкой пути от рассматриваемой клетки до цели? Такой подход будет эвристической оценкой?
Эвр. оценка
(Суммируем цены перехода на оранжевые клетки начиная от текущей, игнорируя препятствия)
mrbadge вне форума Ответить с цитированием
Старый 01.06.2012, 13:24   #6
crazy horse
ios developer
Старожил
 
Аватар для crazy horse
 
Регистрация: 16.11.2007
Сообщений: 2,885
По умолчанию

Цитата:
Алгоритм А* выглядит довольно привлекательным для этой цели.
Дейкстр и есть частный случай A*, так что много разбираться не придется. Насколько я помню, эвристика добавляется одной-двумя строчками кода. Вот попавшаяся выкладка: http://www.policyalmanac.org/games/a...torial_rus.htm Если проблема останется, - я могу порыться в своей литературе, часть которой посвящена именно поиску пути применительно к играм, в практическом аспекте этого дела. Правда, на английском и для экшнскрипта, но суть все равно одна.
Делайте что хотите, но чтобы через полчаса в лесу было светло, сухо и медведь!
crazy horse вне форума Ответить с цитированием
Старый 01.06.2012, 13:51   #7
mrbadge
Пользователь
 
Регистрация: 26.01.2011
Сообщений: 48
По умолчанию

Спасибо, в статье, что Вы предложили, нашел ссылку конкретно про эвристику:
http://www.policyalmanac.org/games/heuristics.htm
mrbadge вне форума Ответить с цитированием
Старый 01.06.2012, 14:00   #8
crazy horse
ios developer
Старожил
 
Аватар для crazy horse
 
Регистрация: 16.11.2007
Сообщений: 2,885
По умолчанию

Еще пришел в голову вариант взять сетку с изначально крупным шагом, смежные с препятствиями ячейки дробить на более мелкие. Самой идее это не противоречит, но надо учитывать сокращение дистанции при переходе.
Делайте что хотите, но чтобы через полчаса в лесу было светло, сухо и медведь!
crazy horse вне форума Ответить с цитированием
Старый 01.06.2012, 14:20   #9
mrbadge
Пользователь
 
Регистрация: 26.01.2011
Сообщений: 48
По умолчанию

Хотелось бы еще уточнить: для хранения открытых и закрытых вершин, карты пройденных вершин достаточно будет использовать, например, двунаправленный список, где в каждой ячейке будет храниться стоимость пути, эвр. оценка, их сумма и родитель? Или стоит использовать что-то другое?
mrbadge вне форума Ответить с цитированием
Старый 01.06.2012, 14:30   #10
crazy horse
ios developer
Старожил
 
Аватар для crazy horse
 
Регистрация: 16.11.2007
Сообщений: 2,885
По умолчанию

Цитата из линка, приведенного выше:
Цитата:
7. Реализация открытого списка: Это один из наиболее важных элементов в алгоритме A*. Каждый раз при обращении к открытому списку вам необходимо найти вершину с наименьшей стоимостью F. Существует несколько способов это сделать. Вы можете сохранять элементы пути когда потребуется и просто проматривать весь открытый список каждый раз, когда надо извлечь элемент с наименьшей стоимостью F. Это простой метод, но очень медленный для длинных путей. Он может быть улучшен использованием сортированного списка и тогда нуждно будет просто выбрать первый элемент списка - это и будет элемент с наименьшей стоимостью F. Когда я писал свою программу этот метод был первым, который я использовал.

Это будет быстро работать на маленьких картах, но это не оптимальное решение. Серьезные программисты A*, которые стремятся действительно к впечатляющей скорости, используют что-то, что называются "двоичными кучами" (binary heaps) и это то, что я использовал в своей программе. Это будет по крайней мере в 2-3 раза быстрее в большинстве случаев и намного быстрее (в 10 и больше раз) на длинных путях. Если вы заинтересовались, прочтите мою статью Using Binary Heaps in A* Pathfinding.
Делайте что хотите, но чтобы через полчаса в лесу было светло, сухо и медведь!
crazy horse вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
поиск пути Nikita1111 Visual C++ 1 09.02.2012 00:44
Поиск абонента по на карте номеру телефона. sexybabeonwings Общие вопросы Delphi 1 26.09.2009 16:39