Алгоритм минимизации вертикальной суммы связанных строк

#algorithm #linear-algebra #minimization

Вопрос:

У меня есть проблема, для которой я пытаюсь найти алгоритм. Я был бы признателен за любые предложения.

У меня есть n строк длиной m. Строки имеют двоичные (0,1) значения, которые имеют некоторую ожидаемую сумму. 1 может быть помещен в любом месте его строки до тех пор, пока сумма соответствует ожидаемой. Цель состоит в том, чтобы минимизировать вертикальную сумму для каждого столбца длиной m.

Например, если у нас есть 4 строки и 10 столбцы, где ожидаемые суммы равны:

 Row 1: 6  Row 2: 7  Row 3: 4  Row 4: 5  

Потенциальным решением может быть:

 1 1 1 1 1 1 0 0 0 0  1 1 1 0 0 0 1 1 1 1  1 0 0 1 1 1 0 0 0 0   0 1 0 0 0 0 1 1 1 1  

Получение вертикальных сумм:

 3 3 2 2 2 2 2 2 2 2  

В отличие от больших сумм, если бы мы просто разместили все в начале:

 1 1 1 1 1 1 0 0 0 0  1 1 1 1 1 1 1 0 0 0  1 1 1 1 0 0 0 0 0 0  1 1 1 1 1 0 0 0 0 0  

С суммами:

 4 4 4 4 3 2 1 0 0 0  

Итак, я пытаюсь распределить нагрузку. Мое количество строк достигнет миллионов/миллиардов, поэтому я надеюсь на подход линейной алгебры, а не на итеративный. Спасибо!

Ответ №1:

 def create_min_vert_matrix(num_r, num_c, arr_sum_rows):   res = []   curr = 0   for r in range(num_r):   row = [0]*num_c   while arr_sum_rows[r] gt; 0:   arr_sum_rows[r] -= 1   row[curr] = 1   curr = (curr 1)%num_c   res.append(row)   return res  

Быстрый тест:

 create_min_vert_matrix(4, 10, [6,7,4,5])  [[1, 1, 1, 1, 1, 1, 0, 0, 0, 0],  [1, 1, 1, 0, 0, 0, 1, 1, 1, 1],  [0, 0, 0, 1, 1, 1, 1, 0, 0, 0],  [1, 1, 0, 0, 0, 0, 0, 1, 1, 1]]  

Функция принимает количество строк num_r , количество столбцов num_c и массив, который указывает , какой должна быть сумма единиц в каждой строке ( arr_sum_rows ).

Идея состоит в том, что если мы распределим данные по одному столбцу как можно более равномерно, мы сможем минимизировать суммы столбцов. Чтобы это произошло, мы отслеживаем последний столбец, в который мы вставили единицу curr , и для каждого вставленного увеличиваем его. Если он становится больше, чем количество столбцов, мы устанавливаем его равным нулю: curr = (curr 1)%num_c .

Алгоритм выполняется там O(n*m) , где n и m -это количество строк и столбцов матрицы и O(1) дополнительное пространство, если мы не учитываем дополнительное пространство, необходимое для результата (в противном случае, конечно, также O(n*m) дополнительное пространство).

Комментарии:

1. Спасибо, это определенно работает! Я действительно ценю ваши усилия по решению этой проблемы! Мое единственное сомнение в том, что я надеялся на более быстрое вычисление линейной алгебры, поскольку моя проблема масштабируется до миллионов/миллиардов строк (я обновлю проблему с помощью этого). Я оставлю это открытым еще на неделю, чтобы посмотреть, не придет ли кому-нибудь в голову такое. Если нет, я приму ваш ответ. Спасибо!