我目前正在尝试获取随机排列的数字数组:
label_array = np.repeat(np.arange(6), 12)
唯一的限制是,随机播放的连续元素不得相同。为此,我目前正在使用以下代码:
# Check if there are any occurrences of two consecutive
# elements being of the same category (same number)
num_occurrences = np.sum(np.diff(label_array) == 0)
# While there are any occurrences of this...
while num_occurrences != 0:
# ...shuffle the array...
np.random.shuffle(label_array)
# ...create a flag for occurrences...
flag = np.hstack(([False], np.diff(label_array) == 0))
flag_array = label_array[flag]
# ...and shuffle them.
np.random.shuffle(flag_array)
# Then re-assign them to the original array...
label_array[flag] = flag_array
# ...and check the number of occurrences again.
num_occurrences = np.sum(np.diff(label_array) == 0)
尽管这适用于这种大小的数组,但我不知道它是否适用于更大的数组。即使这样,也可能会花费很多时间。
那么,有没有更好的方法呢?
答案 0 :(得分:1)
从技术上讲,可能不是最佳答案,希望它能满足您的要求。
import numpy as np
def generate_random_array(block_length, block_count):
for blocks in range(0, block_count):
nums = np.arange(block_length)
np.random.shuffle(nums)
try:
if nums[0] == randoms_array [-1]:
nums[0], nums[-1] = nums[-1], nums[0]
except NameError:
randoms_array = []
randoms_array.extend(nums)
return randoms_array
generate_random_array(block_length=1000, block_count=1000)
答案 1 :(得分:0)
在Python> = 3.6的情况下,这是一种使用random.choices的方法,该方法允许从具有权重的总体中进行选择。
想法是一一生成数字。每次生成新数字时,我们都会通过将其权重暂时设置为零来排除前一个数字。然后,我们减小所选对象的权重。
正如@roganjosh适当指出的那样,当我们剩下最后一个值的多个实例时,最终会遇到一个问题-这真的很常见,尤其是值少且重复次数多时
我使用的解决方案是使用简短的send_back
函数将这些值重新插入不会产生冲突的列表中。
import random
def send_back(value, number, lst):
idx = len(lst)-2
for _ in range(number):
while lst[idx] == value or lst[idx-1] == value:
idx -= 1
lst.insert(idx, value)
def shuffle_without_doubles(nb_values, repeats):
population = list(range(nb_values))
weights = [repeats] * nb_values
out = []
prev = None
for i in range(nb_values * repeats):
if prev is not None:
# remove prev from the list of possible choices
# by turning its weight temporarily to zero
old_weight = weights[prev]
weights[prev] = 0
try:
chosen = random.choices(population, weights)[0]
except IndexError:
# We are here because all of our weights are 0,
# which means that all is left to choose from
# is old_weight times the previous value
send_back(prev, old_weight, out)
break
out.append(chosen)
weights[chosen] -= 1
if prev is not None:
# restore weight
weights[prev] = old_weight
prev = chosen
return out
print(shuffle_without_doubles(6, 12))
[5, 1, 3, 4, 3, 2, 1, 5, 3, 5, 2, 0, 5, 4, 3, 4, 5,
3, 4, 0, 4, 1, 0, 1, 5, 3, 0, 2, 3, 4, 1, 2, 4, 1,
0, 2, 0, 2, 5, 0, 2, 1, 0, 5, 2, 0, 5, 0, 3, 2, 1,
2, 1, 5, 1, 3, 5, 4, 2, 4, 0, 4, 2, 4, 0, 1, 3, 4,
5, 3, 1, 3]
一些粗略的计时:生成(shuffle_without_doubles(600, 1200))
大约需要30秒,因此有720000个值。