Dynamic programming approach to from number list (use pseudo code) - algorithm

STATE the running time of the methods. Polynomial time algorithms are expected.
A club wants to organize a party for the students. However, only part of the students can attend
the party. The candidates are choosing by pairs with the following requirements: assume the
students are lined-up, each student is given a lucky number, and some students may have the
same lucky numbers. The club requires that only students who have the same luck numbers may
be paired-up and join in the party while all the students locate within a chosen pair will lose the
opportunity.
We have helped the club to formulate the problem formally.
Given a sequence of positive integers (represent the lucky numbers) A = (a1, a2, ... an), a pair (ai, aj) is defined as a dancing pair if ai=aj, and i<j. A dancing pair list L={(π‘Žπ‘–1, π‘Žπ‘—1),… (π‘Žπ‘–π‘˜, π‘Žπ‘—π‘˜) }
is good if and only if for any two pairs (π‘Žπ‘–π‘₯, π‘Žπ‘—π‘₯), (π‘Žπ‘–π‘¦, π‘Žπ‘—π‘¦) of L, either jx<iy or jy<ix for 1 ≀ π‘₯, 𝑦 ≀ π‘˜.
For example, if A={1, 3, 4, 1, 2, 3, 2, 4, 3, 5, 3, 4, 5}, some good dancing lists might be:
{(1, 1), (2, 2), (3, 3)} (locations in A={1, 3, 4, 1, 2, 3, 2, 4, 3, 5, 3, 4, 5})
{(1, 1), (3, 3) (5, 5)} (locations in A={1, 3, 4, 1, 2, 3, 2, 4, 3, 5, 3, 4, 5})
a) Given a sequence of positive integers A, design a polynomial time algorithm to find a
good dancing pair list with maximum number of dancing pairs.
b) Assume the weight of the dancing pair (ai, aj) is ai+aj. The total weight of a good dancing
list is the sum of all the weights of the dancing pairs in the list. Design a polynomial time
algorithm to find a good dancing pair list with maximum total weight.
for part a,
if i write like this
foreach list L
foreach item I in list L
foreach list L2 such that L2 != L
for each item I2 in L2
if I == I2
return new 3-tuple(L, L2, I) //
how to continue?

Related

How would I code an algorithm that does as follow?

I have three arrays of six red numbers ranging from 1 to 6. There can be multiple times the same number.
For example, [1, 4, 3, 3, 6, 2], [5, 5, 2, 1, 3, 4] and [2, 4, 3, 1, 1, 6]
The goal of the algorithm is to turn numbers blue in those arrays following these rules:
Every blue number has to be unique (1, 2, 3, 4, 5, 6)
Each array should have 2 blue numbers
The algorithm should warn me if it isn't possible to do so
In this example, the blue numbers could be (1, 4) in array one, (2, 5) in array two and (3, 6) in array three.
Is it realistic to code an algorithm that could do that? I'm looking for the logic that I could code to make it work.
You can reduce this problem to bipartite matching.
If we consider two sets of vertices, one for the arrays and one for the numbers, and make an edge between the array A and number n if n is an element of A, then we have a bipartite graph on which we can use any matching algorithm. Then, each match between an array and a number indicates that that number is blue in that array.
This only works for making a single number blue for each array, but can be expanded by adding every array as a vertex twice, thus getting two matches per array and therefore two blue numbers per array.

Exact amount of comparisions in Insertion Sort

I want to get number of permutations of {1, ..., n} for which Insertion Sort does exactly n(n-1)/2 comparisions.
For example, for {1, 2, 3, 4} we got (4, 3, 2, 1), (3, 4, 2, 1), (4, 2, 3, 1) etc. - for all of them InsertionSort does 4*3/2 = 6 comparisions.
Anybody know some exact formula for that?
I am thinking about something like (n-1) + 1 = n, where
1 stands for reverse sequence and then we can swap all of (n-1) pairs in reverse sequence.
Here is a hint. The complete list for (1, 2, 3, 4) are:
(4, 3, 2, 1)
(3, 4, 2, 1)
(4, 2, 3, 1)
(2, 4, 3, 1)
(4, 3, 1, 2)
(3, 4, 1, 2)
(4, 1, 3, 2)
(1, 4, 3, 2)
Look at it from last column to first.
Walk step by step through the insertion sorts. See where they merge. Do you see a pattern there?
Reversing it, can you figure out how I generated this list? Can you prove that the list is complete?
The why is what matters here. Just saying 2n-1 is useless.
n(n-1)/2 is the sum of all elements in the range (1, n - 1). Since your sequence has length n, you can expand that range to (0, n - 1).
The number of swaps for each insertion would be:
run # list value swaps
1 [] a 0 (no swaps possible)
2 [a] b 1
3 [b, a] c 2
...
10 [i,...,a] j 9
...
n [...] ? n - 1
So we need to move every element through the entire list in order to achieve the required count of swaps. The number of comparisons can be at most one higher than the number of swaps, which means each value that is being inserted must either be placed at the first or second index of the resulting list. Or
Put differently, assuming ascending ordering of the output:
The input list should in general be a nearly descending list, where each element in the list may be preceded by at most one element that is not larger than the element in question.

