This question already has answers here:
All possible permutations of a NxN matrix in Java
(2 answers)
Closed 1 year ago.
Permutation matrices are matrices with exactly one 1 on each line and column.
Example:
(1 0 0)
(0 1 0)
(0 0 1)
I am trying to generate all possible permutations of a n-sized matrix but this seems harder to solve than expected. I tried swapping rows at first, but if you only swap rows of one initial matrix, you can't generate all possibilities. So I tried some recursion, but sadly I can't get my head through recursion. Does somebody have some advice?
I think you could make an algorithm based on recursion, with this design:
public Collection<Matrix> permute(int n)
Base case is n=1: It returns a single matrix {1}.
The rest of cases must iterate from i=0 to n-1. On eeach iteration:
Call to permute(n-1) and iterate the returned list. On each iteration:
Convert the n-1 matrix to a n x n matrix, inserting a row at position 0 and a column at position 0 (filled with 0).
Set an 1 in the (0,0) position.
Move the first column to the i position.
I suggest you could also make a battery of unit tests. Each one should check, at least, that the size of the collection returned by permute(n) has n! elements:
1->1
2->2
3->6
4->24
Related
[Interview Question] I got this question in a recent online interview. I had no clue how to solve it. Can anyone please help me solve this so that I can learn in Java.
Tom is very good in problem-solving. So to test Tom's skills, Jerry asks Tom a graph problem. Jerry gives Tom, an array A of N integers.
A graph is a simple graph, iff it has no self-loop or multi-edges.
Now Jerry asks Tom whether he can design a simple graph of N vertices or not. The condition is that Tom has to use each and every element of A exactly once for the degrees of vertices of the graph.
Now, Tom wants your help to design his graph. Print "YES" if the graph can be designed, otherwise print "NO" (without quotes).
Input
A single integer T, in the first line, denoting the number of test cases.
For each test case, there are 2 lines.
The first line is a single integer N, denoting the number of elements of array A.
The second line has N-space separated integers, representing elements of A.
Output
For each test case, print "YES" or "NO" (without quotes) whether the graph can be designed or not, in a new line.
Constraints
1<= T <= 100
1<= N <= 100
0<= Element of A <= 5000
Sample Test Cases
Input
1
2
1 1
Output
YES
Explanation
For this test case, a simple graph with 2 vertices can be designed, where each vertex has degree 1.
Input
2
3
1 2 1
3
1 1 1
Output
YES
NO
Explanation
For the first test case, we can design a simple graph of 3 vertices, which has degree sequence as [1, 2, 1]. The first vertex has degree 1, second, has 2 and third has 1.
For the second test case, we cannot make a simple graph of 3 vertices, which has degree sequence as [1, 1, 1].
One necessery condition is that sum of elements in A is even. That is due each edge
is counted twice in adjencency list.
Next is to try to construct graph, or at least 'allocate' pairs of nodes.
Sort elements of A in decending order,
Let the largest (first) element be a,
Check are element on positions 2 to a+1 larger than 0,
If there is a element with value 0 than it is not possible to construct a graph,
Decrease these a elements by 1 and set first element to 0,
Repeat process until all elements are 0.
Note that sorting in subsequent steps can be done in O(n) with merge sort step, since list consists
of three sorted parts:
first element (0) which can go to the end,
sorted part with a elements,
rest which is also sorted.
This question already has answers here:
What distribution do you get from this broken random shuffle?
(10 answers)
Closed 7 years ago.
So, I'm watching Robert Sedgewick's videos on Coursera and I am currently at the Shuffling one. He's showing a "poorly written" shuffling code for online poker (it has a few other bugs, which I've removed because they are not related to my question) This is how the algorithm works:
for(int i = 0; i < N; i++)
int r = new Random().nextInt(53);
swap(cardArray, i, r);
It iterates all the cards once. At each iteration a random number is generated and the i-th card is swapped with the r-th card. Simple, right?
While I understand the algorithm, I didn't understand his probability calculation. He said that because Random uses a 32-bit seed (or 64, it doesn't seem to matter), this is constrained to only 2^32 different permutations.
He also said that Knuth's algorithm is better (same for loop, but choose a number between 1 and i) because it gives you N! permutations.
I can agree with Knuth's algorithm calculations. But I think that on the first one (which is supposed to be the faulty one) there should be N^N different permutations.
Is Sedgewick wrong or am I missing a fact?
Sedgewick's way of explaining it seems very strange and obtuse to me.
Imagine you had a deck of only 3 cards and applied the algorithm shown.
After the first card was swapped there would be 3 possible outcomes. After the second, 9. And after the 3rd swap, 27. Thus, we know that using the swapping algorithm we will have 27 different possible outcomes, some of which will be duplicate outcomes to the others.
Now, we know for a fact that there are 3 * 2 * 1 = 6 possible arrangements of a 3-card deck. However, 27 is NOT divisible by 6. Therefore, we know for a fact that some arrangements will be more common than others, even without computing what they are. Therefore, the swapping algorithm will not result in an equal probability among the 6 possibilities, i.e., it will be biased towards certain arrangements.
The same exact logic extends to the case of 52 cards.
We can investigate which arrangements are preferred by looking at the distribution of outcomes in the three-card case, which are:
1 2 3 5 occurrences
1 3 2 5 occurrences
2 1 3 4 occurrences
2 3 1 4 occurrences
3 1 2 4 occurrences
3 2 1 5 occurrences
Total 27
Examining these, we notice that combinations which require 0 or 1 swaps have more occurrences than combinations that require 2 swaps. In general, the fewer the number of swaps required for the combination, the more likely it is.
Since the sequence of numbers generated by a random number generator is uniquely determined by the seed, the argument is right - but it applies to Knuth's algorithm as well, and to any other shuffling algorithm: If N! > 2^M (where N is the number of cards and M is the number of bits in the seed), some permutations will never be generated. But even if the seed is big enough, the actual difference between the algorithms lies in the probability distribution: the first algorithm does not produce an uniform probability for the different permutations, while Knuth's does (assuming that the random generator is "random" enough). Note that Knuth's algorithm is also called the Fisher-Yates shuffle.
Sedgwick is right, of course. To get a true random order of cards, you must first use an algorithm that selects equally among the N! possible permutations, which means one that selects one of N, one of N-1, one of N-2, etc., and produces a different result for each combination, such as the Fisher-Yates algorithm.
Secondly, it is necessary to have a PRNG with an internal state of greater than log2(N!) bits, or else it will repeat itself before reaching all combinations. For 52 cards, that's 226 bits. 32 isn't even close.
I'm sorry, but I have to disagree with the answers of Aasmund and Lee Daniel. Every permutation of N elements can be expressed as 3(N - 1) transpositions between 1 and some index i between 1 and N (which is easy to prove by induction on N - see below) Therefore, in order to generate a random permutation it is enough to generate 3(N-1) random integers between 1 and N. In other words, you random generator only needs to be able to generate 3(N-1) different integers.
Theorem
Every permutation of {1, ..., N} can be expressed as the composition of N-1 transpositions
Proof (by induction on N)
CASE N = 1.
The only permutation of {1} is (1) which can be written as the composition of 0 transpositions (the composition of 0 elements is the identity)
CASE N = 2. (Only for who wasn't convinced by the case N = 1 above)
There are two permutations of 2 elements (1,2) and (2,1). Permutation (1,2) is the transposition of 1 with 1. Permutation (2,1) is the transposition of 1 and 2.
INDUCTION N -> Case N + 1.
Take any permutation s of {1, ..., N, N+1}. If s doesn't move N+1, then s is actually a permutation of {1, ..., N} and can be written as the composition of N-1 transpositions between indexes i,j with 1<=i,j<=N.
So let's assume that s moves N+1 to K. Let t the transposition between N+1 and K. Then ts doesn't move N+1 (N+1 -> K -> N+1) and therefore ts can be written as the composition of N-2 transpositions, i.e.,
ts = t1..tN-1.
Hence, s = t1..tN-1t
which consists of N transpositions (one less than N+1).
Corollary
Every permutation of {1, ..., N} can be written as the composition of (at most) 3(N-1) permutations between 1 and i, where 1<=i<=N.
Proof
In view of the Theorem it is enough to show that any transposition between two indexes i and j can be written as the composition of 3 transpositions between 1 and some index. But
swap(i,j) = swap(1,i)swap(1,j)swap(1,i)
where the concatenation of swaps is the composition of these transpositions.
Had a question regarding generating a list of 10-digit phone numbers on a PhonePad, given a set of possible moves and a starting number.
The PhonePad:
1 2 3
4 5 6
7 8 9
* 0 #
Possible moves:
The same number of moves a Queen in chess can make (so north, south, east, west, north-east, north-west, south-east, south-west... n-spaces per each orientation)
Starting number: 5
So far I have implemented the PhonePad as a 2-dimensional char array, implemented the possible moves a Queen can make in a HashMap (using offsets of x and y), and I can make the Queen move one square using one of the possible moves.
My next step is to figure out an algorithm that would give me all 10-digit permutations (phone numbers), using the possible moves in my HasMap. Repetition of a number is allowed. * and # are not allowed in the list of phone numbers returned.
I would imagine starting out with
- 5555555555, 5555555551, 5555555552... and so on up to 0,
- 5555555515, 5555555155, 5555551555.. 5155555555.. and with the numbers 2 upto 0
- 5555555151, 5555551515, 5555515155.. 5151555555.. and with numbers 2 upto 0
... and so on for a two digit combination
Any suggestions on a systematic approach generating 10-digit combinations? Even a pseudocode algorithm is appreciated! Let me know if further clarification is required.
Thanks in advance! :)
In more detail, the simplest approach would be a recursive method, roughly like:
It accepts a prefix string initially empty, a current digit (initially '5'), and a number of digits to generate (initially 10).
If the number of digits is 1, it will simply output the prefix concatenated with the current digit.
If the number of digits is greater than 1, then it will make a list of all possible next digits and call itself recursively with (prefix + (current digit), next digit, (number of digits)-1 ) as the arguments.
Other approaches, and refinements to this one, are possible of course. The "output" action could be writing to a file, adding to a field in the current class or object, or adding to a local variable collection (List or Set) that will be returned as a result. In that last case, the (ndigits>1) logic would have to combine results from multiple recursive calls to get a single return value.
I want to write a simple recursive function for a game plan in java.
I have 2^k teams and want an output like this (e.g. 4 teams):
(team)(day1)(day2)(day3)
1 2 3 4
2 1 4 3
3 4 1 2
4 3 2 1
My idea was to call the function recursive with half of its original size, but I can't figure out how to code it properly. If called with n/2, the output has to go into the upper left corner of the plan, the output PLUS n/2 has to go to the lower left corner and the rest is symmetric to the center.
Thanks
My code so far
public void plan(int size) {
if(size==2){}
else{}
}
make a Set for each day (unique)
then use n(max number)
itterate a loop n times and each itteration
newRandomNumber % n (fetch a random number a limit it to 0 to (n-1)
now add the (generatedValue+1) to the set
if it already exists (do check ) then increment the value till its new value then add to set
note: i dont get ur symetric requirement
I have to write a quicksort algorithm that uses the median of the array as the pivot. From my general understanding from what I read in a book, I have to use a select algorithm in which I split the array into n/5 sub arrays, sort each of the sub arrays using insertion sort, find the median, then recursively call the select algorithm to find the median of the medians. I'm not even sure how to start this and I'm pretty confused. the selectMedian algorithm call is supposed to look something like this: SelectMedian(int first, int last, int i) where i is the ith index I want to select (in this case it would be the middle index, so array.length/2). The book I'm reading gives this description of it:
The algorithm in words (if n>1):
1. Divide n elements into groups of 5
2. Find median of each group (use insertion sort for this)
3. Use Select() recursively to find median x of the n/5
medians
4. Partition the n elements around x. Let k = rank(x)
5. if (i == k) then return x
if (i < k) then use Select() recursively to find i-th
smallest element in first partition else (i > k) use
Select() recursively to find (i-k)th smallest element in
last partition.
can anyone assist me in writing this algorithm? thanks!
Would that really be necessary? Why not use the median of three where you select the pivot based on the median of three values, ie. the first, middle and last values.
Or you could even use a random pivot, which will drastically lower the chances of ending up with QuickSort's worst case time of O(N²), which may also be appropriate for your implementation.
I assume you can figure out created n/5 sub-arrays of 5 elements each.
Finding the median of a subarray is fairly easy: you look at each element and find the element which has two smaller elements.
For example, you have 1 4 2 3 5. 1 has no smaller elements. 4 has three smaller elements. 2 has one smaller element. 3 has two smaller elements; this is the one you want.
Now you have found n/5 medians. You want to find the median of the medians, so you run the algorithm again.
Example:
1 7 2 4 9 0 3 8 5 6 1 4 7 2 3
[1 7 2 4 9][0 3 8 5 6][1 4 7 2 3]
findMedian([1 7 2 4 9]) = 4;
findMedian([0 3 8 5 6]) = 5;
findMedian([1 4 7 2 3]) = 3;
[4 5 3]
findMedian([4 5 3]) = 4;
4 is your pivot.
The reason you do this is to try and split your array evenly; if your array is split lopsided, you'll get O(N^2) performance; if your array is split evenly, you get O(NlogN) performance.
Selecting a random pivot means you could get either one - in practice it would balance out to O(NlogN) but a lot of applications want consistent performance, and random quicksort is not consistent from run to run.
The reason we use 5 (instead of 3 or 7) is because we're adding another term of time complexity searching for the median - this term has to be less than O(NlogN) but you want it to be as small as possible. Using 3 gets you O(N^2), using 5 gets you O(NlogN), and 5 is the smallest number for which this is true.
(the algorithm to find the median in linear time was given by Blum, Floyd, Pratt, Rivest and Tarjan in their 1973 paper "Time bounds for selection", and answered a famous open problem)
QUICKSORT2(A, p, r)
if p<r
median=floor((p + r) /2) - p + 1
q=SELECT(A, p, r, median)
q=PARTITION2(A, p, r, q)
QUICKSORT2(A, p, q-1)
QUICKSORT2(A, q+1, r)
PARTITION2(A, p, r, q)
switch between A[r] and A[q]
return PARTITION(A, p, r)