Слияние двух частичных (совместно переопределенных) наборов информации о заказе

У меня есть веб-приложение с данными в сетке. Пользователь может изменить порядок столбцов, а сервер может изменить существующие столбцы. Я хотел бы сохранить порядок столбцов пользователя в файле cookie и восстановить его при загрузке страницы.

Говоря более формально, у меня есть два массива уникальных идентификаторов (строк) с именами user_columns и server_columns. Я хотел бы изменить порядок server_columns таким образом, чтобы соблюдать всю информацию о заказе от user_columns и как можно больше от server_columns. Как мне это сделать? Каково разумное формальное определение «насколько это возможно»?

Мой анализ на данный момент:

Один аспект проблемы тривиален: если сервер удаляет некоторые столбцы, удалите соответствующие записи из user_columns. Любая информация о порядке столбцов, которых больше нет, является спорной. Тогда проблема становится одной из проблем слияния двух потенциально конфликтующих наборов информации о заказе.

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

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

Это звучит так, как будто это на правильном пути?

Заметьте также, что мы можем рассмотреть три вида сравнений: A и B оба находятся в user_columns, одно из них или ни одно из них. Первый и последний виды легко разрешаются (см. user_columns и server_columns соответственно); тот, что посередине, и его взаимодействие с последним - сложные части.


person Jonas Kölker    schedule 21.03.2014    source источник
comment
Возможно, связано: stackoverflow.com/ вопросы/15932601/ и stackoverflow.com/questions/6352212/   -  person Jonas Kölker    schedule 22.03.2014
comment
На каком языке вы хотите это реализовать?   -  person Ivarpoiss    schedule 22.03.2014
comment
@Иварпоисс: javascript   -  person Jonas Kölker    schedule 22.03.2014
comment
Пожалуйста, уточните вопрос. Может ли сервер изменить порядок столбцов или просто изменить набор столбцов? Потому что в первом случае, почему вы вообще упоминаете теорию голосования? Нет необходимости в голосовании, если только одна сторона вообще имеет порядок   -  person Niklas B.    schedule 22.03.2014
comment
И user_columns, и server_columns являются массивами, и сервер может изменить порядок столбцов, т. е. если A и B встречаются в server_columns при двух последовательных загрузках страницы, они могут встречаться в двух разных порядках. Я думаю, что более интересным свойством является то, что user_columns и server_columns могут не совпадать при загрузке одной страницы, но в любом случае я думаю, что ответ положительный :)   -  person Jonas Kölker    schedule 22.03.2014
comment
Вас бы устроил алгоритм, минимизирующий инверсии относительно server_columns и полностью учитывающий user_columns (ноль инверсий относительно user_columns)? Потому что так я интерпретирую вопрос.   -  person Niklas B.    schedule 22.03.2014


Ответы (3)


Допустим, у нас есть столбцы C, пронумерованные от 1 до C. У нас есть две последовательности последовательностей столбцов: U = u1, u2, ... un и S = s1, s2, ... sm. Мы хотим найти перестановку P для S, такую, что P не имеет инверсий относительно U и минимальное количество инверсий относительно S.

Мы можем показать, что существует такой оптимальный P, который представляет собой чередование U ∩ S и S \ U. Под «чередованием» я подразумеваю, что P не имеет инверсий относительно U ∩ S или S \ U.

Мы можем применить динамическое программирование, чтобы найти оптимальное чередование: Пусть A = (ai< /sub>) = U ∩ S и B = (bj) = S \ U. Пусть f(i,j) — количество инверсий относительно S оптимального чередования префиксов a1...i слова A и b1...j слова B. Идея заключается в следующем. очень похоже на алгоритм самой длинной общей подпоследовательности DP. у нас рецидив

f(0,j) = 0 for all j >= 0
f(i,0) = f(i-1, 0) + sum(k=1 to i-1, [1 if A[i] appears before A[k] in S])
f(i,j) = min(f(i-1, j) + sum(k=1 to i-1, [1 if A[i] appears before A[k] in S])
                       + sum(k=1 to j, [1 if A[i] appears before B[k] in S]),
             f(i, j-1) + sum(k=1 to i, [1 if B[j] appears before A[k] in S])
                       + sum(k=1 to j-1, [1 if B[j] appears before B[k] in S]))

Я использовал обозначение [1 if X] здесь для обозначения значения 1, если X истинно, и 0, если X ложно.

Матрица f может быть построена за время O(|A|^2 * |B|^2). Минимальная стоимость (количество инверсий относительно S) будет f(|A|, |B|).

Мы также можем реконструировать оптимальную перестановку, используя матрицу DP: мы строим ее сзади наперед. Мы начинаем с кортежа (i,j) = (|A|, |B|) и на каждом шаге в зависимости от того, какой из двух вариантов является минимальным в переходе DP, мы знаем, нужно ли нам ставить A[i] или B[j] в начало перестановки. Затем мы переходим к (i-1, j) или (i, j-1) в зависимости от того, что мы выбираем.

Вот реализация алгоритма, извините за отсутствие навыков работы с JS.

