Permutation and combination algorithm 1: generate all Sequences

Source: Internet
Author: User
Tags new set

Generation length:NAll with Sequences(N-tuples)

Chat with friends in the QQ group (well, I am still using QQ and despise me as much as possible. When does MSN support arbitrary addition of emotices and textures like QQ, instead of compressing the emoticon I added completely beyond my imagination? It is not too late for me to give up QQ. You can't even use "worship you without reservation", MSN my ass. QQ expression: after adding the same image to MSN :. What's the world !), One of the common topics is how to generate all the combinations with sequences, all subsets of a set (idempotence), or all of them in full order. Similar problems often occur in some forums. Interesting topic. It is also a good exercise material for training the brain to prevent Alzheimer's disease from time to time during programming. It is especially suitable for programmers who sit in the gym, enjoy the oil bar, and never go to the gym at the age of 30. You don't have to read it. You are the boss! There is another benefit to doing this kind of questions: Review the joy of writing small programs. I don't know how many people will enjoy the whole process of building a wage management system. I am very interested in debugging strange APIs and repeatedly modifying complicated xml configuration files. I won't. Writing a small program is different. There is no deadline for pressure, no worries about the system, no worries about the program architecture. It can tangle every detail of the algorithm, or Persistently improve the performance of every part of the code. The master is happy. The mind is clear, eyes are transparent, and the mind is moving at will. When you break down the characters, the problem becomes serious. Layer-by-layer barrier is broken with code extension. The process of writing a mini-program to solve the problem is as if a child is ignorant of the game, purely for fun. An afternoon passes. They are full of mud and exhausted. But they are still excited and still look forward to the next game. Well, this year, we will not accept gifts, but only wisdom questions. Today, I am beginning to be guilty again. However, adhering to the principles of drag and drop, we should simply talk about common algorithms for such problems. If you know how to generate an algorithm with all sequences, you will know how to generate a power set. The two have an intuitive ing relationship. A new set of algorithms is used to generate a full arrangement. It is easier to generate all sequences, so use it to open your stomach. Of course, I have written a detailed guide to this kind of problem, and I am just a cheap Porter. Fortunately, I can comfort myself with the words of Daniel himself: whenever I find any interesting question, I can easily Google it. Unfortunately, I find that some smart people have already answered the question. An N-tuple is a sequence containing n elements, which is generally written. For example, it is a 6-tuple. Note the differences between tuple and set. Tuple can contain repeated elements. In addition, the tuple elements are ordered, just like the elements in the array. So how can we generate all sequences given an N-tuple? There is always no difference in learning from simplicity to complexity. Therefore, we start with a simple binary N-element sequence (Binary N-tuple): Each element of the binary N-element sequence is a bit, and a non-0 is 1. For example, a binary 3-tuple generates all ordered columns (0, 0, 0) (0, 0, 1) (0, 1, 0) (0, 1, 1) (1, 0, 0) (1, 0, 1) (1, 1, 1) a total of 8. Although the binary N-element sequence is simple, it has been widely used. For example, if we know how to generate a binary N-yuan sequence, we also know how to generate an idempotent set: an N-yuan set, which is defined as a subset, if and only when the corresponding binary N element has a sequence element. The above 3-tuple is used as an example. Given a set, more applications will be discussed below. The conclusions drawn from the discussion of the sequence of binary n elements lay the foundation for us to explore how to generate more complex composite styles in the future. The method to generate all binary n elements with sequences is simple, but we start from the binary number and add one after another until we get it. Using carry addition, we just traverse all N-tuples. Simple, but wonderful. The code is implemented in ruby. Because Ruby code is not much different from pseudocode, will it be understandable to the boss of Ruby. Besides, algorithms are algorithms. It doesn't matter the language. It is boring not to find XXX language algorithm when learning algorithms. The outer loop is responsible for adding 1 one by one, while the inner loop is responsible for carrying. If all bits are 1, all loops are exceeded because the addition is not allowed.
def binary_all_tuples(tuple_length)
  tuple =
 Array.new(tuple_length, 0)
    
  loop do
    puts tuple.inspect 

    j = tuple_length - 1

    while tuple[j] == 1 do
      tuple[j] =
 0
      j -= 1

    end    

    
return if j == -1
    tuple[j] += 1
  end
end
 
We know that the loop has been performed for a total of times. Therefore, we do not need to judge the J value every time. However, this is the details.
def binary_all_tuples_2(tuple_length)
  tuple = Array.new(tuple_length, 0)
 1.upto(1<<tuple_length) do |i|
    puts tuple.inspect   
    j = tuple_length -
1
    while tuple[j] == 1 do
      tuple[j] =
0
      j -=
1
    end   
    tuple[j] += 1    
  end
end 
With this algorithm, it is easy to generate all subsets of a set:
def each_tuple(tuple_length=0, &proc)
  tuple = Array.new(tuple_length, 0)  
  loop do
    yield tuple   
    j = tuple_length - 1
   while tuple[j] == 1
do
      tuple[j] =
0
      j -=
1
    end   
    return if j == -1
    tuple[j] += 1
