We often use the number of the binary system as "constant", that is, always the P into 1. For example, the P-decimal number k can be expressed as
K = a0*p^0 + a1*p^1 + a2*p^2 + ... + an*p^n (where 0 <= ai <= p-1),
It can represent any one natural number.
For this constant-input notation, and the conversion between the various conversions, you should be very familiar with it, but you may rarely hear about the number of changes in the system. Here I want to introduce a special kind of variable number, it can be used to achieve the full array of hash function, and the hash function can achieve perfect collision prevention and space utilization (no collision, and all the space is fully used, not many more). This full-array hash function is also known as the full-permutation counting technique. Now let's take a look at the number of changes in the system.
We examine such a variable number: 1th every 2 into 1, 2nd every 3 into 1, ..., the nth bit every n+1 into 1. It is represented in the form of
K = a1*1! + a2*2! + a3*3! + ... + an*n! (where 0 <= ai <= i),
It can also be extended to the following form (because A0 is always 0 by definition), as opposed to the P-binary representation:
K = a0*0! + a1*1! + a2*2! + a3*3! + ... + an*n! (where 0 <= ai <= i).
(The subsequent variable numbers refer to this variable number, and the previous notation is used)
Let us first examine whether the rounding of this variable is correct. It is assumed that the first bit AI of the variable number k is i+1, need carry, and ai*i!= (i+1) *i!=1* (i+1)!, that is, the right to the high position into 1. This indicates that the variable can carry correctly, and thus is a legitimate way of counting.
Next we examine the properties of n-bit variable K:
(1) When all bit AI is I, this time K has the maximum value
Max[k] = 1*1! + 2*2! + 3*3! + ... + n*n!
= 1! + 1*1! + 2*2! + 3*3! + ... + n*n! -1
= (+) *1! + 2*2! + 3*3! + ... + n*n! -1
= 2! + 2*2! + 3*3! + ... + n*n! -1
= ...
= (n+1)!-1
Therefore, the maximum value of the N-bit K-binary number is (n+1)!-1.
(2) When all bit AI is 0 o'clock, this time K has a minimum value of 0.
Therefore, the n-bit variable can represent all the natural numbers in the range of 0 to (n+1)!-1, Total (n+1)! one.
In some state-space search algorithms, we need to quickly determine whether a state has appeared, which is often done using the hash function. Among them, there is a kind of special state space, they are produced by the whole arrangement, such as n digital problem. For the full arrangement of n elements, a total of n! different permutations or states are produced. The following is a discussion of how to use the variable number here to implement a hash function for the full array.
From the point of view of the numbers, both the full and the variable numbers are used for factorial. If we can represent all the permutations of n elements with 0 to n!-1, which n! a continuous number of binary numbers, then we can completely count the entire arrangement, establish a relationship between the total and the natural number one by one, and implement a perfect hash function. So, can our ideas be fulfilled? The answer is yes, the following will be discussed.
Suppose we have b0,b1,b2,b3,..., bn n+1 a different element and assume that there is an order relationship b0<b1<b2<...<bn between the elements. They are all arranged in a total of (n+1)! different permutations. For any of the resulting permutations C0,c1,c2,.., cn, where the I element ci (1 <= i <= N) and the I element in front of it constitute the number of reverse pairs of di (0 <= di <= i), then we get a sequence of reverse order d1,d2,..., DN (0 <= di <= i). This is not the individual bits of the previous n-bit variable number. So, we use n bits to change the number of M to represent this arrangement:
M = d1*1! + d2*2! + ... + dn*n!
Therefore, each permutation can be represented as an n-bit variable in this way. Next, we will examine whether n-bit variable numbers can be set up with the n+1 of the full array of elements one by one corresponding relationship.
Because n-bits can be represented (N+1)! A different number, and the n+1 element has exactly the same arrangement (N+1)! A different arrangement, and each permutation can already be represented as an n-bit variable number. If we can prove that any two different permutations produce two different variable numbers, then we can conclude that:
★ Theorem 1 Each permutation of the n+1 elements corresponds to a different n-bit variable number.
/* Supplement: What is the reverse order number:
The sum of the opposite ordinal of the standard column
For example
The standard column is 1 2 3 4 5
Then the inverse number algorithm for 5 4 3 2 1:
Look at the second, before 4 there is a 5, in the standard column 5 in the back of 4, so remember a
Similarly, the third 3 before 4 5 is in the standard column after 3, so remember 2
Similarly, there were 3 before 2, 1 before 4
Adding these numbers together is an inverse number =1+2+3+4=10
One more 2 4 3 1 5
4 ago there were 0
3 ago there were 1
1 ago there were 3
5 ago there were 0
So the reverse number is 1+3=4.
*/
For any of the two different permutations of the P0,P1,P2,..., pn (permutation p) and q0,q1,q2,..., qn (permutation q), look forward to the first distinct element, recorded as Pi and Qi (0 < i <= N).
(1) If Qi > pi, then,
If the element x before qi in the permutation Q has an inverse pair of Qi (x > Qi), then there is the same element x > pi (because x > Qi and qi > pi) before the Pi in the arrangement p, that is, the element x before pi in the permutation p is also in reverse order with PI, So the inverse number of pi is greater than or equal to QI in reverse order. Qi and pi in the permutation P form pi in reverse order, so the reverse number of pi is greater than the number of Qi reverse.
(2) Similarly, if pi > qi, then the reverse number of Qi is greater than the reverse number of pi.
Therefore, by (1) and (2), the permutation p and the permutation Q correspond to at least the number of the first I-bit different, that is, any of the two different permutations of the whole arrangement has a distinct number of variations. So far, theorem 1 is proof.
The algorithm for calculating a permutation of n elements is roughly the following (the time complexity is O (n^2)):
Template <typename t>
size_t permutationtonumber (const T permutation[], int n)
{
n cannot be too large, otherwise it will overflow (if size_t is 32 bits, then n <= 12)
size_t result = 0;
for (int j = 1; j < n; ++j) {
int count = 0;
for (int k = 0; k < J; ++k) {
if (Permutation[k] > Permutation[j])
++count;
}
FACTORIALS[J] Save the j!
Result + = count * Factorials[j];
}
return result;
}
Summarize:
In fact, if only the number of reverse order can be done O (n logn), the time spent on the reverse number, the number of reverse is equivalent to the number of permutations, so is O (n logn)
It is also said that tree-like arrays can be used for optimization.
Example:
For example, an arrangement of three elements
Arrange reverse order Hash
123 000 0
132 001 2
213 010 1
231 002 4
312 011 3
321 012 5
Description
(1) Since n! is a large number, it is generally only used for smaller n.
(2) with the algorithm of calculating the number of permutations, we can use an array of size n! to hold each permutation state, using the permutation number as the array subscript, thus realizing the fast retrieval of the state. If only the token state appears, you can use one to mark the state.