Maximum number of distinct inversions in an array - sorting

Given an array A of n integers, we say that a pair of indices i<j∈[n] is an inversion in A if A[i]>A[j]. What is the maximum number of distinct inversions that A can have?
Is it
a) n - 1
b) n
c) n(n−1)/2
d) n^2
e) n(n−1)(2n−1)/6

Well, it's obviously possible for all pairs of distinct indices to be inversions (if the entire array is in reverse order, e.g.: [5,4,3,2,1]). And it's obviously not possible for more than all pairs of distinct indices to be inversions.
So the question is: how many pairs of distinct indices are there?
If you arrange them geometrically, the pattern is pretty clear:
(1,2) (1,3) (1,4) (1,5)
(2,3) (2,4) (2,5)
(3,4) (3,5)
(4,5)
(Note that I didn't include e.g. (2,1), since that's the same two indices as (1,2).)
Such numbers are called triangular numbers, for obvious reasons. Wikipedia gives a formula, but be sure not to confuse the n in its formula with the n in your problem statement. (They are slightly different. You'll need to do a small amount of algebra.)

Related

Counting the number of same ordered pairs in three different permutations

I have three different permutations of the set {1,2,..n}, and I would like to write some code to count the number of pairs of numbers that come in the same order in all three permutations.
As an example with permutation of.
{1,2,3}
(1,2,3).
(3,2,1)
there are 0 such pairs where they come in the same order because (1,2,3) and (3,2,1) are sorted in both increasing and decreasing order
I want an optimal O(N*logN) solution. A hint was given, in which you have to count the number of inversions of each permutation, i.e
an inversion is the of pair (i,j) such that i > j but a[j] > a[i]
I can do this in O(NlogN).
So definitely if one pair came in the increasing order in each of the permutations it would add 1 to each inversion count for each permutation. But that isn't true if i > j and
a[j] > a[i] (all came in decreasing order) as I should be increasing the count but this doesn't contribute anything to the inversion count. Also afterwards if I can count the number of inversions in each array, but I don't see a link between that and the number of same-ordered pairs.
For each permutation you have, you should count the number of cases where a[i] < a[j], for each pair of indices i and j such that i < j. Let's call this non-inversions. Then, you can find out the result by taking the minimum of the non-inversion counts you found.
For instance, in your sample case, the values corresponding for the permutations (1,2,3), (1,2,3) and (3,2,1) are 3, 3, and 0, respectively.
For a different sample case, you can examine (1,2,3,4), (1,2,4,3), (1,3,2,4) and (4,1,3,2). The corresponding counts for these permutations are 6, 4, 5, and 2. The result is min(6,4,5,2) because the only tuples that remain ordered in each case are (1, 2) and (1, 3).
The key idea behind this solution is based on what non-inversion count implies. In an ordered array of size N, there are N(N-1)/2 ordered pairs contributing to the non-inversion count. As you introduce some inversions into that array, the relative order of some elements are lost, while some remain. By finding the minimum of the non-inversion counts, you can find the number of pairs that preserve their relative ordering in the 'worst' case. (even though this alone is not enough not identify them individually)
If you insist on counting the inversions (i.e. as opposed to the non-inversions) the procedure is pretty much the same. Count the inversions for each permutation given to you. Then simply subtract the maximum value you find from N(N-1)/2, and obtain the result.

Finding two sublists of fixed sizes (K,L) to maximize total sum among positive sequence

Given a list of positive integers, and two integers K and L, I need to select two non-overlapping contiguous sublists of lengths K and L so as to maximize the combined sum of the two sublists.
For example, if the list is [6,1,4,6,3,2,7,4], K = 3, and L = 2, then I want the sublists [4,6,3] and [7,4], whose combined sum of 24 is the maximum achievable.
The list has at least K + L elements and at most 600 elements; the elements are integers in the range [1, 500].
I do not know where to start. I'm thinking a Dynamic Programming solution, but I'm not very familiar with it so I'm not sure if that's the way to go.
Scan array left to right, calculating partial sums for continuous subarrays of length K and of length L starting at every index. It might be performed in O(n).
Write the largest sums before each index to auxiliary arrays LeftK, LeftL
Write the largest sums after each index to auxiliary arrays RightK, RightL
Now for every index i get sums of LeftK[i]+RightL[i] and LeftL[i]+RightK[i] and choose the best sum among all entries.

Finding all pair of points with the same distance to a line in O(nlogn)

I am trying to solve an algorithm problem. I have 2 arrays, say A and B, containing some points. Length of A and B are the same. I know that all points in A and B are distinct. Now, I want to find all the pairs with the same distance to a line. There is also one more rule. I cannot compare 2 points both in A and both in B.
How can I solve this problem in O(nlogn)? I think this is a divide and conquer problem, but I could not find a solution.
Thanks in advance.
EDIT: An example:
Line -> y=0
A = {(1,2), (3,4)}
B = {(1,-2), (3,-4)}
Output -> {{(1,2), (1,-2)}, {(3,4), (3,-4)}}
EDIT2: Assume that all distances are also distinct.
This is esoteric (prohibition of comparing two points looks silly here) variant of nuts and bolts problem. O(NlogN) solution might use quicksort-like partition:
Make comparison function like this:
float Compare(int A_Index, int B_Index)
return Distance(line, A[A_Index]) - Distance(line, B[B_Index])
Choose random index a_idx from A. Partition B array using Compare with a_idx. Resulting pivot B[b_idx] corresponds to A[a_idx] element. Now partition array A against b_idx. You have a pair of equal elements and left and right subarrays of points with smaller and larger distances.
Repeat for both halves of arrays until all points are paired.
Why not an O(n) routine? Hash the distance from each point in A to Line:
Distance 1 -> {A[0]}
Distance 2 -> {A[1]}
Iterate over B and if the distance from B[i] to Line has already been hashed, add B[i] to make a pair:
Distance 1 -> {A[0], B[0]}
Distance 2 -> {A[1], B[1]}
A hash table (std::unordered_map) which was keyed on the distance, would have a feature of N insertions of order O(1). However, if there was a collision with the key it would break the constraint of comparing 2 A elements.
Searching the hash table for elements in B would also be O(1). So the performance would be O(N) - but I can't see how to avoid the collision case.

Algorithm design manual (Steven Skiena) regarding random samples on Ordered pairs Page 250

given the following explanation
Problem: We need an efficient and unbiased way to generate random
pairs of vertices to perform random vertex swaps. Propose an efficient
algorithm to generate elements from the (n 2) unordered pairs on {1,
. . . , n} uniformly at random.
Solution: Uniformly generating random structures is a surprisingly
subtle problem. Consider the following procedure to generate random
unordered pairs: i = random int(1,n-1); j = random int(i+1,n);
It is clear that this indeed generates unordered pairs, since i < j.
Further, it is clear that all (n 2) unordered pairs can indeed be
generated, assuming that random int generates integers uniformly
between its two arguments.
But are they uniform? The answer is no. What is the probability that
pair (1,2) is generated? There is a 1/(n−1) chance of getting the 1,
and then a 1/(n−1) chance of getting the 2, which yields p(1,2) = 1/(n
− 1)2. But what is the probability of getting (n − 1,n)? Again, there
is a 1/n chance of getting the first number, but now there is only one
possible choice for the second candidate! This pair will occur n times
more often than the first! The problem is that fewer pairs start with
big numbers than little numbers. We could solve this problem by
calculating exactly how unordered pairs start with i (exactly (n − i))
and appropriately bias the probability. The second value could then be
selected uniformly at random from i + 1 to n.
But instead of working through the math, let’s exploit the fact that
randomly generating the n2 ordered pairs uniformly is easy. Just pick
two integers independently of each other. Ignoring the ordering (i.e.
, permuting the ordered pair to unordered pair (x,y) so that x < y)
gives us a 2/n^2 probability of generating each unordered pair of
distinct elements. If we happen to generate a pair (x,x), we discard
it and try again. We will get unordered pairs uniformly at random in
constant expected time using the following algorithm:
in the above paragraph "The problem is that fewer pairs start with
big numbers than little numbers." shouldn't this be more pairs instead of fewer pairs
in the above paragraph "We could solve this problem by calculating exactly how unordered pairs start with i (exactly (n − i))" shouldn't this me how many unordered pairs rather than how unordered pairs
EDIT
in the above paragraph "Ignoring the ordering (i.e.
, permuting the ordered pair to unordered pair (x,y) so that x < y)
gives us a 2/n^2 probability of generating each unordered pair of
distinct elements." how is the probability 2/n^2 derived ?
Thanks
in the above paragraph "The problem is that fewer pairs start with big numbers than little numbers." shouldn't this be more pairs instead of fewer pairs
No, it's fewer.:
n - 1 pairs start with 1 (1 2; 1 3; ...; 1 n)
n - 2 pairs start with 2 (2 3; 2 4; ...; 2 n)
n - 3 pairs start with 3
...
in the above paragraph "We could solve this problem by calculating exactly how unordered pairs start with i (exactly (n − i))" shouldn't this me how many unordered pairs rather than how unordered pairs
Yes, there is a missing "many" there.
in the above paragraph "Ignoring the ordering (i.e. , permuting the ordered pair to unordered pair (x,y) so that x < y) gives us a 2/n^2 probability of generating each unordered pair of distinct elements." how is the probability 2/n^2 derived ?
There are n*n possibilities of generating pairs where order does matter (1 2 and 2 1 are different pairs). Since you then proceed to ignore the ordering, both 1 2 and 2 1 will be the same, so you have two favorable cases.
This does not account for the fact that you discard x x pairs though. Then it would be 2 / (n*(n - 1)), because if you pick x once, you only have n - 1 possibilities for the second pick.
Assuming the indices for your n items are 0..(n-1), and random(n) gives a random number ≥ 0 and < n :
i = random(n)
j = random(n-1)
j = (i+j+1) % n
Now every pair (i,j) with i≠j has exactly probability 1/(n(n-1)). Obviously, swapping (i,j) has the same result as swapping (j,i).
You could also do:
i = random(n)
j = random(n)
And ignore the fact that this may result in (i,i) pairs (swapping them will have no effect).