person Niklas B.    schedule 22.03.2014
comment
Что касается доказательства чередования: предположим, что у нас есть b₂, aᵢ, ..., aⱼ, b₁ как часть решения с b₁ инвертированным относительно b₂. Пусть Inv(1) будет количеством инверсий между b₁ и aᵢ..aⱼ, а Inv(2) аналогично. Если Inv(1) ≤ Inv(2), то aᵢ, ..., aⱼ, b₁, b₂ имеет меньше инверсий, чем исходный (новый Inv(2 ) = old Inv(1) ≤ old Inv(2), и мы зафиксировали инверсию b₁/b₂), и аналогично в обратном порядке, если Inv(2) ≤ Inv( 1). Поскольку замена соседних неупорядоченных элементов b снижает количество инверсий, решение имеет элементы b по порядку. КЭД. Правильный? - person Jonas Kölker; 23.03.2014
comment
@JonasKölker Очень хорошо, это на самом деле очень похоже на идею доказательства, которую я имел в виду, и это очень компактная ее формулировка. мне это нравится - person Niklas B.; 23.03.2014
comment
@JonasKölker На самом деле я думаю, что замена b1 и b2 может стоить вам одной дополнительной инверсии, но, поскольку вы также уменьшаете ее, ставя b1 и b2, чтобы получить как минимум одинаково хорошую перестановку. Или, если быть более точным, new Inv(2) = old Inv(1) <= old Inv(2) не обязательно выполняется, если я не ошибаюсь, но здесь уже слишком поздно, чтобы быть уверенным в этом прямо сейчас - person Niklas B.; 23.03.2014
comment
@JonasKölker Кстати, если вам интересно, повторение, вероятно, можно решить за O (|A| * |B|) - person Niklas B.; 23.03.2014
comment
Я был бы очень заинтересован как в исправлении моего доказательства, так и в более быстром алгоритме :) - person Jonas Kölker; 23.03.2014
comment
@Jonas Алгоритмическая часть проще: например. Пусть g(x,K) = sum(k=1 to K, [1 if x appears before A[k] in S]). Тогда у нас есть g(x,K) = g(x,K-1) + [1 if x appears before A[K] in S], так что мы можем вычислить все суммы за O(1). Вы можете ответить, что X появляется перед Y в S запросах в O (1), предварительно вычислив ранги элементов в S - person Niklas B.; 23.03.2014

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

person David Eisenstat    schedule 21.03.2014
comment
Это звучит как разумное определение. Я подозреваю, что этого можно добиться с помощью метода Шульце или ранжированных пар, но мне этого недостаточно. - person Jonas Kölker; 22.03.2014
comment
Я думаю, что мы можем просто использовать DP для оптимального чередования набора столбцов клиента с набором столбцов сервера, исключая столбцы клиента. - person Niklas B.; 22.03.2014
comment
@НикласБ. Я думал, что может быть что-то подобное. Мне пришлось выбежать за дверь через пять минут после того, как я начал этот ответ. - person David Eisenstat; 22.03.2014

Это относится к ответу Николаса Б:

Теорема. Рассмотрим последовательность S = s₁, …, sₙ некоторого упорядоченного множества (например, целых чисел). Если i ‹ j и sᵢ > sⱼ, то замена sᵢ и sⱼ уменьшает количество инверсий, т. е. , пусть S' = s₁, …, sᵢ₋₁, sⱼ, sᵢ₊₁, …, sⱼ₋₁, sᵢ, sⱼ₊₁, …, sₙ; тогда S' имеет меньше инверсий, чем S.

Интуитивно сказано: если два элемента не в порядке и вы меняете их местами, вы ближе к отсортированному списку.

Доказательство. Обратите внимание, что единственными элементами, которые имеют различный относительный порядок в S и S', являются (sᵢ, sⱼ), (sᵢ, sₖ) и (sⱼ, sₖ) для каждый k, где i ‹ k ‹ j. Мы знаем, что (sᵢ, sⱼ) является инверсией в S, но не S', поэтому рассмотрим sₖ для некоторых таких k.

Либо sₖ ‹ sⱼ ‹ sᵢ, либо sⱼ ‹ sₖ ‹ sᵢ, либо sⱼ ‹ sᵢ ‹ sₖ (мы предполагаем, что элементы S< /em> быть уникальным).

В первом случае (sᵢ, sₖ) является инверсией в S и (sⱼ, sₖ) является инверсией в S'. Во втором случае (sᵢ, sₖ) и (sⱼ, sₖ) являются инверсиями в S, но не в S'. В третьем случае (sⱼ, sₖ) является инверсией в S и (sᵢ, сₖ). Это все изменения в инверсиях.

В каждом случае количество инверсий в S' либо такое же, как и в S, либо меньше. Вспомните, что (sᵢ, sⱼ) было исправлено с S на S', и мы получили желаемый результат. ■

Таким образом, если у нас есть a₁, bᵢ, …, bⱼ, a₂ с каждым aS \ U и каждый bUS и a₁ > a₂, и мы меняем местами a₁ и a₂, получая a₂, bᵢ, …, bⱼ, a₁, количество инверсий меньше. Поскольку такие перестановки переставляют только элементы S \ U, а не элементы US, любое решение, имеющее нулевые инверсии на US и (при этом) минимальное количество инверсий на S \ U должны сделать все такие свопы.

Следовательно: элементы S \ U должны идти по порядку, и, таким образом, решение представляет собой чередование US и S \ U.

person Jonas Kölker    schedule 23.03.2014
comment
Престижность за то, что вы сделали доказательство самостоятельно, я очень ценю это :) Это выглядит хорошо для меня, у меня вчера было что-то не так, когда я думал, что есть проблема. Мой подход был примерно таким: допустим, у нас есть b2 ai, ..., aj b1 в качестве подстроки перестановки, и у нас есть X < b1 < Y < b2 < Z в S, где X, Y и Z представляют подмножества ai, ..., aj. Тогда b2 ai, ..., aj b1 имеет 1 + |X| + 2|Y| + |Z| инверсий, b1 b2 ai, ..., aj имеет 2|X| + |Z| и ai, ..., aj b1 b2 имеет 2|Z| + |Y|. Таким образом, в зависимости от того, |X| < Z| или нет, мы всегда можем добиться большего успеха, используя один из этих - person Niklas B.; 24.03.2014