我怎样才能修复我的代码来解决这个难题? (Python)

How can I fix my code to solve for this puzzle? (Python)

这是我正在解决的难题的图表: 其中 A、B、C、D 是 0 或 1 的四个数字,alpha 是一些随机常数(可以是正数或负数,但忽略它们为 0 的情况)。目标是在给定随机 alpha 数组的情况下确定列表 [A,B,C,D]。以下是一些规则:

  1. 如果alpha>0,则相邻点的值不同。 (例如:如果 alpha_A = 4.5,则 A、B = 01 或 10。

  2. 如果alpha <0,则相邻点具有相同的值。 (例如:如果 alpha_B = -4.5,则 B、C = 00 或 11。

  3. 让相邻的两个点为最高的常量alpha_i,然后从绝对值第二高的开始,迭代到第二低的。仅当 alpha_i 具有最小绝对值时才可能违反规则 1 和 2。

这是我当前的代码:

alpha = np.random.normal(0, 10, N_object4)
pa = np.abs(alpha)
N_object4 = 4
num = pa.argsort()[-3:][::-1] # Index of descending order for abs
print(alpha)
print(num)
ABCD = np.zeros(N_object4).tolist()
if alpha[num[0]] > 0:
    ABCD[num[0]+1] = 1  # The largest assignment stays constant.
for i in range (1,len(num)): # Iterating from the 2nd largest abs(alpha) to the 2nd smallest.
    if i == 3:
        num[i+1] = num[0] 
    elif alpha[num[i]] > 0:
        if np.abs(num[i]-num[0]) == 1 or 2:
            ABCD[num[i+1]] = 1-ABCD[num[i]]
        elif np.abs(num[i]-num[0]) == 3:
            ABCD[num[i]] = 1-ABCD[num[0]]
    elif alpha[num[i]] < 0:
            if np.abs(num[i]-num[0]) == 1 or 2:
                **ABCD[num[i+1]] = ABCD[num[i]]**
            elif np.abs(num[i]-num[0]) == 3:
                ABCD[num[i]] = ABCD[num[0]]  

我想我的代码中仍然遗漏了一些东西。我当前版本有错误(标有**的行):

IndexError: index 3 is out of bounds for axis 0 with size 3

我想知道我的错误在哪里?

此外,所需输出的示例:if

alpha = [12.74921599, -8.01870123, 11.07638142, -3.51723019] 

然后

num = [0, 2, 1]

正确的ABCD列表应该是:

ABCD = [0, 1, 1, 0] (or [1, 0, 0, 1])

我以前的版本可以给我一个输出,但是列表 ABCD 看起来不正确。

非常感谢您阅读我的问题,非常感谢您的帮助:)

查看您的代码是否发现一些异味:

  • nums 是 3 个元素长,看来你想要 num = pa.argsort()[-4:][::-1]

您在其他地方也有索引问题:

if i == 3:
       num[i+1] = num[0] 

元素4不在数组中

我的个人建议:考虑到问题的规模较小,摆脱 numpy 并仅使用 python 列表。

另一个观察(我花了很多年才学会)是对于小问题,暴力破解是可以的。

这是我的暴力解决方案,有更多时间,可以改进它来做回溯或动态规划:

import random
# To make things simpler, I will consider A = 0, and so on
pairs = [
    (0, 1),
    (1, 2),
    (2, 3),
    (3, 0),
]

# Ensure no zeros on our list
alphas = [(random.choice([1, -1]) * random.uniform(1, 10), pairs[n]) for n in range(4)]

print(alphas)

# Sort descending in
alphas.sort(reverse=True, key=lambda n: abs(n[0]))

print(alphas[:-1])


def potential_solutions():
    """Generator of potential solutions"""
    for n in range(16):
        # This just abuses that in binary, numbers from 0 to 15 cover all posible configurations
        # I use shift and masking to get each bit and return a list
        yield [n >> 3 & 1 , n >> 2 & 1, n >> 1 & 1, n & 1]


def check(solution):
    """Takes a candidate solution and check if is ok"""
    for alpha, (right, left) in alphas[:-1]:
        if alpha < 0 and solution[right] != solution[left]:
            return False
        elif alpha > 0 and solution[right] ==  solution[left]:
            return False
    return True


# Look for correct solutions
for solution in potential_solutions():
    if check(solution):
        print(solution)