Преобразование матрицы в блочную матрицу путем перестановки строк и столбцов

У меня есть прямоугольная матрица с n строками и m столбцом. Все элементы матрицы — натуральные числа (включая 0).

Среди m столбцов мне присвоен некоторый индекс j (< m). Я бы хотел, чтобы матрица стала блочной матрицей, как показано ниже.

Для первых i строк (мы можем выбрать любой i <= n, какой хотим) каждая запись справа от j должна быть равна 0. А для следующих (n-i) строк каждая запись слева от индекса j (включая j ) должно быть 0.

Если это невозможно, сумма записей в двух заштрихованных областях (темно-серого цвета) на рисунке выше должна быть как можно меньше.

Единственные операции, разрешенные с исходной матрицей, — это замена строк и столбцов. Меня интересует эффективный алгоритм для достижения этой цели.


Редактировать

Вот CSV-файл исходной матрицы (реальные данные из моего приложения): https://github.com/ryu577/optimizn/blob/master/optimizn/ab_split/testing/arrs_orig.csv

Дж — 25.

Я набрал 561 балл по этой матрице с имитацией отжига. Мне было бы интересно посмотреть, сможет ли кто-нибудь победить это.

Если рассматривать матрицу как матрицу смежности графа, то блоки соответствуют связным компонентам. Для их поиска существуют эффективные алгоритмы.

n. m. could be an AI 31.05.2024 08:40

Но M1 и M2 не обязательно должны быть сильно связными матрицами смежности компонентов.

Rohit Pandey 31.05.2024 08:42

Кроме того, матрица прямоугольная.

Rohit Pandey 31.05.2024 08:51

Вы можете рассматривать его как двудольный график, он работает по сути одинаково.

n. m. could be an AI 31.05.2024 09:06

Первый проход должен заключаться в подсчете количества нулей в каждой строке, что ограничивает значение j и немедленно сообщает вам, невозможна ли ваша целевая форма блока. Вы можете сделать то же самое (менее эффективно) для каждого столбца, который таким же образом ограничивает k. Сортировка строк по количеству нулей в них кажется разумным способом продолжить работу после этого. Замена колонок обойдется дороже, поэтому чем их меньше, тем лучше.

Martin Brown 31.05.2024 10:09

Если M1 и M2 полностью ненулевые, то количество нулей в каждой строке и столбце будет одинаковым. Возможно, это крайний случай. А если мы транспонируем матрицу до замены столбцов, они тоже станут дешевыми, не так ли?

Rohit Pandey 31.05.2024 17:32

Хотя я обычно не одобряю комментарии, выражающие лишь догадки, я рискну и предположу, что это может быть хорошо изученная проблема в линейной алгебре.

Cary Swoveland 01.06.2024 07:45

Неясно, задан ли i или это результат работы алгоритма.

Olivier 03.06.2024 09:08

(@Оливье Not clear whether i is given or [an output]we can choose any i <= n we want)

greybeard 03.06.2024 09:33

@RohitPandey Что означает оценка (561)?

Joyful Wasp 11.06.2024 10:57

Это означает, что если я просуммирую столбцы в двух серых областях, я получу 561.

Rohit Pandey 12.06.2024 05:37

@RohitPandey Мой код, слегка измененный, чтобы предотвратить бесконечный цикл сортировки разреженной матрицы, дает минимум 30 при i=49 и j=166.

Joyful Wasp 13.06.2024 10:26

@SudoKoach - извините, я должен был уточнить здесь ... j фиксирован на 25. Мы можем перемещать i, но не можем перемещать j (вопрос проясняет это).

Rohit Pandey 13.06.2024 23:45
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
13
276
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это проблема минимального разреза с ограничением по размеру. Это NP-трудно решить точно.

Поскольку вы задали вопрос с точки зрения матриц, я рискну и предположу, что у вас есть свободный доступ к библиотеке, которая может вычислить частичное разложение по сингулярным значениям. Если да, то позвольте мне предложить дешевую спектральную эвристику.

Найдите сингулярный вектор m-элемента, соответствующий наибольшему сингулярному значению. Предполагая, что элементы этого вектора различны (без потери общности из-за возмущения или использования индексов для разрыва связей), выберите элемент порядка j; элементы с меньшими значениями соответствуют первым j-1 столбцам выходных данных, а элементы с большими значениями соответствуют последним m-j столбцам. При таком расположении столбцов каждая строка «голосует» за то, должна ли она находиться в верхней или нижней половине.

Спасибо. Разве это не то же самое, что сортировать столбцы по элементам наибольшего сингулярного вектора? Почему это сработает? И сработает ли голосование среди рядов?

Rohit Pandey 07.06.2024 08:30

@RohitPandey да, ты можешь сортировать.

David Eisenstat 07.06.2024 13:11

Извините, я хотел спросить... как будет проходить голосование среди рядов? Может быть, отсортировать по суммам до j?

