2009-11-19 9 views
6

Я ищу здесь несколько указателей, поскольку я не совсем знаю, с чего начать исследование этого.Сортировка бинарной 2D-матрицы?

У меня есть 2D матрицу с 0 или 1 в каждой ячейке, например:

1 2 3 4 
A 0 1 1 0 
B 1 1 1 0 
C 0 1 0 0 
D 1 1 0 0 

И я хотел бы, чтобы отсортировать его так, как «верхний треугольный», насколько это возможно, например, так:

4 3 1 2 
B 0 1 1 1 
A 0 1 0 1 
D 0 0 1 1 
C 0 0 0 1 

Строки и столбцы должны оставаться неповрежденными, т.е. элементы нельзя перемещать индивидуально и их можно заменить только «целыми».

Я понимаю, что там, вероятно, будет патологические случаи, когда матрица имеет несколько возможных отсортированных результатов (то есть ту же самую форму, но различаются по идентичности «первоначальных» строк/столбцов.)

Так, может кто-нибудь подскажите, где я могу найти некоторые отправные точки для этого? Существующая библиотека/алгоритм будет замечательной, но я соглашусь узнать имя проблемы, которую я пытаюсь решить!

Я сомневаюсь, что это проблема линейной алгебры как таковая, и, возможно, есть какая-то техника обработки изображений, которая применима.

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

Подробнее: Дополнительная информация о том, что я пытаюсь сделать, может помочь прояснить. Каждая строка представляет участника, каждый столбец представляет собой вызов. Каждый 1 или 0 представляет «успех» для участника по конкретной задаче.

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

Замечание об принятом ответе: Я принял Имитированный отжиг как «ответ» с предостережением о том, что этот вопрос не имеет правильного ответа. Это похоже на хороший подход, хотя на самом деле мне не удалось найти функцию подсчета очков, которая работает для моей проблемы.

+1

Вопросы: (1) Обратите внимание, что нет ничего, что вы можете сделать с матрицей всех 1s: Вы хорошо с этим? (2) Как только нет нулей ниже диагонали, вам небезразлично, где 1s находятся выше диагонали? (3) Минимизирует число 1s ниже диагонали достаточно хорошего критерия? Как просто минимизировать количество строк, которые имеют (по крайней мере) 1 ниже диагонали? – ShreevatsaR

+0

Ответ 1) Да, все нули или все-одни никогда не произойдут, и если они это сделают, они по определению все будут считаться эквивалентными, поэтому их сортировка в какую-то другую перестановку не будет проблемой. – Tom

+0

Ответ 2 + 3) Да, я хочу, чтобы 1s был как можно ближе к верхней части каждого столбца, т. Е. Как можно больше 1s в верхнем правом углу. Обратите внимание, что под диагональю может быть 1s и 0s над ней, это не строго треугольная матрица. – Tom

ответ

6

Алгоритм, основанный на simulated annealing, может обрабатывать такие вещи без слишком много проблема. Невероятно, если у вас есть маленькие матрицы, которые, скорее всего, имеют фиксированное решение, но отлично, если ваши матрицы становятся больше и проблема становится более сложной.

(Тем не менее, это также не ваше желание, что вставки могут быть сделаны постепенно.)

Отборочных

  1. Разработайте функцию производительности, что «оценка» а матрица - матрицы, которые ближе к ваша трехгранность должна получить лучший результат, чем те, которые меньше треугольника.

  2. Придумать набор операций, которые разрешено на матрице. Ваше описание было немного неоднозначным, но если вы можете поменять строки, то один op будет SwapRows(a, b). Другой может быть SwapCols(a, b).

при отжиге петля

Я не буду давать полную экспозицию здесь, но идея проста. Вы выполняете случайные преобразования на матрице, используя свои операции. Вы измеряете, насколько «лучше» матрица после операции (с использованием функции производительности до и после операции). Затем вы решаете, следует ли совершить это преобразование. Вы повторяете этот процесс много.

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

public bool ShouldAccept(double cost, double temperature, Random random) { 
    return Math.Exp(-cost/temperature) > random.NextDouble(); 
} 

