0

I am trying to solve a mathematics combinatorics question in python in which we select a committee of 5 people with female majority from a group of 8 men and 9 females. My code:

import random
people=["m1", "m2", "m3","m4", "m5", "m6" , "m7","m8", "l1", "l2", "l3", "l4", "l5", "l6", "l7", "l8", "l9"]
combinations=[]

for g in range(10000):
    a=random.sample(people, k=5)
    b=a.count("l1")
    b+=a.count("l2")
    b+=a.count("l3")
    b+=a.count("l4")
    b+=a.count("l5")
    b+=a.count("l6")
    b+=a.count("l7")
    b+=a.count("l8")
    b+=a.count("l9")
    if b>=3:
        if a in combinations:
            pass
        else:
            combinations.append(a)

print (len(combinations))

But for some reason this is including repeated groups. Which means my last few lines of code are not working correctly.

hjjinx
  • 55
  • 6
  • also make `combinations` a `set` or your code is going to be sloooow – Jean-François Fabre May 27 '18 at 19:28
  • your `b=a.count("l1") ...` block would be better with `b = sum(x[0]=='l' for x in a)` – Jean-François Fabre May 27 '18 at 19:28
  • I'm still very much a beginner to Python and I don't understand what you're saying. I'm sorry if I cause you any trouble – hjjinx May 27 '18 at 19:29
  • you're not causing trouble. If you were you'd have gotten downvotes – Jean-François Fabre May 27 '18 at 19:30
  • 1
    What exactly are you trying to do? Your code tries to make 10,000 random attempts to find appropriates committees and counts the number of successes. Would you prefer to just find a fixed number of random successful committees? (Pythons `combinations` and `product` functions could help here.) If so, do you want the "random" to be uniform over all successful committees? Or are you trying to calculate the probability of a random committee of five of those people having a majority of females? – Rory Daulton May 27 '18 at 19:39
  • @RoryDaulton oh sorry for the late reply I didn't see your comment. Actually as I said I am a beginner to Python and I'm trying to make use of the few commands that I know of. I didn't know that those existed. To be honest I am starting to post my questions online not just to get my query solved but also I learn much more stuff like you just told me combinations and product exist for doing that. However I got the answer from this also on 100,000 attempts it gives a constant answer every time I run it. – hjjinx May 27 '18 at 20:16

1 Answers1

1

the main issue is that in takes order into account. In your list of lists,

['l1', 'l2', 'l6', 'm6', 'm8'] != ['l2', 'l1', 'l6', 'm6', 'm8']

So the trick is to apply a sort to the random pick, so you won't get the same group in different orders (read: How to efficiently compare two unordered lists (not sets) in Python?).

Also, using in in a list is a performance issue. Better use a set for fast lookup, but in that case, convert your list to tuple (like a list, but immutable thus hashable) to be able to put it in the set.

Last trick: your counting is clumsy. Count the elements which start by l by checking if the first letter is l, in a generator comprehension fed to the built-in sum function.

import random
people=["m1", "m2", "m3","m4", "m5", "m6" , "m7","m8", "l1", "l2", "l3", "l4", "l5", "l6", "l7", "l8", "l9"]
combinations=set()

for g in range(10000):
    a = tuple(sorted(random.sample(people, k=5)))
    b = sum(x[0]=="l" for x in a)
    if b>=3:
        combinations.add(a)

print (len(combinations))
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • Thanks for that! I still haven't really got to using those commands since I'm a beginner and don't even know what a tuple is. But now I know the problem and will look it up. – hjjinx May 27 '18 at 19:41