Цикл де Брёйна, трабл с вызовом рекурсии - C#

Узнай цену своей работы

Формулировка задачи:

Перевожу с питона на шарп цикл Де Брейна, на английской версии лежит скрипт, который приведен ниже (слегка его подчистил до неоходимого функционала).
Листинг программы
  1. def de_bruijn(k, n):
  2. """
  3. De Bruijn sequence for alphabet k
  4. and subsequences of length n.
  5. """
  6. alphabet = list(map(str, range(k)))
  7. a = [0] * k * n
  8. sequence = []
  9. def db(t, p):
  10. if t > n:
  11. if n % p == 0:
  12. sequence.extend(a[1:p + 1])
  13. else:
  14. a[t] = a[t - p]
  15. db(t + 1, p)
  16. for j in range(a[t - p] + 1, k):
  17. a[t] = j
  18. db(t + 1, t)
  19. db(1, 1)
  20. return "".join(alphabet[i] for i in sequence)
  21. print(de_bruijn(2, 2))
Собственно в самом цикле неоднократно происходят вызовы db(x,y), а в шарпе код как будто игнорирует эту инструкцию и спокойно выполняет код дальше. При одинаковых параметрах k n = 2 2, питон выдает необходимые 0011, шарп выдает 0100, поскольку выполняет db единожды, ходя должен минимум трижды.
Листинг программы
  1. static int k=2, n=2;
  2. int[] a = new int[k * n];
  3. static List<int> sequence = new List<int>();
  4. void db(int t, int p)
  5. {
  6. if (t > p)
  7. {
  8. if (n % p==0)
  9. {
  10. for (int i = 1; i >= p + 1; i++)
  11. {
  12. sequence.Add(a[i]);
  13. }
  14. }
  15. }
  16. else
  17. {
  18. a[t] = a[t - p];
  19. db(t + 1, p);
  20. for (int j = a[t - p] + 1; j < k; j++)
  21. {
  22. a[t] = j;
  23. db(t + 1, t);
  24. }
  25. }
  26. }
  27.  
  28. private void button1_Click(object sender, EventArgs e)
  29. {
  30. db(1, 1);
  31. string s = string.Empty;
  32. for (int i = 0; i < a.Length; i++)
  33. {
  34. s += a[i];
  35. }
  36. textBox1.Text = "" + s;
  37. }
Что я делаю не так? Возможно кривой перевод программы, но питон не знаю и не разбирался до сегодняшнего дня, пытался даже вызвать из db другой метод - игнорирует.

Решение задачи: «Цикл де Брёйна, трабл с вызовом рекурсии»

