fork download
  1. import random
  2. import itertools
  3.  
  4. #Храним списки пар (элемент, вес). Веса нормализованы.
  5. weighted_elements = [[(1, 0.8), (2, 0.1), (3, 0.1)],
  6. [(1, 0.3), (2, 0.5), (3, 0.1), (10, 0.1)],
  7. [(8, 0.35), (4, 0.25), (2, 0.4)]]
  8.  
  9. #Амплитуда шума. Пусть будет 30% от максимального разброса суммарных весов векторов.
  10. amp = 0.3 * sum(max(item[1] for item in sublist) - min(item[1] for item in sublist) for sublist in weighted_elements)
  11.  
  12. #Если все элементы имеют равный вес, то amp == 0, что плохо.
  13. #Есть простая альтернатива: amp = 0.3 * len(weighted_elements)
  14.  
  15. combs = sorted(itertools.product(*weighted_elements),
  16. key = lambda x: sum(y[1] for y in x) + amp * random.random(),
  17. reverse = True)
  18.  
  19. res = [[item[0] for item in vec] for vec in combs]
  20.  
  21. print (res)
  22.  
  23.  
  24.  
  25.  
  26.  
Success #stdin #stdout 0.03s 11636KB
stdin
Standard input is empty
stdout
[[1, 2, 8], [1, 2, 4], [1, 1, 2], [1, 2, 2], [1, 1, 8], [1, 1, 4], [1, 3, 2], [1, 10, 8], [1, 10, 2], [1, 3, 8], [3, 2, 8], [3, 2, 4], [1, 10, 4], [2, 2, 2], [1, 3, 4], [3, 1, 2], [2, 1, 8], [2, 2, 8], [2, 2, 4], [3, 2, 2], [2, 3, 2], [3, 3, 2], [3, 10, 2], [2, 1, 4], [2, 1, 2], [3, 1, 8], [3, 10, 4], [2, 10, 4], [2, 3, 4], [3, 1, 4], [2, 10, 2], [2, 3, 8], [3, 10, 8], [3, 3, 8], [2, 10, 8], [3, 3, 4]]