web-dev-qa-db-fra.com

Nombre de combinaisons inférieur à 100

J'ai 13 listes appartenant à différents groupes:

  • Groupe A (liste 1)

  • Groupe B (Liste 2), (Liste 3), (Liste 4), (Liste 5), (Liste 6)

  • Groupe C (Liste 7), (Liste 8), (Liste 9), (Liste 10), (Liste 11)

  • Groupe D (liste 12), (liste 13)

Tous les groupes ensemble doivent totaliser 1

  • Le groupe A peut prendre des valeurs de 0 à 0,7

  • Le groupe B peut prendre des valeurs de 0 à 0,6

  • Le groupe C peut prendre des valeurs de 0 à 0,9

  • Le groupe D peut prendre des valeurs de 0 à 0,1

Je veux trouver toutes les combinaisons différentes que ces listes peuvent faire sans dépasser les limites de leur groupe.

Par exemple:

si pour une combinaison élément List2 = 0.6, List3, List4, List5 et List6 doivent être 0

Y a-t-il un moyen simple de le faire? (Je peux utiliser R ou Python)

(Les listes prennent des valeurs de 0 à la limite de leur groupe avec un incrément de .1)

# i.e. 
List1=[0.0,0.1,0.2,...,0.7]
List2 = [0.0,0.1,0.2,...,0.6]
# etc.
7

Réponse modifiée en fonction de la nouvelle question


Vous pouvez utiliser des compréhensions de liste, qui sont raisonnablement rapides. Le code suivant n'a pris que quelques secondes sur mon PC. J'ai utilisé l'idée de John Coleman pour trouver d'abord les combinaisons possibles de sommes par groupe. J'ai également utilisé des nombres entiers plutôt que des flottants. Pour transformer les solutions au problème comme indiqué dans la question, divisez chaque valeur de liste par 10.

from itertools import product

A = range(8)  # 1 value from this group
B = range(7)  # 5 values from this group (with replacement)
C = range(10) # 5 values from this group (with replacement)
D = range(2)  # 2 values from this group (with replacement)

# use John Coleman's idea:
# first find all possible combinations of sums per group
groupsums = [sums for sums in product(A, B, C, D) if sum(sums) == 10]
print(len(groupsums))  # -> 95

def picks(maxi, n):
    """Returns list of combinations of n integers <= maxi 
       that sum to maxi."""
    return [combi for combi in product(range(maxi + 1), repeat=n)
                  if sum(combi) == maxi]

# make list of lists that each have 13 items from the above ranges, 
# with constraints as stated in the question
samples = [[a, b0, b1, b2, b3, b4, c0, c1, c2, c3, c4, d0, d1] 
           for a, b, c, d in groupsums
           for b0, b1, b2, b3, b4 in picks(b, 5)
           for c0, c1, c2, c3, c4 in picks(c, 5)
           for d0, d1 in picks(d, 2)]

# show the first 5 and last 5 results
for i in range(5):
    print(samples[i])
print('...')
for i in range(1, 6):
    print(samples[-i])

# show the number of solutions
print(len(samples))
95
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 7, 0, 1]
...
[7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[7, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[7, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[7, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
[7, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
313027
2
Arne