textual
Листинг программы
  1. using System;
  2. using Google.OrTools.ConstraintSolver;
  3.  
  4. public class DeBruijn
  5. {
  6.  
  7.     // [url]https://github.com/google/or-tools/releases[/url]
  8.  
  9.     /**
  10.      *
  11.      *  ToNum(solver, a, num, base)
  12.      *
  13.      *  channelling between the array a and the number num.
  14.      *
  15.      */
  16.     private static Constraint ToNum(IntVar[] a, IntVar num, int bbase)
  17.     {
  18.         int len = a.Length;
  19.  
  20.         IntVar[] tmp = new IntVar[len];
  21.         for (int i = 0; i < len; i++)
  22.         {
  23.             tmp[i] = (a[i] * (int)Math.Pow(bbase, (len - i - 1))).Var();
  24.         }
  25.         return tmp.Sum() == num;
  26.     }
  27.  
  28.  
  29.  
  30.     /**
  31.      *
  32.      * Implements "arbitrary" de Bruijn sequences.
  33.      * See [url]http://www.hakank.org/or-tools/debruijn_binary.py[/url]
  34.      *
  35.      */
  36.     private static void Solve(int bbase, int n, int m)
  37.     {
  38.         Solver solver = new Solver("DeBruijn");
  39.  
  40.  
  41.         // Ensure that the number of each digit in bin_code is
  42.         // the same. Nice feature, but it can slow things down...
  43.         bool check_same_gcc = false; // true;
  44.  
  45.         //
  46.         // Decision variables
  47.         //
  48.         IntVar[] x = solver.MakeIntVarArray(m, 0, (int)Math.Pow(bbase, n) - 1, "x");
  49.         IntVar[,] binary = solver.MakeIntVarMatrix(m, n, 0, bbase - 1, "binary");
  50.  
  51.         // this is the de Bruijn sequence
  52.         IntVar[] bin_code =
  53.           solver.MakeIntVarArray(m, 0, bbase - 1, "bin_code");
  54.  
  55.         // occurences of each number in bin_code
  56.         IntVar[] gcc = solver.MakeIntVarArray(bbase, 0, m, "gcc");
  57.  
  58.         // for the branching
  59.         IntVar[] all = new IntVar[2 * m + bbase];
  60.         for (int i = 0; i < m; i++)
  61.         {
  62.             all[i] = x[i];
  63.             all[m + i] = bin_code[i];
  64.         }
  65.         for (int i = 0; i < bbase; i++)
  66.         {
  67.             all[2 * m + i] = gcc[i];
  68.         }
  69.  
  70.  
  71.         //
  72.         // Constraints
  73.         //
  74.  
  75.         solver.Add(x.AllDifferent());
  76.  
  77.         // converts x <-> binary
  78.         for (int i = 0; i < m; i++)
  79.         {
  80.             IntVar[] t = new IntVar[n];
  81.             for (int j = 0; j < n; j++)
  82.             {
  83.                 t[j] = binary[i, j];
  84.             }
  85.             solver.Add(ToNum(t, x[i], bbase));
  86.         }
  87.  
  88.         // the de Bruijn condition:
  89.         // the first elements in binary[i] is the same as the last
  90.         // elements in binary[i-1]
  91.         for (int i = 1; i < m; i++)
  92.         {
  93.             for (int j = 1; j < n; j++)
  94.             {
  95.                 solver.Add(binary[i - 1, j] == binary[i, j - 1]);
  96.             }
  97.         }
  98.  
  99.         // ... and around the corner
  100.         for (int j = 1; j < n; j++)
  101.         {
  102.             solver.Add(binary[m - 1, j] == binary[0, j - 1]);
  103.         }
  104.  
  105.         // converts binary -> bin_code (de Bruijn sequence)
  106.         for (int i = 0; i < m; i++)
  107.         {
  108.             solver.Add(bin_code[i] == binary[i, 0]);
  109.  
  110.         }
  111.  
  112.  
  113.         // extra: ensure that all the numbers in the de Bruijn sequence
  114.         // (bin_code) has the same occurrences (if check_same_gcc is True
  115.         // and mathematically possible)
  116.         solver.Add(bin_code.Distribute(gcc));
  117.         if (check_same_gcc && m % bbase == 0)
  118.         {
  119.             for (int i = 1; i < bbase; i++)
  120.             {
  121.                 solver.Add(gcc[i] == gcc[i - 1]);
  122.             }
  123.         }
  124.  
  125.         // symmetry breaking:
  126.         // the minimum value of x should be first
  127.         // solver.Add(x[0] == x.Min());
  128.  
  129.  
  130.         //
  131.         // Search
  132.         //
  133.         DecisionBuilder db = solver.MakePhase(all,
  134.                                               Solver.CHOOSE_MIN_SIZE_LOWEST_MAX,
  135.                                               Solver.ASSIGN_MIN_VALUE);
  136.  
  137.         solver.NewSearch(db);
  138.  
  139.         while (solver.NextSolution())
  140.         {
  141.             Console.Write("x: ");
  142.             for (int i = 0; i < m; i++)
  143.             {
  144.                 Console.Write(x[i].Value() + " ");
  145.             }
  146.  
  147.             Console.Write("\nde Bruijn sequence:");
  148.             for (int i = 0; i < m; i++)
  149.             {
  150.                 Console.Write(bin_code[i].Value() + " ");
  151.             }
  152.  
  153.             Console.Write("\ngcc: ");
  154.             for (int i = 0; i < bbase; i++)
  155.             {
  156.                 Console.Write(gcc[i].Value() + " ");
  157.             }
  158.             Console.WriteLine("\n");
  159.  
  160.  
  161.             // for debugging etc: show the full binary table
  162.             /*
  163.             Console.Write("binary:");
  164.             for(int i = 0; i < m; i++) {
  165.               for(int j = 0; j < n; j++) {
  166.                 Console.Write(binary[i][j].Value() + " ");
  167.               }
  168.               Console.WriteLine();
  169.             }
  170.             Console.WriteLine();
  171.             */
  172.  
  173.         }
  174.  
  175.         Console.WriteLine("\nSolutions: {0}", solver.Solutions());
  176.         Console.WriteLine("WallTime: {0}ms", solver.WallTime());
  177.         Console.WriteLine("Failures: {0}", solver.Failures());
  178.         Console.WriteLine("Branches: {0} ", solver.Branches());
  179.  
  180.         solver.EndSearch();
  181.  
  182.     }
  183.  
  184.     public static void Main(String[] args)
  185.     {
  186.         int bbase = 2;
  187.         int n = 3;
  188.         int m = 8;
  189.  
  190.         if (args.Length > 0)
  191.         {
  192.             bbase = Convert.ToInt32(args[0]);
  193.         }
  194.  
  195.         if (args.Length > 1)
  196.         {
  197.             n = Convert.ToInt32(args[1]);
  198.         }
  199.  
  200.         if (args.Length > 2)
  201.         {
  202.             m = Convert.ToInt32(args[2]);
  203.         }
  204.  
  205.         Solve(bbase, n, m);
  206.     }
  207. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

12   голосов , оценка 4 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы