Posts: 1,094
Threads: 143
Joined: Jul 2017
Nov-06-2022, 12:21 AM
(This post was last modified: Nov-06-2022, 12:21 AM by Pedroski55.)
Polished my poor contribution, seems to work!
import itertools
import random
images = ['im1', 'im2', 'im3', 'im4', 'im5', 'im6', 'im7', 'im8',
'im9', 'im10', 'im11', 'im12', 'im13', 'im14', 'im15',
'im16', 'im17', 'im18','im19','im20','im21','im22','im23','im24']
com_set = itertools.combinations(images, 9)
# creates a list of tuples
mylist = list(com_set)
len(mylist) # 1307504
# just pick randomly from mylist
uniques = []
while len(uniques) < 150:
randnum = random.randint(0, 1307504)
# make sure no image appears more than once
if len(mylist[randnum] == len(set(mylist[randnum]):
# make the tuple a list for shuffling
l2 = list(mylist[randnum])
random.shuffle(l2)
uniques.append(l2)
for u in uniques:
print(u)
Posts: 6,806
Threads: 20
Joined: Feb 2020
I was not thinking that min_ and max_ represented the variation of a single set, they are just the extreme outliers for biggest set, smallest set, and biggest difference (diff) between the biggest and smallest sets. 150 sets is a small sample and I just wanted to show that there will be cases where a random sampling will give results that are random, but don't look even.
I think the requirements are wrong. I would make the number of images a multiple of the set size. If you can't do that, I really don't know how I would solve this problem. Maybe make sets of 8, which is easily done by shuffling the image list and slicing to get 3 sets, repeat 50 times. Then I would have to go back and add a "random" image to each set in such a way that the "extra" image is not already in the set, and all the images are equally represented among the "extra" images. Ugly.
Posts: 4,795
Threads: 76
Joined: Jan 2018
Nov-06-2022, 09:30 AM
(This post was last modified: Nov-06-2022, 09:30 AM by Gribouillis.)
(Nov-06-2022, 12:21 AM)Pedroski55 Wrote: Polished my poor contribution, seems to work! There are many flaws in this code. The first thing is that you store 1.3 million tuples just to reproduce what random.sample() does without memory consumption. Then the part that checks that images appear only once is unnecessary because this will always be true because the initial 'images' list contains no repeated items. Finally you don't need to shuffle the result because all the shuffled versions of the combination are already members of 'mylist'. (sorry I was wrong on this point this is a difference between sample() and combinations()).
Posts: 6,806
Threads: 20
Joined: Feb 2020
A rough hack at what I am thinking:
import random
from collections import Counter
from itertools import chain
images = list(range(1, 25))
image_pool = []
for _ in range(50):
random.shuffle(images)
image_pool.extend(images)
extras = []
for _ in range (150 // len(images)+1):
random.shuffle(images)
extras.extend(images)
# Construct sets of 9 using 8 images from the image pool and 1 extra image.
sets = []
for index in range(0, 8*150, 8):
set_ = image_pool[index:index+8]
for image in extras+images: # +images is a safety net
if image not in set_:
set_.append(image)
extras.remove(image)
break
sets.append(set_)
x = [s[8] for s in sets]
print(x)
counts = Counter(x).most_common()
print("\n".join(map(str, counts))) 6 images are used 57 times. The other 18 images are used 56 times. I ran a test with modified code to count how many times the "safety net" was used. I repeated creating 150 sets 100,000 times and didn't use the safety net once.
Posts: 1,094
Threads: 143
Joined: Jul 2017
@ Grillboulis
Well, I don't think that memory is so great a consideration nowadays.
The above completes in the blink of an eye. It's not like it takes minutes to finish.
Put in a function, as you recently told me I believe, as soon as the function completes, the garbage collector removes all leftovers.
I don't think I need to check if the tuples of 9 images have any repeats of 1 image, because they are combinations, which should be unique, I think, but I wasn't sure, as I never deal in permutations and combinations, so it is just a safety.
If permutations of 9 from 24 are allowed, there will be nearly 500 trillion permutations to choose from.
Isn't it possible to get permutations with random.sample()??
|