finding the maximum sum in Matrix

Input: A 2-dimensional NxN -symmetric Matrix - with NxN positive elements.
Output: A 2-dimensional matrix of NxN size with N selected elements such that its summation is the maximum among all possible selection. Other elements that are not selected are zero. In other words, we should select N elements from matrix to return maximum sum.
Requirement: If the dimension of matrix is 4*4, we should select 4 integer. Every row and column in matrix should not be used more than 2 times.
For example if we have 4*4 matrix, the following element could be selected:
(1,2)
(2,3)
(3,4)
(4,1)
but if we select (1,2)and (4,1), we cannot select (1,3), because we used 1 two times.
IS there an efficient algorithm for this problem?
This problem is in that weird place where it's not obvious that there's a solution polytope with integral vertices and yet its similarity to general matching discourages me from looking for an NP-hardness reduction. Algorithms for general matching are complicated enough that modifying one would be a daunting prospect even if there were a way to do it, so my advice would be to use an integer program solver. There's a formulation like
maximize sum_{ij} w_{ij} x_{ij}
subject to
sum_{ij} x_{ij} = n
forall k, sum_i x_{ik} + sum_j x_{kj} ≤ 2
forall ij, x_{ij} in {0, 1},
where w_{ij} is the ijth element of the weight matrix.

Resources