Вот еще одно предложение: все наборы местоположений в матрице, которые вы хотите использовать, могут быть представлены как перестановки единичной матрицы, чьи записи «1» сообщают вам, какие элементы матрицы добавить. Затем вы берете минимум над набором сумм для всех перестановок. Вы можете представить перестановку простым массивом, так как в перестановке единичной матрицы NxN есть только N элементов, равных 1. Так что вызовите этот массив p, где p (i) говорит вам, какой столбец в i-й строке использовать.
Итак, фундаментальное наблюдение здесь состоит в том, что вы хотите, чтобы все перестановки матрицы тождественности NxN были представлены, и вы можете представить это как перестановки (0,1, ..., N-1).
Псевдокод может выглядеть так:
Given: an NxN matrix (2-D array), M, for which you want the minimal sum of N
elements with no subset falling on the same row or column
minsum = N * max entry in M (just initialized to guarantee >= min sum sought)
foreach permutation p of (0,1,...,N-1):
sum = 0
for i = 0:N-1:
sum += M(i,p(i))
if sum >= minsum: break; # (if we already know this isn't a new min, move on)
if sum < minsum: minsum = sum
print("minimum sum = ", minsum)
Добавление фрагмента кода для запоминания определенного набора местоположений это добавление к минимуму оставлено здесь как упражнение для читателя. Обратите внимание, что это прекращает любую перестановку, как только это не будет новой минимальной суммой.
Для массива NxN есть N! перестановок, так что на практике это быстро становится дорого для больших N (не ваша текущая проблема при N = 5). В этот момент более глубокие методы динамического программирования c, позволяющие досрочно прекратить работу с частичными результатами или избежать повторного вычисления сумм подмножеств с помощью, скажем, запоминания, будут применимы и желательны.
Большинство других алгоритмов собираются сделать то же самое c работает таким образом, что может выглядеть или не выглядеть явно схожим в коде. Мне нравится этот подход, потому что он имеет хорошее отображение в довольно прямолинейном понимании в математических терминах, и вы можете легко определить, что быстро растет с ростом N необходимость в том, чтобы вычислить минимум для быстро расширяющегося набора перестановок .
Алгоритмы для вычисления всех перестановок массива довольно легко найти, и вы получаете их бесплатно в C ++ в функции next_permutation, которая является частью STL. Я рекомендую Google "перечислить все перестановки", и если вам нужно работать на определенном языке программирования, добавьте это и в запрос. Алгоритм не очень сложен и существует как в рекурсивной, так и в итерационной формах. И, эй, для случая 5x5 вы могли бы в любом случае статически перечислить все 120 перестановок.