Generating permutations which are not mirrors of each other - c++

I want to generate permutations of n numbers, where there is no two permutations which are reversions of each other (the first one read from the last character to the first is the same as the second one). For instance, n = 3, I want to generate:
1 2 3 //but not 3 2 1
1 3 2 //but not 2 3 1
2 1 3 //but not 3 1 2
I do not care which one of the two will be generated. The algorith should be applicable for large n (>20). Is there any such algorithm or a way to check if the generated permutations is a mirror of previously generated one?

Use std::next_permutation and ignore permutations whose first element is larger than its last.

No, By usual hardware and software upto this days, you cannot do this, because the number of such a permutations is 20!/2 > 10^10 * 2^20, means you need many years to generate them.

Related

Efficient algorithm for finding max number of pairs [duplicate]

This question already has answers here:
Choosing mutually exclusive pairs efficiently
(4 answers)
Closed 7 years ago.
What would be the fastest way to find pairs of numbers from a list of pair of numbers such that maximum number of pairs are formed?
For e.g: I have 6 numbers: 0, 1, 2, 3, 4, 5
Following are the valid pairs:
0 1
0 2
0 3
1 4
3 5
Now, once a number is included in a pair, the number cannot be included in another pair.
That is, if I chose the pair 0 1, I cannot again chose 0 2 as I have already used 0 once.
I need to choose pairs from the list of valid pairs such that I get maximum number of pairs.
As per the example:
If I choose the following pairs:
0 1
3 5
Note that I'll be able to chose only these two pairs such that no number is repeated and 2 and 4 will be left.
But If I choose the following pairs:
0 2
1 4
3 5
I get three pairs and no number is left alone. Similarly from a given list, I need to calculate the maximum number of pairs I can make. What would be the most efficient way to do it?
This problem can be solved in polynomial time complexity using Bloossom algorithm:
http://en.wikipedia.org/wiki/Blossom_algorithm
Form a graph where each number is node and connect each pair with edge. Run the above mentioned algorithm on this graph to find solution.
So your valid pairs could be represented as a graph, and then the maximum number of pairs is a maximum matching in that graph.
Note that you can have multiple solutions. For valid pairs [(0,1),(1,2),(2,3),(3,4)] both [(0, 1), (2, 3)] and [(1, 2), (3, 4)] are solutions.

C++ two dimensional array of bitsets

I have an assignment where we're tackling the traveling salesman problem.
I'm not going to lie, the part I'm doing right now I actually don't understand fully that they're asking, so sorry if I phrase this question weirdly.
I sort of get it, but not fully.
We're calculating an approximate distance for the salesman. We need to create a two-dimensional array, of bitsets I believe? Storing the values in binary anyway.
0 represents that the city hasn't been visited, and 1 represents that is has been visited.
We've been given an algorithm that helps significantly, and I should be able to finish it if anyone here can help with the first step:
Create memoisation table [N][(1 << N)]
(where N = number of cities).
I get that 1 << N means convert the number of cities (e.g. 5) to binary, then move the set to the left by one place.
My main issues are:
Converting N to binary (I think this is what I need to do?)
Moving the set to the left by one
Actually creating the 2-dimensional array of these sizes...
I could be wrong here, in fact that's probably pretty likely... any help is appreciated, thanks!
Here is the general rule "<<" operator means left shift and ">>" means right shift. Right shifting any number by 1 is equivalent to divide by 2 and left shift any numbers by 2 is equivalent to multiply by 2. For example lets say a number 7 (Binary 111). So 7 << 1 will become 1110 which is 7 * 2 = 14 and 7 >> 1 will become 11 which is 7 / 2 = 3 .
So for algorithm to convert a number N to a bitset array as binary is
N mod 2 (take the remainder if you divide N by 2)
Store the remainder in a collection (i.e, List, Array, Stack )
Divide N by 2
If N/2 >1 Repeat from step 1 with N/2
Else reverse the array and you have your bitset.
Moving the set left to one, If you meant leftshift by one you can do it by N<<1
This is how you create 2 dimensional array in C++
[Variable Type] TwoDimensionalArray[size][size];
For this problem though I believe you might want to read about C++ bitset and you can easily implement it using bitset. For that you just have to figure out the size of the bitset you want to use. For example if the highest value of N is 15 then you need a bitset size of 4. Because with 4 bit the maximum number you can represent is 15 (Binary 1111). Hope this helps.

Compression of sorted data with small difference

