【问题标题】:Python -- program after refactoring returns different resultPython——重构后的程序返回不同的结果
【发布时间】:2017-09-01 07:44:02
【问题描述】:

我正在计算2 * Volumesphere(dimension=4) / Volumecylinder(dimension=4)。我错的是解决问题的第一种方法。第二种方法给出了正确的答案。也就是说,当答案应该是 1.17 时,我得到 1.14。这些程序有何不同?我看不出区别。

import random

# FIRST WAY

print('elegant solution')

coordinates = [0] * 3
alpha = 0
delta = 0.1
deltas = [0] * 3
n_trials = 1000000
n_hits = 0

for a in range(6):
    for i in range(n_trials):
        # gets random deltas, and random alpha for 4th dimension
        deltas = [random.uniform(-delta, delta) for coordinate in deltas]
        alpha = random.uniform(-1.0, 1.0)

        # sum of the (n - 1) first components
        sum_components = sum((coordinates[j] + deltas[j])**2 for j in range(3))

        # if the sample is inside the cylinder
        if sum_components < 1.0:
            coordinates = [coordinates[j] + deltas[j] for j in range(3)]

        # if the sample is inside the sphere
        if sum_components + alpha**2 < 1.0:
            n_hits += 1

    print (2.0 * float(n_hits) / float(n_trials)) # 2V_sph(4) / V_cyl(4) where V_sph=hits Vcyl=trials
    coordinates = [0] * 3
    n_hits = 0

# SECOND WAY

print('typical solution')

x, y, z, alpha = 0.0, 0.0, 0.0, 0.0
delta = 0.1
n_trials = 1000000
n_hits = 0

for a in range (6):
    for i in range(n_trials):
        # gets random deltas, and random alpha for 4th dimension
        del_x, del_y, del_z, alpha = random.uniform(-delta, delta), random.uniform(-delta, delta), random.uniform(-delta, delta), random.uniform(-1, 1)

        # if the sample is inside the cylinder
        if (x + del_x)**2 + (y + del_y)**2 + (z + del_z)**2 < 1.0:
            x, y, z = x + del_x, y + del_y, z + del_z

        # if the sample is inside the sphere
        if x**2 + y**2 + z**2 + alpha**2 < 1.0:
            n_hits += 1

    print (2.0 * n_hits / float(n_trials)) # 2V_sph(4) / V_cyl(4) where V_sph=hits Vcyl=trials
    x, y, z = 0.0, 0.0, 0.0
    n_hits = 0

【问题讨论】:

    标签: python algorithm for-loop if-statement math


    【解决方案1】:

    下一行:

    if (sum_components + alpha**2) < 1.0:
    

    不等于:

    if (x**2 + y**2 + z**2 + alpha**2) < 1.0:
    

    等于:

    if ((x + del_x)**2 + (y + del_y)**2 + (z + del_z)**2 + alpha**2) < 1.0
    

    你可以换一种方式:

    if sum(c**2 for c in coordinates) + alpha**2 < 1.0
    

    您的代码不是很 Pythonic。这是一些重构:

    import random
    
    delta = 0.1
    n_trials = 1000000
    
    for _ in range(6):
        coords = [0] * 3
        n_hits = 0
    
        for _ in range(n_trials):
            deltas = [random.uniform(-delta, delta) for _ in range(len(coords))]
            alpha = random.uniform(-1.0, 1.0)
    
            if sum((c + d)**2 for c, d in zip(coords, deltas)) < 1.0:
              coords = [c + d for c, d in zip(coords, deltas)]
    
            if sum(c**2 for c in coords) + alpha**2 < 1.0:
                n_hits += 1
    
        print(2.0 * n_hits / n_trials)
    

    【讨论】:

    • 您也可以在答案中添加一个工作表达式:(sum(i**2 for i in coordinates)+alpha**2) :)
    • 非常感谢你们! :)
    猜你喜欢
    • 2021-07-05
    • 2020-07-28
    • 1970-01-01
    • 2019-07-01
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 1970-01-01
    • 2019-01-18
    相关资源
    最近更新 更多