gpt4 book ai didi

python反Collat​​z猜想

转载 作者:行者123 更新时间:2023-12-05 07:31:57 27 4
gpt4 key购买 nike

程序应该做的是采取步骤和数字,然后输出您有多少个独特的序列,正好有 x 个 steps 来创建 number

有人知道我可以如何节省一些内存吗 - 因为我应该在 4 秒的限制内为相当大的数字工作。

def IsaacRule(steps, number):
if number in IsaacRule.numbers:
return 0
else:
IsaacRule.numbers.add(number)
if steps == 0:
return 1
counter = 0
if ((number - 1) / 3) % 2 == 1:
counter += IsaacRule(steps-1, (number - 1) / 3)
if (number * 2) % 2 == 0:
counter += IsaacRule(steps-1, number*2)

return counter

IsaacRule.numbers = set()

print(IsaacRule(6, 2))

如果有人知道带内存的版本,我将不胜感激,现在它可以工作,但仍有改进的余地。

最佳答案

基线:IsaacRule(50, 2) 需要 6.96 秒

0) 使用LRU缓存

这使代码花费了更长的时间,并给出了不同的最终结果

1) 消除if条件:(number * 2) % 2 == 0 to True

IsaacRule(50, 2) 需要 0.679 秒。感谢 Pm2Ring 的这个。

2) 将 ((number - 1)/3) % 2 == 1 简化为 number % 6 == 4 并尽可能使用楼层划分:

IsaacRule(50, 2) 耗时 0.499s

真值表:

| n | n-1 | (n-1)/3 | (n-1)/3 % 2 | ((n-1)/3)%2 == 1 |
|---|-----|---------|-------------|------------------|
| 1 | 0 | 0.00 | 0.00 | FALSE |
| 2 | 1 | 0.33 | 0.33 | FALSE |
| 3 | 2 | 0.67 | 0.67 | FALSE |
| 4 | 3 | 1.00 | 1.00 | TRUE |
| 5 | 4 | 1.33 | 1.33 | FALSE |
| 6 | 5 | 1.67 | 1.67 | FALSE |
| 7 | 6 | 2.00 | 0.00 | FALSE |

代码:

def IsaacRule(steps, number):
if number in IsaacRule.numbers:
return 0
else:
IsaacRule.numbers.add(number)
if steps == 0:
return 1
counter = 0
if number % 6 == 4:
counter += IsaacRule(steps-1, (number - 1) // 3)
counter += IsaacRule(steps-1, number*2)

return counter

3) 使用集合重写代码

IsaacRule(50, 2) 耗时 0.381s

这让我们可以利用对集合所做的任何优化。基本上我在这里进行广度优先搜索。

4) 打破循环,这样我们就可以跳过对以前状态的跟踪。

IsaacRule(50, 2) 需要 0.256 秒

我们只需要添加一个检查 number != 1 来打破唯一已知的循环。这会加快速度,但如果您从 1 开始,则需要添加一个特殊情况。感谢 Paul 的建议!

START = 2
STEPS = 50

# Special case since we broke the cycle
if START == 1:
START = 2
STEPS -= 1

current_candidates = {START} # set of states that can be reached in `step` steps

for step in range(STEPS):
# Get all states that can be reached from current_candidates
next_candidates = set(number * 2 for number in current_candidates if number != 1) | set((number - 1) // 3 for number in current_candidates if number % 6 == 4)

# Next step of BFS
current_candidates = next_candidates
print(len(next_candidates))

关于python反Collat​​z猜想,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51537946/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com