Вы должны прочитать отличную информацию, содержащуюся в Numerical Recipes для получения дополнительной информации по этому алгоритму.

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

алгоритм Scoring

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

Как вы измеряете «идеальное решение» - треугольность? Вот наивный и легкий бомбардир: для каждой точки вы знаете, должно ли оно быть 1 или 0.Добавьте +1 к оценке, если матрица правильная, -1, если это неправильно. Вот код, так что я могу быть явным (не тестировался! Ознакомьтесь!)

int Score(Matrix m) { 
    var score = 0; 
    for (var r = 0; r < m.NumRows; r++) { 
     for (var c = 0; c < m.NumCols; c++) { 
      var val = m.At(r, c); 
      var shouldBe = (c >= r) ? 1 : 0; 
      if (val == shouldBe) { 
       score++; 
      } 
      else { 
       score--; 
      } 
     } 
    } 
    return score; 
} 

При этом алгоритм подсчета баллов, случайным полем 1s и 0s даст оценку 0. «противоположный» треугольник даст самый отрицательный результат, и правильное решение даст самый положительный результат. Разница в двух баллах даст вам стоимость.

Если этот бомбардир не работает для вас, вам нужно будет «настроить его», пока он не выдает нужные вам матрицы.

Этот алгоритм основан на предпосылке, что настройка этого счетчика намного проще, чем разработка оптимального алгоритма для сортировки матрицы.

+3

Да, но эти «алгоритмы общего назначения» также обычно отсасывают поиск фактически оптимальных решений - они часто могут занять много времени, чтобы сходиться или застревать в локальных минимумах. Можете ли вы * доказать * что-нибудь о результатах, полученных при моделированном отжиге для этой конкретной проблемы? – ShreevatsaR

+0

Это должно работать, хотя и не детерминированным образом. (в отличие от других ответов до сих пор ...) +1.Возможно, вы можете предложить ввести «щепотку» аналитического/эвристического трюка в микс, например, путем идентификации строк или столбцов, которые имеют только нули, и поместите их внизу/слева соответственно и сделайте эти несмежные w/r до разрешенных преобразования. – mjv

+0

Точка прилипания (по крайней мере, где я застреваю) является функцией оценки. Учитывая, что смоделированный отжиг может определенно работать, но как вы знаете, как матрица «треугольник-у»? И да, двумя допустимыми операциями являются SwapRow (a, b) и SwapCol (a, b). – Tom

0

Вот отправная точка:

Преобразование каждой строки из двоичных бит в число

Сортировки чисел в порядке убывания.

Затем преобразуйте каждую строку обратно в двоичную.

+0

Да, это работает для строк, но столбцы тоже нужно сортировать. – Tom

+0

Согласитесь с Томом. – kafuchau

0

Базовый алгоритм:

  1. Определить суммы строк и хранить значения. Определите суммы столбцов и сохраните значения.
  2. Сортируйте суммы строк в порядке возрастания. Сортировка столбца сумм в порядке возрастания.

Надеюсь, у вас должна быть матрица с максимально приближенной к верхней правой треугольной области.

+0

Этот вид работ, но не «закончил» сортировку примера, который я дал: суммы строк: A: 2, B: 3, C: 1, D: 2, col sum - 1: 2, 2: 4 , 3: 2, 4: 0, поэтому неоднозначно, какие строки заказов A, D и cols 1,3 должны войти. – Tom

+0

Если я понимаю остальную проблему ... Возможно, после того, как вы сделали первые два шаги, вы можете посмотреть на новую матрицу и проверить строки и столбцы с одинаковыми равными суммами, чтобы увидеть, какие более плотно упакованы с 1 в правую/верхнюю (таким образом, индекс нижней строки и более высокий индекс столбца). – kafuchau

1

Я придумал алгоритм ниже, и, похоже, он работает правильно.

Фаза 1: перемещение строк с наиболее 1 ы вверх и столбцы с большинством 1 с правой.

  1. Сначала строки. Сортируйте строки, посчитав их 1 s. Нам все равно , если 2 строки имеют одинаковое количество 1 s.
  2. Теперь столбцы. Сортируйте cols по , считая их 1 s. Нам все равно , если 2 cols имеют одинаковое количество 1 s.