end
end
require ’set’
def powerset(
set = [])
 each_tuple(
set.size) do |tuple|
    puts “tuple: #{tuple.inspect}”   
    subset = []
   tuple.each_index do |index|
      subset << set[index] if tuple[index] ==
1
    end   
    puts subset.inspect
  end
end
The first function each_tuple () is basically the same as the first binary_all_tuples. The only difference is that each_tuple () does not print every tuple. Instead, each tuple obtained by yield is processed by the attaching process & Proc. The second function powerset () only needs to find the coordinate index corresponding to an element in each tuple, and then collect the corresponding set [Index. Such a simple algorithm also has a wonderful extension. For example, we can extend the binary value to a decimal number. N-tuple in decimal format: In ,. So we only need to add them gradually. We can further summarize and process the multi-hexadecimal sequence. That is to say, The hexadecimal order of any element in the n-element sequence is expressed as follows: different elements are not necessarily the same. Essentially, the method for generating the full sequence has not changed. Now we only need to accumulate the number of mixed hexadecimal. The number of mixed hexadecimal values can be written as follows: the accumulative algorithm is still intuitive: for the mixed hexadecimal sequence that meets the condition (1), we continue to formula (2) add 1 to the number in. There is no essential difference between the carry rule and the previously unified carry rule. In the first place, add to carry again.
def all_tuples(radix_list = [])
  tuple_length = radix_list.size
  tuple = Array.new(tuple_length, 0)   
  loop do
    puts tuple.inspect   
    j = tuple_length - 1
    while tuple[j] == radix_list[j] -1
do
      tuple[j] =
0
      j -=
1
    end



    return if j == -1
    tuple[j] += 1
  end
end
Surprisingly, Master Gao suggested that when the number of embedded loops is small, it would be easier to write them into N-layer nested loops. It actually makes sense. The nested loop of handwriting saves the time for conception and troubleshooting, and the code is more intuitive. At the beginning, a few of our friends worked on the operating system together. When I was still there to figure out how to write a complex loop into a simple and universal way, a quickshooter in the same group had already completed debugging. He writes nested loops and judgments first, and then reconstructs them later. The preceding algorithms generate all sequences in alphabetical or arithmetic order. Sometimes, we need to generate sequences in other order. The most famous is the so-called gray code, that is, in the generated sequence, any adjacent two sequences only have one difference. For example, the order of Gray code generation for Binary ternary sequences is: (0, 0, 0) (0, 0, 1) (0, 1, 1) (0, 1, 0) (1, 1, 0) (1, 1, 1) (1, 0, 1) (1, 0, 0) is obvious, we can use a sequence to generate different Gray Codes. The following is another set of Gray Codes: (0, 0, 0) (1, 0, 0) (1, 0, 1) (0, 0, 1) (0, 1, 1) (0, 1, 0) (1, 1, 0) (1, 1, 1) Gray code is widely used. From analog signals to genetic algorithms to discrete mathematics to the solution of nine links, There is a shadow of it. If you are interested, go to Google or Baidu. After the discussion, we can see the relationship between the solution of the 9-series and the gray code, as well as the efficient algorithm derived from the solution. There are many Equivalent Gray code definitions. From a simple start, we can see that the expression in formula (3) represents an empty string, indicating that a 0 is added before each string in the sequence to form a new sequence, in contrast, it indicates that the sequence is flipped, and each field in the string is prefixed with one to form a new sequence. Let's look at the first n = 3: n = 0. We get the null sequence n = 1, so we get the unique Gray code: 0, 1N = 2, = 0 (0, 1), 1 (1, 0) = 00, 01, 11, 10n = 3, = 0 (00, 01, 11), 1 (11, 01, 00) = 000,001,011,111,101,000 intuitively understands that all sequences are built from scratch. So it is consistent with all strings in the gray code definition-the adjacent strings differ by one character. The last string is exactly the same as the first string. Therefore, after 0 and 1 are added respectively, the last string is exactly the same as the other one. With an intuitive concept, induction proves that it is almost trivial (the original formula is used to express our intuitive ideas ). The preceding example can be considered as an initial condition. If it is a gray code, do you need to write the following steps? Because Formula (3) is a recursive definition, we can directly convert it into code:
def gray_rec(n)
  return [] if n ==
0
  return [“0″,“1″] if n ==
1
  partial = gray_rec(n-1)     
  return partial.collect{ |e| “0″+e} + partial.reverse.collect{|e|“1″+e}
end
The addition of return ["0", "1"] If n = 1 is purely to save the subsequent judgment on the empty set. Most of those familiar with the lisp series cannot use tail-recursion-optimized code, so let's make a small change. Ruby has no tail-recursion optimization, so the following code should have no substantial improvements.
def gray_rec_helper(count, max, partial_result)
  return [] if max ==
0
  return partial_result if count == max
 
  return gray_rec_helper(count+1,
        max,
partial_result.collect{ |e| “0″+e}+ partial_result.reverse.collect{ |e| “1″+
e})
end
 
def tail_gray(n)
  return gray_rec_helper(1, n, [“0″,“1″]
)
end
This generation method is not economical. We will later export faster algorithms through 9-series pushing. Then gradually improve the algorithm to obtain a high-speed algorithm that does not require inner loops. 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.