如何利用电脑全部算力运行10e+15次模拟的Python代码?
问题分析与解决方案
首先必须明确:10^16次模拟(10e+15)在任何本地设备上都是完全不可行的。哪怕你的电脑每秒能执行10亿次模拟,也需要约115天才能完成;而Python的实际执行速度远低于这个量级,实际需要数百年,这显然不现实。
你的代码存在两个核心问题:
- 模拟次数远超合理范围,蒙特卡洛模拟不需要这么多次就能得到足够精确的结果(通常1e6~1e7次就足够);
- 递归实现的模拟效率极低,且单线程运行没有利用多核CPU的算力。
优先方案:用动态规划计算精确概率
因为你的模拟逻辑是固定10天、每天价格变化是±1~±6的离散情况,完全可以用动态规划直接计算精确概率,不需要任何模拟。
动态规划实现代码
def calculate_exact_probability(days, initial_price, target_price): # dp[day][price] = 到达该价格的路径数 dp = [{} for _ in range(days + 1)] dp[0][initial_price] = 1 for day in range(1, days + 1): for price, count in dp[day-1].items(): # 正面:+1~+6 for delta in range(1, 7): new_price = price + delta dp[day][new_price] = dp[day].get(new_price, 0) + count # 反面:-1~-6 for delta in range(1, 7): new_price = price - delta dp[day][new_price] = dp[day].get(new_price, 0) + count # 计算所有超过target_price的路径数总和 total_successful = sum(count for price, count in dp[days].items() if price > target_price) total_paths = 2**days * 6**days # 每天2种硬币结果*6种骰子结果,共10天 return total_successful / total_paths days = 10 initial_price = 100 target_price = 150 exact_prob = calculate_exact_probability(days, initial_price, target_price) print(f"精确概率:{exact_prob:.6f}")
这段代码会直接计算出精确的概率,运行时间仅需几毫秒,完全不需要模拟。
若坚持使用模拟:优化代码并利用本地多核算力
如果一定要用蒙特卡洛模拟(比如学习目的),请先将模拟次数降到合理范围(比如1e7次以内),然后通过以下方式优化:
1. 重构模拟代码,去掉递归,改用循环(提升单线程效率)
递归调用会带来额外的开销,改用循环可以大幅提升速度:
import random def simulate_stock_price(days, current_price): for _ in range(days): coin_flip = random.choice([True, False]) # 用布尔值代替字符串,更快 dice_roll = random.randint(1, 6) if coin_flip: current_price += dice_roll else: current_price -= dice_roll return current_price > 150
2. 使用多进程利用多核CPU
Python的multiprocessing模块可以将模拟任务分配到多个CPU核心上并行执行:
import multiprocessing as mp def simulate_batch(num_simulations): count = 0 for _ in range(num_simulations): if simulate_stock_price(10, 100): count += 1 return count def calculate_probability_parallel(num_simulations, days): # 获取CPU核心数 num_cores = mp.cpu_count() # 分配每个进程的模拟次数 batch_size = num_simulations // num_cores batches = [batch_size] * num_cores # 处理余数 if num_simulations % num_cores != 0: batches[-1] += num_simulations % num_cores # 创建进程池 with mp.Pool(num_cores) as pool: results = pool.map(simulate_batch, batches) total_successful = sum(results) return total_successful / num_simulations # 改用合理的模拟次数,比如1e7次 num_simulations = 10_000_000 probability = calculate_probability_parallel(num_simulations, 10) print(f"模拟概率:{probability:.4f}")
3. 进一步优化:使用NumPy向量化模拟
用NumPy可以将模拟向量化,大幅提升速度:
import numpy as np def calculate_probability_numpy(num_simulations, days): # 生成所有模拟的硬币结果:True=Heads, False=Tails coin_flips = np.random.choice([True, False], size=(num_simulations, days)) # 生成所有模拟的骰子点数 dice_rolls = np.random.randint(1, 7, size=(num_simulations, days)) # 计算每天的价格变化:正面加,反面减 deltas = np.where(coin_flips, dice_rolls, -dice_rolls) # 计算每个模拟的最终价格 final_prices = 100 + deltas.sum(axis=1) # 计算成功次数 num_successful = np.sum(final_prices > 150) return num_successful / num_simulations num_simulations = 10_000_000 probability = calculate_probability_numpy(num_simulations, 10) print(f"NumPy模拟概率:{probability:.4f}")
4. 使用PyPy代替CPython
PyPy是Python的JIT编译器,对于循环密集型代码(比如你的模拟),速度可以比CPython快5~10倍,直接用PyPy运行你的优化后代码即可。
内容的提问来源于stack exchange,提问作者O M
相关产品推荐
相关产品推荐