Rohit Pandey 07.06.2024 18:30

@RohitPandey, да! Signum([сумма до j] - [сумма после j])

David Eisenstat 07.06.2024 20:16

j задан... это все еще актуально?

quester 08.06.2024 23:00

@quester Ключевым моментом здесь является то, что во время голосования мы выбираем порядок столбцов.

David Eisenstat 09.06.2024 01:22

Не могли бы вы объяснить, почему порядок элементов наибольшего сингулярного вектора можно использовать таким образом?

Rohit Pandey 09.06.2024 08:07

@RohitPandey этот предмет не является моей специальностью, моя интуиция довольно проста, но если бы M_1 и M_2 были бы единицами, то было бы две пары сингулярных векторов: первая пара имела бы один вектор, поддерживаемый в первых j столбцах, и один вектор поддерживается в первых i строках; вторая пара будет иметь один вектор, поддерживаемый в других столбцах, и один вектор, поддерживаемый в других строках. SVD безразличен к перестановкам строк и столбцов, поэтому способен восстанавливать структуру.

David Eisenstat 09.06.2024 17:19

Вот решение «старой школы» для уточнения требований и сравнительного анализа. Если разрешены только операции «перестановка строк и замена столбцов», то матрицу можно разделить только с сортировкой по строкам и по столбцам. Строки сортируются по возрастанию соответствующих столбцов средневзвешенного значения. Столбцы отсортированы по возрастанию соответствующих строк средневзвешенного значения.

import numpy as np
rng = np.random.default_rng()           
N=7
M=15
nbmax=min(N,M)-4
A = rng.integers(0, 4, (N,M))

def getWACols(A,N,M):
    wacols=[]
    colsom=np.sum(A,axis=1)
    for row in range(N):
        wsum=0
        for col in range(M):
            wsum+=A[row,col]*col
        if colsom[row]!=0 :
            wacols.append(wsum/colsom[row])
        else:
            wacols.append((M-1)/2)
    return np.array(wacols)
            
def getWARows(A,N,M):
    warows=[]
    rowsom=np.sum(A,axis=0)
    for col in range(M):
        wsum=0
        for row in range(N):
            wsum+=A[row,col]*row
        if rowsom[col]!=0:
            warows.append(wsum/rowsom[col])
        else:
            warows.append((N-1)/2)
    return np.array(warows)

def sortByRow(A,N,M):
    B=np.zeros((N,M),np.int32)
    wacols_sorted=np.argsort(getWACols(A,N,M))
    bn=True
    for row in range(N):
        for col in range(M):
            B[row,col]=A[wacols_sorted[row],col]
            bn=bn and row==wacols_sorted[row]
    return B,bn

def sortByCol(A,N,M):
    B=np.zeros((N,M),np.int32)
    warows_sorted=np.argsort(getWARows(A,N,M))
    bn=True
    for col in range(M):
        for row in range(N):
            B[row,col]=A[row,warows_sorted[col]]
            bn=bn and col==warows_sorted[col]
    return B,bn    

def partitionMatrix(A,N,M):            
    B,bn=sortByRow(A,N,M)
    bn1=bn and True
    B,bn=sortByCol(B,N,M)
    return B,bn and bn1

print(A)
B=np.copy(A)
bn=False
cntr=0
while not bn and cntr<100:
    B,bn=partitionMatrix(B,N,M)
    cntr+=1
print(B)

j=np.sum(getWACols(B,N,M))/M
i=np.sum(getWARows(B,N,M))/N

print(i,j)
   

Спасибо за решение. Я попробовал это в своем тестовом примере, и, похоже, это не лучшее мое решение. Но я включил в вопрос тестовый пример на случай, если вы захотите подтвердить.

Rohit Pandey 09.06.2024 19:31
Ответ принят как подходящий

Два практических подхода:

  1. Создайте задачу оптимизации, которая минимизирует сумму квадратов соответствующих коэффициентов в целевой матрице с учетом двух матриц перестановок: матрица C размеров mxm и матрица R размеров nxn. Добавьте требования RR^T=I и CC^T=I, используя множители Лагранжа. Запустите оптимизацию, чтобы найти оптимальные C и R. Затем добавьте к целевой функции регуляризатор, который преобразует эти матрицы в правильную перестановку (например, 0 и 1).
  2. Используйте генетическую оптимизацию.

Ни один из них не гарантирует оптимального решения.

Спасибо! Не понял, как добавить регуляризатор для преобразования матриц в правильную перестановку?

Rohit Pandey 09.06.2024 08:03

Добавьте в целевую функцию термин, который будет отдавать предпочтение нулям и единицам в R и C. Например, α|(x-0,5)²-0,25|, где x — каждый коэффициент R и C, а α постепенно увеличивается в вашей целевой функции. итеративный оптимизатор, каким бы он ни был.

Dmitry Negoda 09.06.2024 10:50

Другие вопросы по теме