Предположим, у меня есть двоичная матрица (M x N), в которой M и N могут быть большими. Я хочу найти ровно k столбцов (k относительно мало, скажем, меньше 10), чтобы сумма этих k столбцов была 1-вектором (все элементы равны 1). Достаточно одного решения. Есть ли для этого быстрый алгоритм?
Например, алгоритм, работающий с матрицей
1 0 0
1 0 0
1 1 0
0 1 1
с k = 2, должен возвращать столбцы 0 и 2, но не должен сообщать никаких решений, если k = 1 или k = 3.
Я пробовал два подхода:
- Медленный комбинаторный подход, когда я пробую все (N выбирают k) комбинации и нахожу комбинацию, которая в сумме дает 1-вектор. Это выполняется за время O (N ^ k), что, очевидно, ужасно.
- Рекурсивный подход, который быстрее, но все же выполняется за время O (N ^ k) в худшем случае. Код Python выглядит следующим образом:
import numpy as np
def recursiveFn(mat, col_used_bool, col_sum_to_date, cols_to_go):
N = len(mat)
if cols_to_go == 1:
col_unused = 1 - col_sum_to_date
if list(col_unused) in [list(i) for i in mat]:
return (True, [col_unused])
else:
return (False, None)
for col_id in range(N):
if col_used_bool[col_id]:
continue
if 2 not in mat[col_id]+col_sum_to_date:
col_used_bool[col_id] = True
x = recursiveFn(mat, col_used_bool, mat[col_id]+col_sum_to_date, cols_to_go-1)
col_used_bool[col_id] = False
if x[0]:
return (True, x[1] + [mat[col_id]])
return (False, None)
exMat = [[1,1,1,0],[0,0,1,1],[0,0,0,1]] #input by colums
exMat = [np.asarray(i) for i in exMat]
k = 2
output = recursiveFn(mat = exMat, col_used_bool = [False for i in exMat],
col_sum_to_date = np.asarray([0 for i in exMat[0]]), cols_to_go = k)
print(output[1])
### prints this : [array([0, 0, 0, 1]), array([1, 1, 1, 0])]
Меня не устраивает ни один из этих подходов, и я чувствую, что существует более умный и быстрый алгоритм. Большое спасибо за вашу помощь. Это мой первый пост на StackOverflow, поэтому, пожалуйста, будьте осторожны со мной, если я где-то ошибся!
(Если интересно, я также задал тот же вопрос на Math Stack Exchange , но там меня меньше беспокоит эффективность алгоритмов c и больше интересуют математические методы.)