Я сталкиваюсь с проблемами, пытаясь решить проблему, которая для меня сложнее, чем я предполагал. Учитывая двоичную матрицу NxM, я хочу сгенерировать все возможные решения при условии, что каждый столбец имеет ровно одну «1». Для 2x3 это будет:
1 1
0 0
0 0
1 0
0 1
0 0
1 0
0 0
0 1
0 1
1 0
0 0
0 0
1 1
0 0
0 0
1 0
0 1
0 1
0 0
1 0
0 0
0 1
1 0
0 0
0 0
1 1
После некоторых головных болей у меня работает рекурсивный алгоритм на C, но я не слишком уверен, что он правильный, поскольку он явно не работал в течение самого длительного времени, пропуская некоторые комбинации. После изменения рекурсии, по крайней мере, число комбинаций является правильным, и для N x M, который я могу проверить вручную, это кажется правильным.
Но: потребление памяти ужасно, когда я начинаю с
1 1
0 0
0 0
и самый правый столбец, устанавливающий 1 в 0 и 0 в строке ниже в 1, если есть какая-либо строка. Затем я перехожу на один столбец влево (сбрасываю то, что я сделал, к крайнему правому столбцу, например, рассматривая перенос), и перебираю позицию 1, и для каждой итерации я снова возвращаюсь вправо, пока не останется ни одного столбца для перебора 1. Этот подход может показаться вам неуклюжим (код делает это для меня), но я думаю, что это похоже на подсчет в системе с полиадой, где столбцы являются цифрами, а позиция 1 дает значение цифры.
Может быть, это просто мой неправильный способ рекурсии, но в настоящее время я должен копировать текущий массив для каждой рекурсии, что, конечно, ужасно, но единственный способ, который я нашел, как например,
0 1
1 0
0 0
и дважды скопировать его для генерации
0 0
1 1
0 0
и
0 0
1 0
0 1
Независимо друг от друга легче. Но освобождение памяти в C при повторном использовании не похоже на мой уровень опыта. Я переписал в Java, надеясь, что GC может помочь мне (не могу в это поверить, но похоже, что так и есть), но, опять же, профилирование говорит, конечно, что копирование данных пожирает 99% циклов.
У вас есть предложения по моей проблеме? Может быть, есть даже название для этого, чтобы не думать о существующих алгоритмах? Есть ли у вас псевдокод для рекурсии под рукой? Большое спасибо от курящего мозга!
Я даже не уверен, является ли это комбинаторной или перестановочной проблемой.