Given a list K of groups of items, each group possessing some fixed number of items, what would be a time efficient algorithm to generate all (full) permutations of items from said groups?
Example: If K = {A:3, B:2, C:4}, then these are three valid permutations:
AAABBCCCC
ABACCBCCA
CBACCBCAA
There seems to be some relation to Gray code, but with the added weights I'm not sure how to extend it. Trying to do better than monotonously increasing the overall permutation value and resetting on each iteration.
You can have a look at "13.2 Permutations of a multiset"
here https://jjj.de/fxt/fxtbook.pdf
Related
I have n integers a_1, ..., a_n. I want to pick the minimum number from all of them whose xor forms others.
For example, consider [1,2,3], 1^3=2 so you don't need 2 in the array. So you can remove it. To end up with [1,3]. So the min number of elements is 2 and they can form all the original elements in the array by xoring any 2 of them. Would a greedy approach work here? or DP?
Edit: To explain what I am thinking. A greedy approach I thought about was due to the fact that if a^b=c then a^c=b and b^c=a. First I delete all duplicates. then I would first in the beginning list all the pairs that each element can pair up with to form another element in the array. It takes O(n^3) for preprocessing. Then I pick the element with the least contribution and I delete it and subsequently subtract 1 from each of the other elements. I repeat this until all elements have <=2 pairs. and I stop. This would also take O(n^3) for a total of O(n^3). Does this greedy approach work? Is there a DP way to do it?
If n is bounded by 50 I think backtracking should work.
Suppose at some step we have already selected a subset S of numbers (that should produce all the others) and want to include a new number to that subset.
Then we can do the following:
Consider all remaining numbers R and include in S all numbers that can't be produced by others (in S and R)
Include in S a random (or "best" in some way) number from R
Remove from R all numbers that can be produced by those in updated S
Also you should keep track of the current best solution and cut off all the branches that won't allow to get a better result.
I encountered an Interview Question:
There is an event in the auditorium and Given capacity of the auditorium is NxM.
Every group of person booked ticket and all the tickets are booked, Now you have to assign seat number to all of them such that minimum number of group split.
So basically a 2-D array is given and we have some groups of certain size(different groups may be of different size).Array needs to be completely filled with minimum number of groups split.
One Brute force Recursive approach I found is :Place first group ,then second group and so on.Permute this arrangement to find the arrangement with minimum split.
One efficient solution I found was using subset sum problem.
https://en.wikipedia.org/wiki/Subset_sum_problem
I could not understand how subset sum problem can be used to solve this problem.
Please suggest how can I approach this problem.I am not looking for code,just psuedo-code or algorithm will suffice.
Firstly, I'm assuming that "group-split" means that some part of the group is in one row and remaining is in another. If the number of seats in a row are N, and given a set which contains the size of the different groups, you need to find a subset that will sum to N. If such a subset is found, that row will be filled without breaking any groups. If there is no such subset found, then you will need to break at least 1 group. Then there can be multiple strategies here.
1) You can pick a group that will be split across 2 rows. This group can be the largest of the remaining, or the smallest or can be picked at random. Once this group is decided, you have 2 rows with less than N empty seats that need to be filled recursively.
2) The strategy can be to find a subset that sums to 2*N - if found, 1 group will be split. If not found, then find a subset that sums to 3*N with 2 group-splits and so on. The maximum number of group-splits will be M-1 for M rows.
Continue 1) or 2) to fill M number of rows in the theatre.
In a recent campus Facebook interview i have asked to divide an array into 3 equal parts such that the sum in each array is roughly equal to sum/3.My Approach1. Sort The Array2. Fill the array[k] (k=0) uptil (array[k]<=sum/3)3. After that increment k and repeat the above step for array[k]Is there any better algorithm for this or it is NP Hard Problem
This is a variant of the partition problem (see http://en.wikipedia.org/wiki/Partition_problem for details). In fact a solution to this can solve that one (take an array, pad with 0s, and then solve this problem) so this problem is NP hard.
There is a dynamic programming approach that is pseudo-polynomial. For each i from 0 to the size of the array, you keep track of all possible combinations of current sizes for the sub arrays, and their current sums. As long as there are a limited number possible sums of subsets of the array, this runs acceptably fast.
The solution that I would have suggested is to just go for "good enough" closeness. First let's consider the simpler problem with all values positive. Then sort by value descending. Take that array in threes. Build up the three subsets by always adding the largest of the triple to the one with the smallest sum, the smallest to the one with the largest, and the middle to the middle. You will end up dividing the array evenly, and the difference will be no more than the value of the third smallest element.
For the general case you can divide into positive and negative, use the above approach on each, and then brute force all combinations of a group of positives, a group of negatives, and the few leftover values in the middle that did not divide evenly.
Here are details on a dynamic programming solution if you are interested. The running time and memory usage is O(n*(sum)^2) where n is the size of your array and sum is the sum of absolute values of your array values. For each array index j from 1 to n, store all the possible values you can get for your 3 subset sums when you split the array from index 1 to j into 3 subsets. Also for each possibility, store one possible way to split the array to get the 3 sums. Then to extend this information for 1 to (j+1) given the information from 1 to j, simply take each possible combination of 3 sums for splitting 1 to j and form the 3 combinations of 3 sums you get when you choose to add the (j+1)th array element to any one of the 3 subsets. Finally, when you are done and reach j = n, go through the set of all combinations of 3 subset sums you can get when you split array positions 1 to n into 3 sets, and choose the one whose maximum deviation from sum/3 is minimized. At first this may seem like O(n*(sum)^3) complexity, but for each j and each combination of the first 2 subset sums, the 3rd subset sum is uniquely determined. (because you are not allowed to omit any elements of the array). Thus the complexity really is O(n*(sum)^2).
Given a set of n numbers; What is the code that generate all possible k-size subsets in descending order (decreasing each sum of values)?
Example:
Set={9,8,6,2,1} => n=5 and k=3. So the output is:
[9,8,6]
[9,8,2]
[9,8,1]
[9,6,2]
[9,6,1]
[8,6,2]
[8,6,1]
[9,2,1]
[8,2,1]
[6,2,1]
It is preferred the most efficient algorithm, but the algorithm with NP-Complete complexity (n choose k permutations) is the answer yet.
One-by-one generation in the Matlab Code is preferred for implementation. Or a solution that the maximum size of the ordered list in it can be determined (by this, for greater n and k, one may use an approximation and return specific size of this list without computing all possibilities).
Note: 1)Please give attention to the position of [9,2,1] in this ordered list. So index ordering is not the correct answer.
2)This may be a type of Lexicographical order.
Thanks to Divakar, Yvon, and Luis, one of the possible answers to this question:
There are sorted set combinations in the SSC, so
combs = nchoosek(Set,k);
[~,ind] = sort(sum(combs,2),'descend');
SSC = combs(ind,:);
if you want the index of each number array in the Set (has unique numbers), with num_arr index in SSC use this code
for i=1:k
Index(i)=find(SSC(num_arr,j)==Set(1,:));
end
this code returns [1,3,5] for [9,6,1] in Index.
for greater n
In this case, the computation is very time-consuming or even is impractical. An approximation may solves this issue, for such situations, you can find the first arbitrary answer by modifying the nchoosek.m in the Matlab.
I want to find the similarity of two sequences in Ruby based solely on the quantity of shared values. The sequential position of the values should be irrelevant. What should also be irrelevant is whether one sequence has any values that the other sequence does not have. Levenshtein distance was suggested to me, but it computes the number of edits required to make the sequences identical. Here's a simple example of where the flaw is there:
[1,2,3,4,5]
[2,3,4,5,6,7,8,9]
#Lev distance is 5
[1,2,3,4,5]
[6,7,8,9,10]
#Lev distance is 5
In a perfect world the first set would have much greater similarity than the second set. The crude, obvious solution is to use nested loops to check each value of the first sequence against each value of the second. Is there a more efficient way?
You can do an intersection for a pair of arrays using an & like this:
a = [1,2,3,4,5]
b = [2,3,4,5,6,7,8,9]
common = a & b # => [2, 3, 4, 5]
common.size # => 4
Is this what you are looking for?
If the sequences are sorted (or you sort them), all you have to do is walk down both lists, incrementing the similarity counter and popping off both values if they match. If they don't match, you pop off the smaller value, and continue until one list is empty. The complexity of this is O(n log n) for the sorting plus O(n) for the walk, where n is the sum of the lengths of the two lists.
You could also loop through each list, counting the incidence of each number (so you end up with a list of the counts of each value). Then you could compare these quantities, incrementing the similarity counter by the lesser count for each value.