EndoCrinolog
Здравствуйте!
Представьте, что есть игра «Башня», где из разносортных кирпичей можно строить башню. Каждый промежуток времени выдаётся разное количество различных кирпичей.
У башни есть нулевая высота, которая имеет определенный тип основания. К этому типу основания может подойти только определенный вид кирпича. У кирпичей две стороны — верхняя и нижняя. Нижняя сторона — крепится к продолжению стены башни, на верхнюю — ставится новый кирпич.
Если упростить всё выше сказанное — это что-то вроде мозаики, которая строится только вверх разными элементами.
Так вот, хотелось бы узнать. Есть ли способы построения самой длинной цепочки кирпичей? Я вижу только методом перебора, когда с учетом количества доступных видов кирпичей и основания башни, генерируются множества цепочек, и выбирается самая длинная.
Самого кода алгоритма пока еще нет, планирую его написать на PHP.
Исходные параметры такие:
Массив с типами кирпичей:PHP:
‘amount’ => 0, ‘type’ => ‘1’ ), ‘amount’ => 0, ‘type’ => ‘2’ ), ‘amount’ => 0, ‘type’ => ‘3’ ), ‘amount’ => 0, ‘type’ => ‘4’ ), ‘amount’ => 0, ‘type’ => ‘5’ ), ‘amount’ => 0, ‘type’ => ‘6’ ), ‘amount’ => 0, ‘type’ => ‘7’ ), ‘amount’ => 0, ‘type’ => ‘8’ ), ‘amount’ => 0, ‘type’ => ‘9’ ), ‘amount’ => 0, ‘type’ => ’10’ ), ‘amount’ => 0, ‘type’ => ’11’ ), ‘amount’ => 0, ‘type’ => ’12’ ), ‘amount’ => 0, ‘type’ => ’13’ ), ‘amount’ => 0, ‘type’ => ’14’ ), ‘amount’ => 0, ‘type’ => ’15’ ), ‘amount’ => 0, ‘type’ => ’16’ ) );Буквы — это различные типы соединения кирпичей. Запись SA, например, обозначает, что у кирпича верхняя часть S-типа, а низ A-типа. К примеру, SA можно поставить на AZ, а AZ можно поставить на ZU, и так далее. Amount — это количество, которое можно настраивать.
Массив с типами основания башен:
PHP:
‘Z’ => ‘1_1’, ‘U’ => ‘2_1’, ‘A’ => ‘3_1’, ‘S’ => ‘4_1’ );Ну и конечно же текущий последний кирпич башни, от которого надо начать стройку:
PHP:
$CurrentTowerBase = ‘S’;И, собственно, повторяю вопрос. В данном случае можно действовать только перебором? Или есть какие-то специальные алгоритмы для создания последовательностей из разных элементов?
mkramer
Есть алгоритм, BackTracking. Рекурсивный. У Н. Вирта хорошо описан в его книге «Алгоритмы + структуры данных = программы»
EndoCrinolog
Так, интересно, будем читать
EndoCrinolog
Так, я понял, что алгоритм усложнился… По идее, на выходе должен получиться массив с массивами последовательностей кирпичей, где самая длинная и будет ответом.
Должно быть что-то вроде сетки с количеством блоков 0 — N и прогонами 0 — MКоличество M будет зависеть от того, какие последовательности были выбраны ранее.. И если все они исчерпаны, значит, больше последовательностей нет — надо вернуть..
Понимаю, что всё должно быть в рекурсиве, как мне подсказал @mkramer, но пока что-то в голову не влезает, как это осуществить…
Drunkenmunky
Почитайте-ка про теорию графов.
В частности, вас заинтересует Гамильтонова цепь.
MouseZver
Я понял )))
Ширина или высота, одна из них максимальное, известно ?
EndoCrinolog
По идее, получается граф, и мне нужно найти его максимально длинную цепочку
Максимальная цепочка (по хорошему счету) должна состоять из максимального количества кирпичей (N)
MouseZver
а не лучше каждый кирпич индексировать ?
EndoCrinolog
PHP:
( ( [type] => U|S [up] => U [down] => S ) ( [type] => U|S [up] => U [down] => S ) ( [type] => U|S [up] => U [down] => S ) ( [type] => U|S [up] => U [down] => S ) ( [type] => U|S [up] => U [down] => S ) ( [type] => U|S [up] => U [down] => S ) ( [type] => A|S [up] => A [down] => S ) ( [type] => S|S [up] => S [down] => S ) ( [type] => S|S [up] => S [down] => S ) ( [type] => S|S [up] => S [down] => S ) ( [type] => S|S [up] => S [down] => S ) ( [type] => Z|Z [up] => Z [down] => Z ) ( [type] => Z|Z [up] => Z [down] => Z ) ( [type] => Z|Z [up] => Z [down] => Z ) ( [type] => Z|Z [up] => Z [down] => Z ) ( [type] => Z|Z [up] => Z [down] => Z ) ( [type] => Z|Z [up] => Z [down] => Z ) ( [type] => Z|U [up] => Z [down] => U ) ( [type] => Z|U [up] => Z [down] => U ) ( [type] => Z|U [up] => Z [down] => U ) ( [type] => Z|A [up] => Z [down] => A ) ( [type] => Z|A [up] => Z [down] => A ) ( [type] => Z|A [up] => Z [down] => A ) ( [type] => Z|A [up] => Z [down] => A ) ( [type] => Z|A [up] => Z [down] => A ) ( [type] => Z|A [up] => Z [down] => A ) ( [type] => Z|A [up] => Z [down] => A ) ( [type] => U|Z [up] => U [down] => Z ) ( [type] => U|Z [up] => U [down] => Z ) ( [type] => U|U [up] => U [down] => U ) ( [type] => U|U [up] => U [down] => U ) ( [type] => U|U [up] => U [down] => U ) ( [type] => U|A [up] => U [down] => A ) ( [type] => U|A [up] => U [down] => A ) ( [type] => U|A [up] => U [down] => A ) ( [type] => A|Z [up] => A [down] => Z ) ( [type] => A|Z [up] => A [down] => Z ) ( [type] => A|Z [up] => A [down] => Z ) ( [type] => A|Z [up] => A [down] => Z ) ( [type] => A|U [up] => A [down] => U ) ( [type] => A|A [up] => A [down] => A ) ( [type] => A|A [up] => A [down] => A ) ( [type] => A|A [up] => A [down] => A ) ( [type] => S|Z [up] => S [down] => Z ) ( [type] => S|Z [up] => S [down] => Z ) ( [type] => S|Z [up] => S [down] => Z ) ( [type] => S|Z [up] => S [down] => Z ) ( [type] => S|Z [up] => S [down] => Z ) ( [type] => S|U [up] => S [down] => U ) ( [type] => S|U [up] => S [down] => U ) ( [type] => S|U [up] => S [down] => U ) ( [type] => S|A [up] => S [down] => A ) )Допустим… А дальше?…
EndoCrinolog
Нашел нубский вариант — рандомно ставить кирпичи, запуская повтор функции несколько тысяч раз, пока не выявится самая длинная цепочка…
MouseZver
…
EndoCrinolog
Ну не получилось у меня рекурсией(((
MouseZver
при создании нового кирпича, с более углубленным ходом, заранее в системе регистрируй его.
mkramer
@EndoCrinolog Если не получается рекурсия, значит не знаете, как она работает, за счёт чего. Загуглите «стек вызовов»