以增量方式创建排列,其中元素均匀地呈现和分布

2024-09-28 05:23:49 发布

您现在位置:Python中文网/ 问答频道 /正文

编辑:我想出来了。请参阅最后的解决方案。我很想看看是否有更高效的实现(当然有)。

我需要创建包含9个元素的多个数组,每个元素使用数字0-11(包括)。数字需要随机抽样并按随机顺序存储。让我们假设这些数组本身将存储在一个数组中。不管它包含多少个数组(当然,高于某个阈值),这个结果数组都需要满足两个要求:

  1. 数字0-11需要在所有阵列中均匀采样
  2. 每个数字需要在所有数组中统一索引(例如,beindex[0]index[1]index[2]…和index[11]的次数大致相同
  3. (1) 和(2)需要对结果数组的任何部分保持true。即resulting_array[0:100]以及resulting_array[200:300]等等

到目前为止,我已经尝试过使用itertools和shuffle。这种方法会对所有数字产生或多或少的偶数,即使我对结果数组的一小部分进行切片(不过在这方面可能会更好).然而,这并不能使数字均匀分布在数组索引上。而且,这会产生比我需要的更多的排列;我估计有500个排列我应该可以

import random
import numpy as np
from collections import defaultdict as d

# create 10 random arrays to get things going
def shuffleThings(num, arr):
    results = []
    for i in range(num):
        b = arr.copy()
        random.shuffle(b)
        a = b[0:arrSize]
        results.append(a)
    return results

def updateDict(fDict, dDict, arr):
    for i in range(len(arr)):       
        fDict[arr[i]] += 1
        dDict[arr[i]][i] += 1    
        
def pickNums(arr):
    selected = []
    #random.shuffle(arr)
    for i in range(arrSize):
        selected.append(arr[i][0])
    random.shuffle(selected)
    return selected

def sortArrays(list1, list2): 
    zipped_pairs = zip(list2, list1) 
    z = [x for _, x in sorted(zipped_pairs)]     
    return z
    

startArrays = 10
totalArrays = 80
nums = [0,1,2,3,4,5,6,7,8,9,10,11]
arrSize = 9
freqDict = d(list)
distDict = d(list)

for i in nums:
    freqDict[i] = 0
    distDict[i] = [0,0,0,0,0,0,0,0,0]
    
all_arrays = shuffleThings(10, nums)
for i in all_arrays:
    updateDict(freqDict, distDict,i)

for i in range(totalArrays - startArrays):
    f = sorted(freqDict.items(), key=lambda item: item[1])
    tempNums = pickNums(f)
    newNums = ["","","","","","","","",""]
    counter = 0
    for j in tempNums:
        dists = distDict[j]
        indices = sortArrays([0,1,2,3,4,5,6,7,8,9],dists)
        for k in indices:
            if (newNums[k]==""):
                newNums[k] = j
                break
        counter += 1
    updateDict(freqDict,distDict,newNums)
    all_arrays.append(newNums)
    
res = []
for i in range(len(all_arrays)):
    res.append(str(all_arrays[i])[1:-1])

print(*res, sep='\n')
>>>
##excerpt
1, 3, 0, 8, 5, 7, 9, 11, 10
6, 2, 0, 1, 8, 7, 11, 5, 10
2, 5, 10, 0, 1, 9, 7, 8, 3
4, 9, 3, 7, 1, 5, 8, 11, 2
10, 0, 5, 8, 4, 9, 1, 2, 7
5, 2, 9, 8, 7, 0, 10, 4, 11
2, 0, 7, 10, 5, 4, 1, 3, 8
2, 9, 4, 0, 1, 3, 10, 6, 8
3, 0, 1, 9, 4, 10, 5, 11, 2
1, 5, 2, 7, 0, 8, 10, 11, 9
11, 4, 6, 3, 2, 1, 7, 9, 0

print(freqDict)
>>> {0: 60, 1: 60, 2: 60, 3: 60, 4: 60, 5: 60, 6: 60, 7: 60, 8: 60, 9: 60, 10: 60, 11: 60}

print(distDict)
>>> {0: [7, 7, 7, 7, 6, 6, 6, 7, 7], 
1: [7, 7, 6, 7, 7, 6, 8, 6, 6], 
2: [6, 6, 7, 7, 7, 7, 7, 7, 6], 
3: [7, 7, 6, 6, 6, 7, 7, 7, 7], 
4: [7, 7, 7, 7, 7, 6, 6, 6, 7], 
5: [6, 7, 7, 6, 7, 7, 7, 7, 6], 
6: [6, 6, 7, 7, 7, 6, 6, 7, 8], 
7: [7, 7, 7, 7, 6, 7, 7, 6, 6], 
8: [6, 7, 7, 6, 6, 7, 7, 7, 7], 
9: [7, 6, 6, 6, 7, 7, 6, 8, 7], 
10: [7, 7, 7, 7, 7, 7, 6, 6, 6], 
11: [7, 6, 6, 7, 7, 7, 7, 6, 7]}

Tags: infordefrange数字random数组all

热门问题