除了两个以外的其他基础是否存在格雷码?

时间:2010-10-01 09:39:44

标签: math gray-code

只是好奇心问题,是否为基数为2的基数定义了Gray code

我试图计入基数3,编写连续值,注意一次只更改一个 trit 。我已经能够枚举最多26(3 ** 3-1)的所有值,它似乎有效。

        000              122              200
        001              121              201
        002              120              202
        012              110              212
        011              111              211
        010              112              210
        020              102              220
        021              101              221
        022              100              222

我能看到的唯一问题是,当循环回零时,所有三个 trits 都会发生变化。但这只适用于奇数基数。当使用偶数基数循环回零时,只会改变一个数字,如二进制数字。

我甚至猜测它可以扩展到其他基数,甚至十进制。这可能导致在十点基数计数时的另一个排序......: - )

    0  1  2  3  4  5  6  7  8  9 19 18 17 16 15 14 13 12 11 10
   20 21 22 23 24 25 26 27 28 29 39 38 37 36 35 34 33 32 31 30

现在问题是,有没有人听说过它?有申请吗?或者只是数学狂热?

2 个答案:

答案 0 :(得分:10)

是。看看维基百科上的Gray code article。它有n-ary Gray Code部分。

  

除了二进制反射格雷码之外,还有许多特殊类型的格雷码。一种这样的格雷码是 n-ary格雷码,也称为非布尔格雷码。顾名思义,这种格雷码在其编码中使用非布尔值。

答案 1 :(得分:3)

为了完整性(因为aioobe已经给出了正确的答案),这里是一个C ++程序,它列出了以00开头的所有168个2位灰色代码,标记了96个循环代码。使用algorithm from Wikipedia,您可以轻松构建更长的格雷码,以获得均匀的基数。对于不均匀的基础,您可以根据格雷码更改程序。

这个程序找到的第一个循环2位格雷码是这个:

00 01 02 12 10 11 21 22 20

更改程序后,找到的第一个循环3位灰色为:

000 001 002 012 010 011 021 020 022 122 102 100 101 111
110 112 212 202 222 220 120 121 221 201 211 210 200

代码:

#include <stdio.h>
#include <stdlib.h>

// Highest number using two trits
#define MAXN 9

int gray_code_count, cyclic_count;

bool changes_one_trit(int code1, int code2) {
  int trits_changed = 0;
  if ((code1 / 3) != (code2 / 3)) trits_changed++;
  if ((code1 % 3) != (code2 % 3)) trits_changed++;
  return (trits_changed == 1);
}

int generate_gray_code(int* code, int depth) {
  bool already_used;

  if (depth == MAXN) {
    for (int i = 0; i < MAXN; i++) {
      printf("%i%i ", code[i]/3, code[i]%3);
    }
    // check if cyclic
    if (changes_one_trit(code[MAXN-1], 0)) {
      printf("cyclic");
      cyclic_count++;
    }
    printf("\n");
    gray_code_count++;    
  }

  // Iterate through the codes that only change one trit
  for (int i = 0; i < MAXN; i++) {
    // Check if it was used already
    already_used = false;
    for (int j = 0; j < depth; j++) {
      if (code[j] == i) already_used = true;
    }
    if (already_used) continue;

    if (changes_one_trit(code[depth-1], i)) {
      code[depth] = i;
      generate_gray_code(code, depth + 1);
    }
  }
}

int main() {
  int* code = (int*)malloc(MAXN * sizeof(int));
  code[0] = 0;
  gray_code_count = 0;
  generate_gray_code(code, 1);
  printf("%i gray codes found, %i of them are cyclic\n", gray_code_count, cyclic_count);
  free(code);
}