Merging two partial (jointly overdetermined) sets of ordering information

前端 未结 3 699
南旧
南旧 2021-01-06 04:34

I have a web app with data in a grid. The user can reorder the columns, and the server can change which columns exist. I would like to save the user\'s column order in a coo

3条回答
  •  臣服心动
    2021-01-06 05:32

    Let's say we have C columns, numbered from 1 to C. We have two sequences sequences of columns, U = u1, u2, ... un and S = s1, s2, ... sm. We want to find a permutation P of S, such that P has no inversions with regard to U and a minimal number of inversions with regard to S.

    We can show that there is such an optimal P which is an interleaving of U ∩ S and S \ U. By "interleaving" I mean that P has no inversions with regard to U ∩ S or S \ U.

    We can apply dynamic programming to find the optimal interleaving: Let A = (ai) = U ∩ S and B = (bj) = S \ U. Let f(i,j) be the number of inversions w.r.t. S of the optimal interleaving of the prefixes a1...i of A and b1...j of B. The idea is very similar to the longest common subsequence DP algorithm. We have the recurrence

    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]))
    

    I used the notation [1 if X] here to denote the value 1, if X is true and 0, if X is false.

    The matrix f can be built in time O(|A|^2 * |B|^2). The minimal cost (number of inversions w.r.t. S) will be f(|A|, |B|).

    We can reconstruct the optimal permutation using the DP matrix as well: We build it from back to front. We start with the tuple (i,j) = (|A|, |B|) and at every step depending on which of the two options is minimum in the DP transition, we know whether we need to put A[i] or B[j] to the front of the permutation. Then we proceed with (i-1, j) or (i, j-1) depending on which we choose.

    Here is an implementation of the algorithm, please excuse my lack of JS skills.

提交回复
热议问题