N nonΒ­ overlapping Optimal partition

Here is a problem I run into a few days ago.
Given a list of integer items, we want to partition the items into at most N nonΒ­overlapping, consecutive bins, in a way that minimizes the maximum number of items in any bin.
For example, suppose we are given the items (5, 2, 3, 6, 1, 6), and we want 3 bins. We can optimally partition these as follows:
n < 3: 1, 2 (2 items)
3 <= n < 6: 3, 5 (2 items)
6 <= n: 6, 6 (2 items)
Every bin has 2 items, so we can’t do any better than that.
Can anyone share your idea about this question?
Given n bins and an array with p items, here is one greedy algorithm you could use.
To minimize the max number of items in a bin:
p <= n Try to use p bins.
Simply try and put each item in it's own bin. If you have duplicate numbers then your average will be unavoidably worse.
p > n Greedily use all bins but try to keep each one's member count near floor(p / n).
Group duplicate numbers
Pad the largest duplicate bins that fall short of floor(p / n) with unique numbers to the left and right (if they exist).
Count the number of bins you have and determine the number mergers you need to make, let's call it r.
Repeat the following r times:
Check each possible neighbouring bin pairing; find and perform the minimum merger
Example
{1,5,6,9,8,8,6,2,5,4,7,5,2,4,5,3,2,8,7,5} 20 items to 4 bins
{1}{2, 2, 2}{3}{4, 4}{5, 5, 5, 5, 5}{6, 6}{7, 7}{8, 8, 8}{9} 1. sorted and grouped
{1, 2, 2, 2, 3}{4, 4}{5, 5, 5, 5, 5}{6, 6}{7, 7}{8, 8, 8, 9} 2. greedy capture by largest groups
{1, 2, 2, 2, 3}{4, 4}{5, 5, 5, 5, 5}{6, 6}{7, 7}{8, 8, 8, 9} 3. 6 bins but we want 4, so 2 mergers need to be made.
{1, 2, 2, 2, 3}{4, 4}{5, 5, 5, 5, 5}{6, 6, 7, 7}{8, 8, 8, 9} 3. first merger
{1, 2, 2, 2, 3, 4, 4}{5, 5, 5, 5, 5}{6, 6, 7, 7}{8, 8, 8, 9} 3. second merger
So the minimum achievable max was 7.
Here is some psudocode that will give you just one solution with the minimum bin quantity possible:
Sort the list of "Elements" with Element as a pair {Value, Quanity}.
So for example {5,2,3,6,1,6} becomes an ordered set:
Let S = {{1,1},{2,1},{3,1},{5,1},{6,2}}
Let A = the largest quanity of any particular value in the set
Let X = Items in List
Let N = Number of bins
Let MinNum = ceiling ( X / N )
if A > MinNum then Let MinNum = A
Create an array BIN(1 to N+1) of pointers to linked lists of elements.
For I from 1 to N
Remove as many elements from the front of S that are less than MinNum
and Add them to Bin(I)
Next I
Let Bin(I+1)=any remaining in S
LOOP while Bin(I+1) not empty
Let MinNum = MinNum + 1
For I from 1 to N
Remove as many elements from the front of Bin(I+1) so that Bin(I) is less than MinNum
and Add them to Bin(I)
Next I
END LOOP
Your minimum bin size possible will be MinNum and BIN(1) to Bin(N) will contain the distribution of values.

Finding a group of subsets that does not overlap

