Мой псевдокод:
- Создать граф узлов, где каждый узел представляет слово
- Создание соединений между всеми узлами (каждый узел соединяется с каждым другим узлом). Каждое соединение имеет «значение», которое представляет собой число общих символов.
- Отбросить соединения, где «значение» равно 0.
- Пройдите по графику, предпочитая соединения с самыми высокими значениями. Если у вас два соединения с одинаковым значением, попробуйте оба рекурсивно.
- Сохраните результат прогулки в списке вместе с суммой расстояния между словами в этом конкретном результате. Я не уверен на 100% в банкомате, если вы можете просто суммировать соединения, которые вы использовали. Смотрите сами.
- Из всех выходов выберите тот, который имеет наибольшее значение.
Эта проблема, вероятно, завершена NP, что означает, что время выполнения алгоритма станет невыносимым по мере роста словарей. Прямо сейчас я вижу только один способ оптимизировать его: разрезать график на несколько меньших графиков, запустить код для каждого и затем присоединиться к спискам. Результат не будет таким же идеальным, как при попытке каждой перестановки, но время выполнения будет намного лучше, а конечный результат может быть «достаточно хорошим».
[РЕДАКТИРОВАТЬ] Поскольку этот алгоритм не пробует каждую возможную комбинацию, вполне возможно пропустить идеальный результат. Возможно даже попасть в локальный максимум. Скажем, у вас есть пара со значением 7, но если вы выбрали эту пару, все остальные значения упадут до 1; если бы вы не взяли эту пару, большинство других значений были бы равны 2, что дало бы намного лучший общий конечный результат.
Этот алгоритм обменивает совершенство на скорость. При попытке каждой комбинации потребуются годы, даже с самым быстрым компьютером в мире, вы должны найти способ ограничить время выполнения.
Если словари маленькие, вы можете просто создать каждую перестановку, а затем выбрать лучший результат. Если они вырастут за пределы определенной границы, вы обречены.
Другое решение - смешать два. Используйте жадный алгоритм, чтобы найти «острова», которые, вероятно, довольно хороши, а затем используйте «полный поиск», чтобы отсортировать маленькие острова.