我有一个赋值任务,我为一系列从1到N的初值编写了Collatz猜想程序,并绘制了两幅图:迭代次数与初始值和计算数与初始值。指派提示符是:
现在,修改您的程序,以便它计算3个向量。第一个向量s(k)是起始数( N ),向量f(k)在迭代时将计算出的数作为起始数N的函数存储,g(N)是到达数字1所需的迭代次数。例如,如果N=4、s、f和g看起来是:= 1,2,2,3,3,3,3,3,3,3,4,4 = 1,2,1,3,10,16,8,4,2,1,4,2,1 = 0,1,7,2,则可以在一个窗口中绘制这些值的图,并使其x和y轴范围从1到N,对两个轴都使用从1到200的数字范围。
这是我的密码。
import numpy as np
import matplotlib.pyplot as plt
# INPUTS
# Set N to a positive integer. The Hailstone problem program
# will be evaluated for starting numbers from 1 to N.
N = 200
marker_size = 7
s_no_repeats = range(1, N+1) # starting number vector (with NO repeating starting values)
def flatten(t):
''' Create flatlist out of list of lists '''
return [item for sublist in t for item in sublist]
def find_repeat(numbers):
'''Check repeating value in list and returns the value'''
seen = set()
for num in numbers:
if num in seen:
return num
seen.add(num)
def Collatz(n):
k = 0 # current iteration number
computed_nums = [n] # sequence of computed numbers from n to 1
iterations = [0]
while n != 1:
if n % 2 == 0:
n = (n / 2)
else:
n = ((n * 3) + 1)
k += 1
computed_nums.append(n)
iterations.append(k)
map(int, computed_nums)
return (computed_nums, k)
s = [] # starting number vector (with repeating starting values)
f = [] # computed number vector as function of starting number N at iteration k
g = [] # number of iterations required to get to 1
for starting_num in s_no_repeats:
temp_f, temp_g = Collatz(starting_num)
#print(temp_f)
f.append(temp_f)
g.append(temp_g)
s.append([starting_num] * (temp_g + 1))
s = flatten(s)
f = flatten(f)
print("s vector (starting nums): " + str(s))
print("f vector (computed nums): " + str(f))
print("g vector (iterations): " + str(g))
fig, (ax1, ax2) = plt.subplots(1, 2)
# left subplot (for computed values)
ax1.scatter(s, f, color="blue", s=marker_size, clip_on=False, zorder = 10)
ax1.set_title('range of computed values during iteration')
ax1.set_xlabel('starting value')
ax1.set_xlim([1, N])
ax1.set_ylim([1, N])
# right subplot (for iterations)
ax2.scatter(s_no_repeats, g, color="red", s=marker_size, clip_on=False, zorder = 10)
ax2.set_title('number of iterations')
ax2.set_xlabel('starting value')
ax2.set_xlim([1, N])
ax2.set_ylim([1, N])
fig.tight_layout() # automatically adjusts enough space between subplots我想知道这能不能得到改善?

发布于 2022-01-15 20:38:48
您不使用Numpy,所以删除您的导入。
N是一个参数,而不是常量-因此,将代码重构为传递它的函数,从而从全局命名空间中删除代码。
删除flatten函数,使用list.extend而不是append来构建列表。
find_repeat不用于删除它。
Collatz应该是PEP8的小写.
考虑使用divmod执行组合除法2和模数2。
从您的iterations函数中删除collatz,因为您不使用它。
为您的s、f、g列表和axis对象提供更有意义的名称。
clip_on和zorder只是把它们弄得一团糟,把它们删除。
增加一个__main__守卫。
在你的两个子图之间改变颜色是没有价值的,因为它们有独立的轴。如果您试图在相同的轴上绘制两个数据集,您将需要单独的颜色。
添加PEP484类型提示。
考虑减少点的α通道,以便更容易地说明点密度。
您的map调用的返回未使用,所以请删除它。
import matplotlib.pyplot as plt
def collatz(n: int) -> tuple[
list[int], # computed_nums
int, # current iteration number
]:
k = 0 # current iteration number
computed_nums = [n] # sequence of computed numbers from n to 1
while n != 1:
half_n, odd = divmod(n, 2)
if odd:
n = n*3 + 1
else:
n = half_n
k += 1
computed_nums.append(n)
return computed_nums, k
def collatz_all(n: int) -> tuple[
list[int], # starting
list[int], # computed
list[int], # iterations
range, # starting_no_repeats
]:
starting_no_repeats = range(1, n + 1) # starting number vector (with NO repeating starting values)
starting = [] # starting number vector (with repeating starting values)
computed = [] # computed number vector as function of starting number N at iteration k
iterations = [] # number of iterations required to get to 1
for starting_num in starting_no_repeats:
temp_f, temp_g = collatz(starting_num)
computed.extend(temp_f)
iterations.append(temp_g)
starting.extend([starting_num] * (temp_g + 1))
return starting, computed, iterations, starting_no_repeats
def plot(starting, computed, iterations, starting_no_repeats, n: int) -> plt.Figure:
fig, (ax_computed, ax_iterations) = plt.subplots(nrows=1, ncols=2)
style = {
's': 7,
'alpha': 0.2,
}
# left subplot (for computed values)
ax_computed.scatter(starting, computed, **style)
ax_computed.set_title('range of computed values during iteration')
ax_computed.set_xlabel('starting value')
ax_computed.set_ylim((0, n))
# right subplot (for iterations)
ax_iterations.scatter(starting_no_repeats, iterations, **style)
ax_iterations.set_title('number of iterations')
ax_iterations.set_xlabel('starting value')
ax_iterations.set_ylim((0, n))
fig.tight_layout() # automatically adjusts enough space between subplots
return fig
def main() -> None:
# INPUTS
# Set N to a positive integer. The Hailstone problem program
# will be evaluated for starting numbers from 1 to N.
n = 200
starting, computed, iterations, starting_no_repeats = collatz_all(n)
print(f"s vector (starting nums): {starting}")
print(f"f vector (computed nums): {computed}")
print(f"g vector (iterations): {iterations}")
plot(starting, computed, iterations, starting_no_repeats, n)
plt.show()
if __name__ == '__main__':
main()该地块位于一个大窗口中,因此透明度效果并不十分明显:

对于一个浓缩的窗口来说,它变得更重要:

https://codereview.stackexchange.com/questions/272993
复制相似问题