Алгоритм перемещения шариков из одного набора ведер в другой набор с наименьшим количеством ходов с учетом машины, которая может перемещать неограниченное количество шариков за один ход - PullRequest
3 голосов
/ 19 января 2020

Один из моих друзей предложил проблему, когда у вас есть n блоков (a, b, c, ..., n), каждый с определенным процентом от общего количества шаров. Затем вам дают разбивку, сколько шаров должно быть в каждом ведре к концу задачи. Вам также предоставляется машина, которая за один ход может перемещать неограниченное количество шаров из отдельного ведра в другое отдельное ведро (например, 10 шаров из ведра А в ведро C). Какой алгоритм вы бы использовали, чтобы у вас всегда было наименьшее количество возможных ходов?

Меня это озадачило. Похоже, что это можно решить с помощью расширения алгоритма Евклида, но я совершенно не уверен, как бы это решить. Я проверил очевидный ответ, пытаясь сопоставить 2 самых больших / идеальных блока проблем друг с другом, но это не работает. Любые указатели были бы полезны.

Ответы [ 2 ]

0 голосов
/ 19 января 2020

Используйте A * на графике возможных ходов с функцией heuristi c: количество ведер, отличающихся от их целевого ведра, делится на два. То есть b/2, где b - количество сегментов, в которых содержится неправильное количество.

A * часто рассматривается как алгоритм поиска пути для подобных единиц маршрутизации в игре, но он работает на любом графике, где вы можете найти heuristi c, который никогда не переоценивает расстояние до целевого узла. Самое главное, что A *, вооруженный таким heuristi c, всегда найдет кратчайший путь. Исходя из теории игр, мы можем представить граф, узлы, соединенные ссылками, где каждый узел представляет собой возможное распределение шаров между корзинами, а каждая ссылка представляет собой законный ход, который может сделать машина. Ваш начальный узел - это начальное распределение шаров. Ваш целевой узел - это целевое распределение шаров.

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

Однако мы можем добиться большего. A * просматривает график, используя heuristi c. В частности, это похоже на поиск по первому дыханию, за исключением того, что вместо следующего посещения не посещенного узла, ближайшего к начальному узлу, A * затем посещает не посещенный узел, который минимизирует g(n) + h(n), где g(n) - это длина от непосещенного узел, n, до начального узла, а h(n) - это эвристия c для расстояния от невидимого узла, n, до цели. Это означает, что мы тратим меньше вычислительного времени на поиск оптимального пути, уходя от цели, когда сначала проверяем очевидный путь к цели. Математически доказано, что A * даст вам оптимальный путь от вашего начального узла до целевого узла, если вы найдете допустимый heuristi c, то есть heuristi c, который никогда не переоценивает расстояние до цели. Например, в видеоигре длина пройденного пути между двумя точками всегда больше или равна расстоянию до вороны. Несмотря на то, что наш граф не является графом, представляющим физическое пространство, мы все же можем найти допустимую heuristi c.

Ход может в лучшем случае заставить 2 ведра иметь правильное количество шаров, поскольку ход может Влияет только на два ведра. Таким образом, например, если мы посчитаем наши ведра и увидим, что в 4 ведрах содержится неправильная информация о шариках, то мы знаем, что потребуется как минимум 2 хода. Вполне возможно больше, но оно не может быть меньше 2.

Позволяет сделать наш heuristi c «количеством ведер с неправильным количеством шаров, разделенных на 2».

Наш heuristi c не переоценивает количество ходов, необходимых для получения желаемого количества шаров, так как даже самый лучший вид хода, в котором вы подходите для счастливых пар, может произойти за каждый ход, который вы только t ie наш heuristi c. Наш heuristi c недооценивает ходы довольно часто, но это нормально, вычисления займут больше времени, но не дадут неправильного результата, а план результата для ходов будет по-прежнему кратчайшим. Таким образом, наша heuristi c является допустимой, что означает, что она никогда не переоценивает количество ходов.

Следовательно, A * с heuristi c из "числа ведер, у которых неправильное количество шариков разделено на 2 "всегда найдет наименьшее число ходов, чтобы достичь распределения.

Возможно, можно найти лучшую эвристию c, если так, то поиск будет go быстрее. Это был просто первый heuristi c, о котором я думал.

0 голосов
/ 19 января 2020

Я удалил свой предыдущий ответ. Рассматривали ли вы проблему подмножества сумм? Я не уверен, что он найдет оптимальное решение для общей проблемы, но вот идея.

Для каждого ведра пусть разница = (целевое количество шаров) - (заданное количество шаров). Пусть P - набор положительных разностей, а N - набор абсолютных значений отрицательных разностей.
Выберите следующее максимальное число из двух наборов и найдите минимальную сумму поднабора в противоположном наборе. Если подмножество найдено, переместите шары. В противном случае ищите сумму подмножеств для следующего максимального числа из наборов.

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

Я не уверен, всегда ли оптимальные значения учитывают самые большие сегменты. Дайте нам знать, если вы найдете правильное решение!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...