How to make sure a pair of items in np.random.choice don’t appear together in a loop?

I’m currently trying to run a MonteCarlo simulation without replacement, using np.random.choice, but there are certain items in the list which cannot appear together. For example, if I have a list of five items: RO, MI, VE,NA, SI, and each loop produces a group of four items, RO can appear with VE, MI, or NA, but it cannot appear with SI, on each iteration. So a loop like: [RO,MI,VE,NA] is correct But not: [RO,MI,SI,NA] as SI appears in the same group as RO. This is the code I’m currently using (which is producing the incorrect grouping):

np.random.seed(42)
portfolio=[]
for i in range(0,10000):
    port_gar = list(np.random.choice(cities, size=4, replace=False, p=cities_prob))
    portfolio.append(port_gar)
print(portfolio)

I’m at a loss as to what would do and any help would be appreciated. Thanks!

Answer

Without knowing more about the constraints on which cities can appear in the list, the simplest solution might be to randomly generate cities until you have enough of them that are valid. For example:

def check_valid(port_gar):
    is_valid = True
    
    if 'RO' in port_gar:
        is_valid = is_valid and ('NA' not in port_gar and 'VE' not in port_gar)
    if 'NA' in port_gar:
        is_valid = is_valid and 'VE' not in port_gar
    
    # Add other checks for constraints here

    return is_valid

portfolio = []
while len(portfolio) < 10000:
    port_gar = list(np.random.choice(cities, size=4, replace=False, p=cities_prob))
    if check_valid(port_gar):
        portfolio.append(port_gar)

print(portfolio)

This is definitely not the most efficient implementation, but if the number of samples is relatively small (in this case, 10000) and the number of cities is large, then the performance should be fine.