为什么这种离散编码计算不正确?我错过了什么吗?
Why is this discrete encoding not calculating properly? Am i missing something?
我正在尝试将一些因子编码为离散数,然后将离散数逆向工程返回其因子 - 但是一旦我添加了足够多的因子,反向过程就不会显示正确的数字。
a = 3
b = 13
c = 7
d = 8
e = 3
f = 2
state = (((((b)*20+c)*10+d)*10+e)*5+f)*5
# If i add "a*4" to the front of the line (as shown in this line below), A and B is no longer showing correct
state = ((((((a)*4+b)*20+c)*10+d)*10+e)*5+f)*5
print(state)
print("f:", state // 5 % 5)
state = state // 5
print(state)
print("e:", state // 5 % 5)
state = state // 5
print(state)
print("d:", state // 10 % 10)
state = state // 10
print(state)
print("c:", state // 10 % 10)
state = state // 10
print(state)
print("b:", state // 20 % 20)
state = state // 20
print(state)
print("a:", state // 4 % 4)
state = state // 4
print(state)
您正在尝试做一些不可能的事情。如果你定义
def make_state(a,b,c,d,e,f):
return ((((((a)*4+b)*20+c)*10+d)*10+e)*5+f)*5
然后 make_state(3,13,7,8,3,2)
和 make_state(4,9,7,8,3,2)
评估为相同的状态 (1269585)。因此不可能从 1269585 开始并将该数字解码回原始向量。 make_state()
不是 one-to-one。它丢失了信息。较小的计算 state = (((((b)*20+c)*10+d)*10+e)*5+f)*5
也会丢失信息(至少在对记录的向量没有严格限制的情况下)。通常,对于任何整数 x
,函数 f(a,b): return ax+b
将无法成为 one-to-one,因此除非我遗漏了一些东西,否则整个编码数字序列的方法都是行不通的。
另一方面,如果已知数字的上限,则可以执行类似的操作。例如,如果 a,b,c,d,e,f
分别是 non-negative 个小于 4,20,10,10,5,5
的整数,则函数
def encode(a,b,c,d,e,f):
return 5*(5*(10*(10*(20*a+b)+c)+d)+e)+f
可以反转。这是从 division algorithm 得出的,它指出对于 a,b
和 b > 0
的任何整数,a
可以 唯一地 写成 a = b*q + r
和 0 <= r < b
。在上面的函数中,f
在那个范围 中除以 5
后可以唯一恢复,()
中的部分也可以 5*( ... ) + f
。从那里你可以恢复 e
,等等。一系列 5 divmods
就足够了。请注意,a
上的界限不会进入计算。
解码:
def decode(n):
q,f = divmod(n,5)
q,e = divmod(q,5)
q,d = divmod(q,10)
q,c = divmod(q,10)
a,b = divmod(q,20)
return a,b,c,d,e,f
例如:
>>> encode(3,13,7,8,3,2)
184467
>>> decode(184467)
(3, 13, 7, 8, 3, 2)
更一般地说:
def encode(numbers, choices):
#0 <= numbers[i] < choices[i] for all i
n = numbers[0]
for x,y in zip(numbers[1:],choices[1:]):
n = n*y + x
return n
def decode(n,choices):
numbers = []
for d in choices[:0:-1]:
n,r = divmod(n,d)
numbers.append(r)
numbers.append(n)
return numbers[::-1]
工作方式如下:
>>> encode([3,13,7,8,3,2],[4,20,10,10,5,5])
184467
>>> decode(184467,[4,20,10,10,5,5])
[3, 13, 7, 8, 3, 2]
我正在尝试将一些因子编码为离散数,然后将离散数逆向工程返回其因子 - 但是一旦我添加了足够多的因子,反向过程就不会显示正确的数字。
a = 3
b = 13
c = 7
d = 8
e = 3
f = 2
state = (((((b)*20+c)*10+d)*10+e)*5+f)*5
# If i add "a*4" to the front of the line (as shown in this line below), A and B is no longer showing correct
state = ((((((a)*4+b)*20+c)*10+d)*10+e)*5+f)*5
print(state)
print("f:", state // 5 % 5)
state = state // 5
print(state)
print("e:", state // 5 % 5)
state = state // 5
print(state)
print("d:", state // 10 % 10)
state = state // 10
print(state)
print("c:", state // 10 % 10)
state = state // 10
print(state)
print("b:", state // 20 % 20)
state = state // 20
print(state)
print("a:", state // 4 % 4)
state = state // 4
print(state)
您正在尝试做一些不可能的事情。如果你定义
def make_state(a,b,c,d,e,f):
return ((((((a)*4+b)*20+c)*10+d)*10+e)*5+f)*5
然后 make_state(3,13,7,8,3,2)
和 make_state(4,9,7,8,3,2)
评估为相同的状态 (1269585)。因此不可能从 1269585 开始并将该数字解码回原始向量。 make_state()
不是 one-to-one。它丢失了信息。较小的计算 state = (((((b)*20+c)*10+d)*10+e)*5+f)*5
也会丢失信息(至少在对记录的向量没有严格限制的情况下)。通常,对于任何整数 x
,函数 f(a,b): return ax+b
将无法成为 one-to-one,因此除非我遗漏了一些东西,否则整个编码数字序列的方法都是行不通的。
另一方面,如果已知数字的上限,则可以执行类似的操作。例如,如果 a,b,c,d,e,f
分别是 non-negative 个小于 4,20,10,10,5,5
的整数,则函数
def encode(a,b,c,d,e,f):
return 5*(5*(10*(10*(20*a+b)+c)+d)+e)+f
可以反转。这是从 division algorithm 得出的,它指出对于 a,b
和 b > 0
的任何整数,a
可以 唯一地 写成 a = b*q + r
和 0 <= r < b
。在上面的函数中,f
在那个范围 中除以 5
后可以唯一恢复,()
中的部分也可以 5*( ... ) + f
。从那里你可以恢复 e
,等等。一系列 5 divmods
就足够了。请注意,a
上的界限不会进入计算。
解码:
def decode(n):
q,f = divmod(n,5)
q,e = divmod(q,5)
q,d = divmod(q,10)
q,c = divmod(q,10)
a,b = divmod(q,20)
return a,b,c,d,e,f
例如:
>>> encode(3,13,7,8,3,2)
184467
>>> decode(184467)
(3, 13, 7, 8, 3, 2)
更一般地说:
def encode(numbers, choices):
#0 <= numbers[i] < choices[i] for all i
n = numbers[0]
for x,y in zip(numbers[1:],choices[1:]):
n = n*y + x
return n
def decode(n,choices):
numbers = []
for d in choices[:0:-1]:
n,r = divmod(n,d)
numbers.append(r)
numbers.append(n)
return numbers[::-1]
工作方式如下:
>>> encode([3,13,7,8,3,2],[4,20,10,10,5,5])
184467
>>> decode(184467,[4,20,10,10,5,5])
[3, 13, 7, 8, 3, 2]