Теперь, когда вы пояснили, что вы хотели, вот пересмотр моего первоначального ответа, который представляет собой реализацию на чистом python, основанную на ограничениях. Изменить исходный ответ было довольно легко, поэтому я также добавил код, чтобы ограничить число итераций и распечатать небольшой отчет в конце, проверяя его на соответствие всем критериям.
from collections import Counter
from itertools import chain
from pprint import pprint
import random
def pick_subset(population, length, repeat, max_iterations=1000000):
iterations = 0
while iterations < max_iterations:
# Get subset where every sample value occurrs at exactly "repeat" times.
while iterations < max_iterations:
iterations += 1
subset = [random.sample(population, length) for i in range(length)]
measure = Counter(chain.from_iterable(subset))
if all((iterations == repeat for iterations in measure.values())):
break
# Check whether there are no more than 2 repeats in per row.
if all((all((iterations < 2 for iterations in Counter(row).values()))
for row in subset)):
break
if iterations >= max_iterations:
raise RuntimeError("Couldn't match criteria after {:,d}".format(iterations))
else:
print('Succeeded after {:,d} iterations'.format(iterations))
return subset
samples = range(12)
length = 6
repeat = 3
subset = pick_subset(samples, length, repeat)
print('')
print('Selected subset:')
pprint(subset)
# Show that each sample occurs exactly three times.
freq_counts = Counter(chain.from_iterable(subset))
print('')
print('Overall sample frequency counts:')
print(', '.join(
'{:2d}: {:d}'.format(sample, cnt) for sample, cnt in freq_counts.items()))
# Show that no sample occurs more than twice in a each row.
print('')
print('Sample frequency counts per row:')
for i, row in enumerate(subset):
freq_counts = Counter(row)
print(' row[{}]: {}'.format(i, ', '.join(
'{:2d}: {:d}'.format(sample, cnt) for sample, cnt in freq_counts.items())))
Пример вывода:
Succeeded after 123,847 iterations
Selected subset:
[[4, 9, 10, 2, 5, 7],
[5, 8, 6, 0, 11, 1],
[1, 8, 3, 10, 7, 0],
[7, 3, 2, 4, 11, 9],
[0, 10, 11, 6, 1, 2],
[8, 3, 9, 4, 6, 5]]
Overall sample frequency counts:
0: 3, 1: 3, 2: 3, 3: 3, 4: 3, 5: 3, 6: 3, 7: 3, 8: 3, 9: 3, 10: 3, 11: 3
Sample frequency counts per row:
row[0]: 2: 1, 4: 1, 5: 1, 7: 1, 9: 1, 10: 1
row[1]: 0: 1, 1: 1, 5: 1, 6: 1, 8: 1, 11: 1
row[2]: 0: 1, 1: 1, 3: 1, 7: 1, 8: 1, 10: 1
row[3]: 2: 1, 3: 1, 4: 1, 7: 1, 9: 1, 11: 1
row[4]: 0: 1, 1: 1, 2: 1, 6: 1, 10: 1, 11: 1
row[5]: 3: 1, 4: 1, 5: 1, 6: 1, 8: 1, 9: 1