I am reviewing for an upcoming programming contest and was working on the following problem:
Given a list of integers, an integer t, an integer r, and an integer p, determine if the list contains t sets of 3, r runs of 3, and p pairs of numbers. For each of these subsets, the numbers must be adjacent and any given number can only exist in one subset, if any at all.
Currently, I am solving the problem by simply finding all sets of 3, runs of 3, and pairs and then checking all permutations until finding one which has no overlapping subsets. This seems inefficient, however, and I was wondering if there was a better solution to the problem.
Here are two examples of the problem:
{1, 1, 1, 2, 3, 4, 4, 4, 5, 5, 1, 0}, t = 1, r = 1, p = 2.
This works because we have the triple {4 4 4}, the run {1 2 3}, and the pairs {1 1} and {5 5}
{1, 1, 1, 2, 3, 3}, t = 1, r = 1, p = 1
This does not work because the only triple is {1 1 1} and the only run is {1 2 3} and the two overlap (They share a 1).
I am looking for a more efficient approach to this problem.
There is probably a faster way, but you can solve this with dynamic programming. Compute a recursive function F(t,r,p,n) which decides whether it is possible to have t triples, r runs, and p pairs in the sequence starting at position 1 and ending at n, and storing the last subset of the solution ending at position n if it is possible. If you can have a triple, run, or pair ending at position n then you have a recursive case, either. F(t-1,r,p,n-3) or F(t,r-1,p,n-3) or F(t,r,p-1,n-2), and you have the last subset stored, or otherwise you have a recursive case F(t,r,p,n-1). This looks like fourth power complexity but it really isn't, because the value of n is always decreasing so the complexity is actually O(n + TRP), where T is the total desired number of triples, R is the total desired number of runs, and P is the total desired number of pairs. So O(n^3) in the worst case.

List all k-tuples with entries summing to n, ignoring rotations

Is there an efficient algorithm for finding all sequences of k non-negative integers that sum to n, while avoiding rotations (completely, if possible)? The order matters, but rotations are redundant for the problem I'm working on.
For example, with k = 3 and n = 3, I would want to get a list like the following:
(3, 0, 0), (2, 1, 0), (2, 0, 1), (1, 1, 1).
The tuple (0, 3, 0) should not be on the list, since it is a rotation of (3, 0, 0). However, (0, 3, 0) could be in the list instead of (3, 0, 0). Note that both (2, 1, 0) and (2, 0, 1) are on the list -- I do not want to avoid all permutations of a tuple, just rotations. Additionally, 0 is a valid entry -- I am not looking for partitions of n.
My current procedure is to loop from over 1 <= i <= n, set the first entry equal to i, and then recursively solve the problem for n' = n - i and k' = k - 1. I get some speed-up by mandating that no entry is strictly greater than the first, but this approach still generate a lot of rotations -- for example, given n = 4 and k = 3, both (2,2,0) and (2,0,2) are in the output list.
Edit: Added clarifications in bold. I apologize for not making these issues as clear as I should have in the original post.
You can first generate the partitions (which ignore order completely) as a tuple (x_1, x_2, ..., x_n)
where x_i = number of times i occurs.
So Sum i* x_i = n.
I believe you already know how to do this (from your comments).
Once you have a partition, you can now generate the permutations for this (viewing it as a multiset {1,1,...,2,2...,...n}, where i occurs x_i times) which ignore rotations, using the answer to this question:
Is there an algorithm to generate all unique circular permutations of a multiset?
Hope that helps.
You could just sort your solutions and eliminate rotations that way.
OR
you can try to make your recursive solution build tuples that will only ever be sorted
how? here's something I made up quickly
static list<tuple> tups;
void recurse(tuple l, int n, int k, int m)
{
if (k == 0 && n == 0)
{
tups.add(l);
return;
}
if (k == 0)
return;
if (k*m > n) //prunes out tuples that could not possibly be sorted
return;
else
for(int x = m; x <= n; x++)
recurse(l.add(x), n-x, k-1, x); //try only tuples that are increasing
}
call this with m = 0 and an empty list for the initial step.
here's a C# console app implementation : http://freetexthost.com/b0i05jkb4e
Oh, I see my mistake in the assumption of rotation, I thought you just meant permutations, not an actual rotation.
However, you can extend my solution to create non-rotational permutations of the unique increasing tuples. I'm working on it now
You need to generate Integer Partitions in lexicographical order.
Here is a very good paper with fast algorithms.
HTH.
Note that CAS programs usually implement these functions. For example in Mathematica:
Innput: IntegerPartitions[10, {3}]
Output: {{8, 1, 1}, {7, 2, 1}, {6, 3, 1},
{6, 2, 2}, {5, 4, 1}, {5, 3, 2},
{4, 4, 2}, {4, 3, 3}}

Resources