Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.94/34: Рейтинг темы: голосов - 34, средняя оценка - 4.94
3 / 3 / 1
Регистрация: 04.04.2017
Сообщений: 59

Волновой алгоритм поиска (Алгоритм A* / Алгоритм А стар)

04.04.2017, 18:43. Показов 6559. Ответов 1

Студворк — интернет-сервис помощи студентам
Хочу разработать алгоритм для решения головоломки с подвижными дисками (перестановочная головоломка).
Определение. Перестано́вочные головоло́мки — головоломки, состоящие из множества подвижных элементов, которые могут занимать определённые места в головоломке и переводиться с места на место по определённым правилам. Подвижными элементами могут быть разноцветные шарики, кубики, фишки с буквами или цифрами, диски(ссылка из Википедии).
В общем на вход дается матрица:
Например: 8 4 3
5 0 6
1 2 7
где 0- это пустая клетка.
На выходе необходимо получить матрицу вида:
1 2 3
4 5 6
7 8 0

Насколько я понял в качестве эвристической функции необходимо использовать так называемый метод Манхеттена, где для каждого диска необходимо вычислить расстояние до его "настоящего" места.
Этот метод я смог реализовать, но так и не могу понять как реализовать сам алгоритм. Где начальная точка и что вообще нужно делать. Почитал разные статьи про этот алгоритм, но там в основном описывают этот метод на примере поиска кратчайшего пути в лабиринте (как он работает в этом примере, я разобрался), а вот как его перенести на эту задачу, понять не могу.
Заранее спасибо!
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
04.04.2017, 18:43
Ответы с готовыми решениями:

Нужен алгоритм поиска пути в этом лабиринте (будь то волновой алгоритм или алгоритм правой/левой руки )
#include "stdafx.h" #include <iostream> #include <conio.h> using namespace std; void lab () { int s1 = 0; int s2 =...

Волновой алгоритм поиска пути
Добрый день. Реализую всем известный алгоритм поиска кратчайшего пути. Но не могу понять одну вещь. Пройдя волновым методам по...

Алгоритм А* (А стар)
Хочу создать консольную игру (пишу с использованием библиотеки iostream) и мне надо реализовать движение солдата. у меня есть массив 10...

1
3 / 3 / 1
Регистрация: 04.04.2017
Сообщений: 59
07.04.2017, 22:51  [ТС]
Лучший ответ Сообщение было отмечено SatanaXIII как решение

Решение

Если кому-то может понадобиться эта информация, я смог определить метод по которому должен строиться алгоритм в этом случае.
Может я допущу какие- либо ошибки, так как это лишь мое понимание и может кому- то оно должно быть полезно.
Первым делом стоит определить что из себя представляет сам алгоритм А*. На самом деле это нечто схожее с алгоритмом Дейкстры, но добавлено еще некоторое условие, а именно эвристическая функция(f()). f() = g + h, где g - это стоимость достижения текущего узла, а h - это расстояние от текущего узла до нашей конечной цели.
за h в этом примере принято использовать метод манхеттена.
Метод Манхеттена. В этом методе необходимо найти каждую цифру, стоящую не на своем месте, посчитать сколько шагов нужно найти для достижения ее конечной позиции, и сложить все получившиеся результаты (результаты каждой цифры стоящей не на своем месте).
Например.
1 2 3
4 5 6
8 7 0
Если наш конечный результат должен выглядеть так:
1 2 3
4 5 6
7 8 0, то g у нас равно 2. Так как 7 у нас находится не на своем месте и 8 находится не на своем месте. 1 + 1 = 2.
Когда мы научились находить g для какой - либо расстановки возникает вопрос интерпретации самой доски, т.е. как доску хранить и всю информацию которая касается текущей доски.
Предлагается хранить все это в классе или структуре, где поля будут иметь следующий вид:
доска - может иметь вид матрицы или обычного массива
переменная g - для каждой промежуточной доски будет иметь свое значение
переменная h - аналогично с g
переменная f - хранит значение, возвращаемое функцией
переменная, которая хранит местоположение нуля в текущей таблице. Это важно, чуть ниже опишу почему.
указатель на родителя - необходимо для отслеживания конечного пути до цели.

Надеюсь пока все понятно.
Теперь собственно к самому алгоритму.
Алгоритм подразумевает хранение двух контейнеров:
openset - в книгах по ИИ это то, что называется переферией. То есть узлы, до которых можно дойти из текущего узла. В нашем случае узлы - это доски.
closedset - это узлы которые мы уже посетили.
openset советуется хранить в priorityqueue, так как начинать перебирать узлы нужно с узла, имеющего самый низкий показатель эвристической функции. А это ни что иное, как minheap.

Теперь нужно разобраться с тем, что же представляют из себя промежуточные доски.
Давайте представим следующую картину.
Наша входящая доска имеет вид
1 4 6
8 0 5
2 3 7
Какие варианты досок мы можем получить из текущей доски? Ответ очевиден. Это 4 разных доски, где нуль меняется с числом стоящим справа от него, слева от него, снизу от него и сверху от него. Выходит что в openset у нас попадают все "дети" текущей доски. А сама текущая доска помечается как посещенная(т.е. добавляется в closedset)
Это как раз тот случай, когда нам необходимо знать, где находится нуль. К слову если бы нуль находился в правом верхнем углу, то имелось бы всего два ребенка этой доски, так как нуль может поменяться местами лишь с числами стоящими слева от него и снизу от него.

Алгоритм А*
1)В openset помещается стартовая доска.
2)Начинаем цикл, который будет работать до тех пор, пока в openset есть какие-либо объекты
3)Извлекаем из openset элемент и сравниваем его с нашей целью. Если совпал, то отлично. Нет? Идем дальше
4)Помечаем текущую доску, как посещенную
5)Находим всех "детей" этой доски и помещаем их в openset, конечно если такой доски нет в closedset
6)Переходим к пункту 2

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

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

P.S.S. В этой задаче могут попасться доски, для которых НЕТ РЕШЕНИЯ. В самом коде можно предусмотреть этот факт и сразу вывести ответ.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.04.2017, 22:51
Помогаю со студенческими работами здесь

Волновой алгоритм (алгоритм Ли)
Здравствуйте! У кого-нибудь есть реализованный волновой алгоритм (алгоритм Ли) ? Дело в том, что я игрушку захотел написать (что-то...

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

Волновой алгоритм
Скажите почему программа зацикливается. #include<bits/stdc++.h> using namespace std; int a = { {-1, -1, -1, -1, -1, -1,...

Волновой алгоритм
Нужно реализовать волновой алгоритм поиска кратчайшего пути на поле 20*20, причем координаты начала и конца вводятся пользователем,...

Волновой алгоритм
Доброго времени суток, дорогие форумчане. Никак не додумаю волновой алгоритм, помогите, кто чем может: файл - матрица целых чисел, где...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru