Random lue 3次,因此这不是有效的解决方案。解0,12,30,12,30,12,12,3是一个有效解。我需要一个算法,它将以相同的概率生成所有有效的解决方案。如果是确定性的话就更好了。它确实有效,比我得到的任何东西都好,但是再平衡功能使运行时不确定性。糟糕透了
Random lue 3次,因此这不是有效的解决方案。解0,12,30,12,30,12,12,3是一个有效解。我需要一个算法,它将以相同的概率生成所有有效的解决方案。如果是确定性的话就更好了。它确实有效,比我得到的任何东西都好,但是再平衡功能使运行时不确定性。糟糕透了,random,list,permutation,Random,List,Permutation,lue 3次,因此这不是有效的解决方案。解0,12,30,12,30,12,12,3是一个有效解。我需要一个算法,它将以相同的概率生成所有有效的解决方案。如果是确定性的话就更好了。它确实有效,比我得到的任何东西都好,但是再平衡功能使运行时不确定性。糟糕透了。这肯定不是人们所希望的优雅解决方案。我会仔细考虑一下,但不能保证我会想出更好的办法。 0,3 1,2 3,0 2,1 0,1 2,3 import math, random def get_pool(items, y, z): s
lue 3次,因此这不是有效的解决方案。解0,12,30,12,30,12,12,3是一个有效解。我需要一个算法,它将以相同的概率生成所有有效的解决方案。如果是确定性的话就更好了。它确实有效,比我得到的任何东西都好,但是再平衡功能使运行时不确定性。糟糕透了。这肯定不是人们所希望的优雅解决方案。我会仔细考虑一下,但不能保证我会想出更好的办法。 0,3 1,2 3,0 2,1 0,1 2,3
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 and use_each_times+1 > y):
raise Exception("Impossible.")
pool = {}
for n in items:
pool[n] = use_each_times
for n in random.sample(items, exceptions):
pool[n] += 1
return pool
def rebalance(ret, pool, z):
max_item = None
max_times = None
for item, times in pool.items():
if times > max_times:
max_item = item
max_times = times
next, times = max_item, max_times
candidates = []
for i in range(len(ret)):
item = ret[i]
if next not in item:
candidates.append( (item, i) )
swap, swap_index = random.choice(candidates)
swapi = []
for i in range(len(swap)):
if swap[i] not in pool:
swapi.append( (swap[i], i) )
which, i = 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)
for i 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)
# list is the elements to be permuted
# y is the number of results desired
# z is the number of elements per result
# equalizer keeps track of who got used how many times
def constrained_permutations list, y, z
list.uniq! # Never trust the user. We want no repetitions.
equalizer = {}
list.each { |element| equalizer[element] = 0 }
results = []
# Do this until we get as many results as desired
while results.size < y
pool = []
puts pool
least_used = equalizer.each_value.min
# Find how used the least used element was
while pool.size < z
# Do this until we have enough elements in this resultset
element = nil
while element.nil?
# If we run out of "least used elements", then we need to increment
# our definition of "least used" by 1 and keep going.
element = list.shuffle.find do |x|
!pool.include?(x) && equalizer[x] == least_used
end
least_used += 1 if element.nil?
end
equalizer[element] += 1
# This element has now been used one more time.
pool << element
end
results << pool
end
return results
end
constrained_permutations [0,1,2,3,4,5,6], 6, 2
=> [[4, 0], [1, 3], [2, 5], [6, 0], [2, 5], [3, 6]]
constrained_permutations [0,1,2,3,4,5,6], 6, 2
=> [[4, 5], [6, 3], [0, 2], [1, 6], [5, 4], [3, 0]]
enter code here