Algorithm guidance with 3n+1 Conjecture

霸气de小男生 提交于 2019-12-12 19:17:43

问题


Okay, I know this is going to sound like homework; but here goes any way. I am trying to solve this problem using C#. The excerpt from the problem description is shown below:

Given an input n, it is possible to determine the number of numbers printed (including the 1). For a given n this is called the cycle-length of n. In the example above, the cycle length of 22 is 16. For any two numbers i and j you are to determine the maximum cycle length over all numbers between i and j.

Question

I understand everything except for one thing, the cycle length. I just don't understand it exactly. I find that the text is ambiguous about the definition of it. I assume, that the cycle length is how many numbers were in the sequence so lets say that the input is 10 the cycle length would be 8. But I am just not exactly sure. No code is required on your part but guidance is all I ask.

In addition, I already know how to read from standard input and output. Since the problem is in programming competition format.

My implementation of displaying the sequence of numbers giving n as input

static void collatz(ref int n)
{    
     if (n % 2 == 0)
     {
          n /= 2;
     }
     else
     {
          n = (3 * n) + 1;
     }
     Console.WriteLine(n);
}

static int GetCycleLength(int n)
{
     if (n > 0)
     {
          int count = 1;
          while (n != 1)
          {
               collatz(ref n);
               count++;
          }
          return count;
     }
     else
     {
          return -1;
     }
}

Notes

Although it is not homework, I want to treat as homework, so I put as one of the tags.


回答1:


You should use dynamic programming. That is say, if you work for a number j and while working for j if you encounter k. Then you should not again repeat whole work for k again.

So start from j and go down to i. Suppose you are finding cycle length for a number n. While finding cycle length for n, suppose you encounter numbers: n, n8, n7, n6, ..., n1. Then you cycle length for n is 9 and for n8 is 8 and for n7 is 7. Store cycle length for all such numbers in an array or map. And reuse them everywhere possible when you encounter same numbers for finding cycle length for any different number. This would give you an optimal solution for this problem.

See an example use of dynamic programming at http://en.wikipedia.org/wiki/Dynamic_programming#Fibonacci_sequence




回答2:


The cycle length is the number of times that the algorithm must be applied to the original natural number/integer in order to get to 1, eventually.

Example, if you start with 7:

  1. 7 is odd so we use the algorithm 3(7) + 1 = 22
  2. 22 is even so we use 22/2 = 11
  3. 11 is odd so we use the algorithm 3(11) + 1 = 34
  4. 34 is even so we use the algorithm 34/2 = 17
  5. 17 is odd so we use the algorithm 3(17) + 1 = 52
  6. 52 is even so we use the algorithm 52/2 = 26
  7. 26 is even so we use the algorithm 26/2 = 13
  8. 13 is odd so we use the algorithm 13(3) + 1 = 40
  9. 40 is even so we use the algorithm 40/2 = 20
  10. 20 is even so we use the algorithm 20/2 = 10
  11. 10 is even so we use the algorithm 10/2 = 5
  12. 5 is odd so we use the algorithm 5(3) + 1 = 16
  13. 16 is even so we use the algorithm 16/2 = 8
  14. 8 is even so we use the algorithm 8/2 = 4
  15. 4 is even so we use the algorithm 4/2 = 2
  16. 2 is even so we use the algorithm 2/2 = 1

We have applied the algorithm 16 times to the number 7 and we got to 1. So, 16 is the cycle length.

Code Performance Tip - Instead of multiplying and dividing in your collatz(ref int n) you could use bitwise operations. That would give the performance a serious boost.




回答3:


For a specific starting value (n), the cycle length is simply how many numbers it takes to reach 1 (including the 1 at the end). For 10:

10 5 16 8 4 2 1

So the cycle length is 7.

Hence, for this problem you'll have to loop from i to j, determine the cycle length for each integer you iterate over, and return the maximum cycle length you encounter. You might want to check out dynamic programming as mentioned by another answer (i.e. storing previously computed cycle lengths and then utilizing these stored values in future computations).




回答4:


The text referred to is not ambiguous about the definition of cycle-length; it says: “Given an input n, it is possible to determine the number of numbers printed ... For a given n this is called the cycle-length of n”. For example, given the input 20, the reference procedure prints out 20 10 5 16 8 4 2 1, so the “cycle-length of 20” is 8. Your program, in a sense, emulates the reference procedure for a range of values of n, finding and printing the maximum cycle-length encountered.

Note, the suggestion to use dynamic programming may be slightly misleading. What you can actually use is memoization, ie, recording all or some of the results for previously processed inputs. It is cumbersome to record results so if your program is fast enough without memoization, then don't bother with it. The problem says to assume “no operation overflows a 32-bit integer”. If you make no further assumptions and record all intermediate results you need a dictionary data structure capable of handling billions of different values. If you make assumptions about maximum cycle lengths your program may fail. Anyhow, one approach is to choose some large number K and allocate an array M of integers; initialize the array to all zeroes, except M[1] = 1. In your Collatz routine, each time you do step 4 (ie n ← 3n+1) push a 1 into a stack of bits. (Number of bits in the stack should be not less than maximum cycle length.) Each time you do step 5 (ie n ← n/2) push a 0 into the stack.

If you find M[n] > 0 at any step, then you know you have already computed the cycle length of n to be c = L = M[n]. At that point, you can unwind the bit-stack and return L. In the unwind, after each pop, compute n (as n = 2*n if you pop a 0, or n = (n-1)/3 if you pop a 1), do ++c, and if n<K set M[n] = c.



来源:https://stackoverflow.com/questions/12360625/algorithm-guidance-with-3n1-conjecture

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!