Фаза 2: повтор фаза 1, но с дополнительными критериями, так что мы удовлетворяем треугольную матрицу морфа.
Критерий для строк: если 2 строки имеют одинаковое число 1 s, мы перемещаем до строку, начинающуюся с меньшего числа 0 s.

Критерий перевалы: если 2 перевалов имеют одинаковое количество 1 с, мы перемещаем правой седловины, что имеет меньше 0 сек в нижней части.


Пример:

Фаза 1

1 2 3 4      1 2 3 4     4 1 3 2 
A 0 1 1 0     B 1 1 1 0     B 0 1 1 1 
B 1 1 1 0 - sort rows-> A 0 1 1 0 - sort cols-> A 0 0 1 1 
C 0 1 0 0     D 1 1 0 0     D 0 1 0 1 
D 1 1 0 0     C 0 1 0 0     C 0 0 0 1 

Фаза 2

4 1 3 2      4 1 3 2 
B 0 1 1 1     B 0 1 1 1 
A 0 0 1 1 - sort rows-> D 0 1 0 1 - sort cols-> "completed" 
D 0 1 0 1     A 0 0 1 1 
C 0 0 0 1     C 0 0 0 1 

Edit: получается, что мой алгоритм не дает правильные треугольные матрицы всегда.
Например:

Фаза 1

1 2 3 4     1 2 3 4     
A 1 0 0 0     B 0 1 1 1     
B 0 1 1 1 - sort rows-> C 0 0 1 1 - sort cols-> "completed" 
C 0 0 1 1     A 1 0 0 0     
D 0 0 0 1     D 0 0 0 1     

Фаза 2

1 2 3 4     1 2 3 4     2 1 3 4 
B 0 1 1 1     B 0 1 1 1     B 1 0 1 1 
C 0 0 1 1 - sort rows-> C 0 0 1 1 - sort cols-> C 0 0 1 1 
A 1 0 0 0     A 1 0 0 0     A 0 1 0 0 
D 0 0 0 1     D 0 0 0 1     D 0 0 0 1 
          (no change) 

(*) Возможно фаза 3 увеличит хорошие результаты. На этой фазе мы помещаем строки, начинающиеся с меньшего числа 0 s в верхней части.

+0

Вот вход, где он не работает: рассмотрите '[1 0 0 0], [0 1 1 1], [0 0 1 1], [0 0 0 1]' (который уже является верхним, треугольная). Используя ваш алгоритм на нем, вы попадаете в '[1 0 1 1], [0 0 1 1], [0 0 0 1], [0 1 0 0]', что нет. (И если исходная форма не задана, и вы начинаете с последней матрицы, то алгоритм ничего не меняет: она не находит верхнетреугольную форму.) – ShreevatsaR

+0

Или более простой пример 3x3: '[1 0 0], [0 1 1], [0 0 1] '. – ShreevatsaR

+0

@ShreevatsaR, вы правы, спасибо. Он не всегда создает треугольную матрицу. Тем не менее, он не дает матриц, которые вы сказали. Возможно, вы не применили эти шаги правильно. Проверьте мое редактирование. Что касается '[1 0 0], [0 1 1], [0 0 1]', он даст '[1 0 1], [0 1 0], [0 0 1]'. –

0

Treat строка в виде двоичных чисел, с крайним левым столбцом в качестве самого старшего бита, и отсортировать их в порядке убывания, сверху вниз

Treat столбцов в виде двоичных чисел с самой нижней строкой в ​​качестве наиболее значимого бита и сортируйте их по возрастанию, слева направо.

Повторяйте, пока не достигнете фиксированной точки. Доказательство того, что алгоритм заканчивается слева как упражнение для читателя.

0

Ищите бумагу 1987 года Анны Любив на тему «Двусторонние лексические обозначения матриц».

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

http://dl.acm.org/citation.cfm?id=33385

+1

Просьба также указать информацию в своем вопросе. Если ссылка ACM изменяется (время от времени, я тоже являюсь участником), ваш ответ теряет весь контекст. –

Смежные вопросы