Для простой таблицы вот так:

+---------+---------+---------+
| Column1 | Column2 | Column3 |
+---------+---------+---------+
| A       | J       | Q       |
| A       | K       | S       |
| B       | M       | R       |
| B       | N       | S       |
| B       | J       | Q       |
| C       | K       | R       |
| D       | J       | R       |
| D       | J       | Q       |
| E       | L       | Q       |
+---------+---------+---------+

Можно ли определить, есть ли в этой таблице подмножество из N строк, так что для каждого столбца все N значений различны?

Например, при N = 3 ответом будет да

+---------+---------+---------+
| Column1 | Column2 | Column3 |
+---------+---------+---------+
| A       | J       | Q       |
| B       | N       | S       |
| C       | K       | R       |
+---------+---------+---------+

Есть ли простой алгоритм для решения такого вопроса?

0
Benoit 11 Фев 2020 в 13:50

3 ответа

Лучший ответ

Есть ли простой алгоритм для решения такого вопроса?

Ответ на это строго "да"; вы можете выполнить поиск методом перебора по всем (R выберите K) подмножествам K row, где R - количество строк во всей таблице. Этот алгоритм довольно прост и может быть реализован в несколько строк на языке, подобном Python.

Но я не думаю, что это ответ, который вы ищете; Я думаю, вы хотите знать, есть ли простой алгоритм, который занимает меньше экспоненциального времени. Ответ на это почти наверняка нет; проблема NP-сложная, за счет уменьшения проблемы с максимальным независимым набором, так что нет известного алгоритма, который дает правильные ответы за полиномиальное время, и очень вероятно, что такой алгоритм невозможен.

Сокращение выглядит следующим образом: для данного графика построить таблицу с одной строкой для каждой вершины. Для каждого ребра на графике добавьте один столбец в таблицу; в этом столбце напишите одну и ту же букву в двух строках, к которым присоединяется ребро, а затем напишите разные другие буквы в каждой из оставшихся строк для этого столбца. Результирующая таблица содержит V строк и E столбцов, поэтому ее размер является полиномиальным по размеру исходного графа и строится за полиномиальное время.

Тогда любой набор из K строк, имеющих разные значения в каждом столбце, дает K вершин в исходном графе, не связанных какими-либо ребрами. Это означает, что если вы можете ответить да / нет на то, существует ли такой набор из K строк за полиномиальное время, то вы также можете ответить на форму решения задачи о максимальном независимом наборе за полиномиальное время. Последний является NP-полным, поэтому ваша задача - NP-сложная.

2
kaya3 11 Фев 2020 в 11:24

Простым решением будет просто поиск (возврат).

Но каждый инструмент / библиотека, решающая CSP (проблема удовлетворения ограничений), может найти решение.

1
MrSmith42 11 Фев 2020 в 10:57

Поскольку вы явно запрашиваете алгоритм для решения этой проблемы:

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

Я бы начал так:

  1. Создайте структуру данных для поиска, если вы уже нашли значение (например, hashmap)
  2. Создайте структуру данных для хранения ваших строк результатов, которые соответствуют условию соответствия (все значения разные)
  3. Итерируйте строки входной таблицы, пока не достигнете желаемого размера подмножества или не достигнете конца таблицы
  4. Начните с первого ряда
  5. Выполняя итерацию строки, проверьте для каждого значения, находится ли оно в вашей структуре (созданной в 1.), если yes -> abort, иначе добавьте значение в lookup-структуру. Когда все значения строк проверены, эта строка в порядке и может быть добавлена в ваш набор результатов.
  6. Итерировать следующую строку, если она существует

Но, как отмечено в комментарии, этот алгоритм является жадным алгоритмом, который не всегда найдет возможное решение

0
ChrisN 11 Фев 2020 в 11:32