Create many constrained, random permutation of a list -
i need make random list of permutations. elements can assume integers 0 through x-1. want make y lists, each containing z elements. rules no list may contain same element twice , on lists, number of times each elements used same (or close possible). instance, if elements 0,1,2,3, y 6, , z 2, 1 possible solution is:
0,3 1,2 3,0 2,1 0,1 2,3
each row has unique elements , no element has been used more 3 times. if y 7, 2 elements used 4 times, rest 3.
this improved, seems job (python):
import math, random def get_pool(items, y, z): slots = y*z use_each_times = slots/len(items) exceptions = slots - use_each_times*len(items) if (use_each_times > y or exceptions > 0 , use_each_times+1 > y): raise exception("impossible.") pool = {} n in items: pool[n] = use_each_times n in random.sample(items, exceptions): pool[n] += 1 return pool def rebalance(ret, pool, z): max_item = none max_times = none item, times in pool.items(): if times > max_times: max_item = item max_times = times next, times = max_item, max_times candidates = [] in range(len(ret)): item = ret[i] if next not in item: candidates.append( (item, i) ) swap, swap_index = random.choice(candidates) swapi = [] in range(len(swap)): if swap[i] not in pool: swapi.append( (swap[i], i) ) which, = random.choice(swapi) pool[next] -= 1 pool[swap[i]] = 1 swap[i] = next ret[swap_index] = swap def plist(items, y, z): pool = get_pool(items, y, z) ret = [] while len(pool.keys()) > 0: while len(pool.keys()) < z: rebalance(ret, pool, z) selections = random.sample(pool.keys(), z) in selections: pool[i] -= 1 if pool[i] == 0: del pool[i] ret.append( selections ) return ret print plist([0,1,2,3], 6, 2)
Comments
Post a Comment