我使用538的Riddler练习代码。用Python编写了一个简单的模拟,但是必须添加另一个嵌套循环来获取均值,以减少输出方差。试图运行它,但是在45分钟后我停止了它,认为必须要有一种方法来提高代码的效率。
就上下文而言,问题是:您有一台收音机,每天播放100首歌曲。播放同一首歌曲的概率必须等于50%。
我的方法是将播放列表的大小(从7000开始)增加1,直到重播的平均概率的总平均值等于50%,并且样本数量和样本数量均使用1000。
代码是:
import random
playlist = 7000
chance_of_replay = []
sample = 1000
mean_chance_of_replay = 0
replays = 0
temp_sum = 0
while mean_chance_of_replay > 0.5 or mean_chance_of_replay == 0.0:
playlist += 1
for j in range(0, sample):
for i in range(1, sample + 1):
songs_to_play = 100
songs_played = []
while songs_to_play > 0:
song_pick = random.randint(1, playlist + 1)
if song_pick not in songs_played:
songs_played.append(song_pick)
songs_to_play -= 1
else:
replays += 1
break
chance_of_replay.insert(j, (replays / sample))
replays = 0
for element in chance_of_replay:
temp_sum = temp_sum + element
mean_chance_of_replay = temp_sum/sample
print(playlist)
答案 0 :(得分:0)
在查看代码中的性能问题之前,首先要解决一个更大的问题:代码处于无限循环中。
永远不会清除列表 chance_of_replay ,并且永远不会将变量 temp_sum 设置为0。因此,变量 mean_chance_of_replay 始终会增加并且您的代码将永远运行。
修复了这两个逻辑错误之后,您应该开始担心性能优化。
答案 1 :(得分:0)
播放列表大小增加时,播放同一首歌曲中的两首歌曲的机会降低。 您是否考虑过以7000的播放列表播放同一首歌曲的几率实际上低于50%?如果是这样,那么检查任何较高的值只会导致较小的百分比,因此您将永远找不到答案。
如果要进行仿真(与纯数学方法相反),我可以找到的主要优化是,多次执行数组插入和追加操作是相当大的性能杀手。我要做的是创建一个布尔值数组,用于存储是否已播放任何给定歌曲的状态。检查给定的歌曲是否已播放,并且不需要任何插入即可在幕后制作新阵列的操作要容易得多。
代码如下:
from random import randint
playlist_size = 1
samples = 1000
songs_per_sample = 100
simulation_running = True
while simulation_running:
replays = 0
for _ in range(samples):
songs_played = [False] * playlist_size
for song_sample in range(songs_per_sample):
song_to_play_index = randint(0, playlist_size - 1)
if songs_played[song_to_play_index]:
replays += 1
songs_played[song_to_play_index] = True
replay_chance = replays / (samples * songs_per_sample)
if replay_chance <= 0.5:
break
playlist_size += 1
print(playlist_size)
运行此命令实际上给出了一个令人惊讶的答案,即低于7000!