I have sorted data sequence of integers. Maximal difference between 2 numbers is 3. So data looks for example like this:
Data: 1 2 3 5 7 8 9 10 13 14
Differences: (start 1) 1 1 2 2 1 1 1 3 1
Is there a better way to store (compress) this type of sequences, than save difference values? Because if I use dictionary based methods, It failed to compress, because of randomness of numbers 1,2 and 3. If I use "PAQ" style compression, result are better, but still not quite satisfying. Huffman and Arithmetic coder is worse than dictionary based methods.
Is there some way with prediction?
For example to use regression for original data and than store differences (which could be smaller or more consistent)
Or use some kind of prediction based on histogram of differences?
Or something totally different.... or its not possible at all (which is, in my oppinion, the real answer :))
Since you say in the comments that you're already storing four differences per byte, you're likely to not do much better. If the differences 0, 1, 2, and 3 were random and evenly distributed, then there would be no way to do better.
If they are not evenly distributed, then you might be able to do better with a Huffman or arithmetic code. E.g. if 1 is more common than 0, which is more common than 2 and 3, then you could store 1 as 0, 0 as 10, 2 as 110, and 3 as 111. Or if 0 never happens, 1 as 0, 2 and 3 as 10 and 11. You could do better with an arithmetic code for the case you quote where 1 occurs 80% of the time. Or a poor man's arithmetic code by coding pairs of symbols. E.g.:
11 0
13 100
21 101
12 110
31 1110
22 111100
23 111101
32 111110
33 111111
would be a good code for 1 80%, 2 10%, 3 10%. (That doesn't quite handle the case of an odd number of differences, but you could deal with that with just a bit at the start indicating an even or odd number, and a few more bits at the end if odd.)
There might be a better predictor than the previous value. This would be a function of n previous values instead of just one previous value. However this would be highly data dependent. For example you could assume that the current value is likely to fall on the line made by the previous two values. Or that it falls on the parabola made by the previous three values. Or some other function, e.g. a sinusoid with some frequency, if the data is so biased.

Creating a list of the different numbers that occur in a 2D array using the GPU

Given a 2D array of integers, for example
3 3 1 1 1
3 3 3 1 1
3 3 3 3 1
3 3 3 2 2
3 3 7 2 2
is there an efficient GPU algorithm, that produces a list of all occuring numbers?
For example
1 2 3 7
for the 2d array above.
The list does not need to be sorted (so 3 2 1 7 for example would be okay as well).
Assuming there isn't too large of a range of integers to be dealt with (and that these are non-negative integers) you can make a new array that has the length of the range of possible integers in your original array with values initialized to zero.
Then, when a thread finds a number it increments that index of the array by one (so if we see the integer 4 we do something like result[4]++. We won't need to sync here since all we'll care about is whether or not a given index of this result array has a value of zero or not.
Of course this can be done if we'll expect negative integers as well - we'll just need twice the space in our result array.

Number contained in an odd number of sets

I have a homework problem which i can solve only in O(max(F)*N) ( N is about 10^5 and F is 10^9) complexity, and i hope you could help me. I am given N sets of 4 integer numbers (named S, F, a and b); Each set of 4 numbers describe a set of numbers in this way: The first a successive numbers, starting from S included are in the set. The next b successive numbers are not, and then the next a numbers are, repeating this until you reach the superior limit, F. For example for S=5;F=50;a=1;b=19 the set contains (5,25,45); S=1;F=10;a=2;b=1 the set contains (1,2,4,5,7,8,10);
I need to find the integer which is contained in an odd number of sets. It is guaranteed that for the given test there is ONLY 1 number which respects this condition.
I tried to go trough every number between min(S) and max(F) and check in how many number of sets this number is included, and if it is included in an odd number of sets, then this is the answer. As i said, in this way I get an O (F*N) which is too much, and I have no other idea how could I see if a number is in a odd number of sets.
If you could help me I would be really grateful. Thank you in advance and sorry for my bad English and explanation!
Hint
I would be tempted to use bisection.
Choose a value x, then count how many numbers<=x are present in all the sets.
If this is odd then the answer is <=x, otherwise >x.
This should take time O(Nlog(F))
Alternative explanation
Suppose we have sets
[S=1,F=8,a=2,b=1]->(1,2,4,5,7,8)
[S=1,F=7,a=1,b=0]->(1,2,3,4,5,6,7)
[S=6,F=8,a=1,b=1]->(6,8)
Then we can table:
N(y) = number of times y is included in a set,
C(z) = sum(N(y) for y in range(1,z)) % 2
y N(y) C(z)
1 2 0
2 2 0
3 1 1
4 2 1
5 2 1
6 2 1
7 2 1
8 2 1
And then we use bisection to find the first place where C(z) becomes 1.
Seems like it'd be useful to find a way to perform set operations, particularly intersection, on these sets without having to generate the actual sets. If you could do that, the intersection of all these sets in the test should leave you with just one number. Leaving the a and b part aside, it's easy to see how you'd take the intersection of two sets that include all integers between S and F: the intersection is just the set with S=max(S1, S2) and F=min(F1, F2).
That gives you a starting point; now you have to figure out how to create the intersection of two sets consider a and b.
XOR to the rescue.
Take the numbers from each successive set and XOR them with the contents of the result set. I.e., if the number is currently marked as "present", change that to "not present", and vice versa.
At the end, you'll have one number marked as present in the result set, which will be the one that occurred an odd number of times. All of the others will have been XORed an even number of times, so they'll be back to the original state.
As for complexity, you're dealing with each input item exactly once, so it's basically linear on the total number of input items -- at least assuming your operations on the result set are constant complexity. At least if I understand how they're phrasing things, that seems to meet the requirement.
It sounds like S is assumed to be non-negative. Given your desire for an O(max(F)*N) time boundary you can use a sieving-like approach.
Have an array of integers with an entry for each candidate number (that is, every number between min(S) and max(F)). Go through all the quadruples and add 1 to all array locations associated with included numbers represented by each quadruple. At the end, look through the array to see which count is odd. The number it represents is the number that satisfies your conditions.
This works because you're going under N quadruples, and each one takes O(max(F)) or less time (assuming S is always non-negative) to count the included numbers. That gives you O(max(F)*N).