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