We will pass a policy list to the function. Policy list contains a list of entities.We need to return list of entities that cannot talk to each other. Eg. policy1 = [['A'], ['B', 'C'], ['D']] This policy1 means that B-C traffic allowed rest all is denied. We need to return list of entities that cannot talk to each other. block_list = [('A', 'C', 'D'), ('A', 'B', 'D')]
Similarly for policy2 = [['A', 'B'], ['B', 'C'], ['D']] where B can communicate directly with A,C but A and C cannot communicate with each other and cannot communicate D. D cannot communicate with each other(A,B,C). block_list = [('A', 'C', 'D'), ('B', 'D')]
Similarly for policy3 = [['A'], ['B', 'C'], ['D', 'E']]; A cannot communicate with any other entity. B and C can communicate with each other but not with others(A,D,E), block_list = [('A', 'C', 'D'), ('A', 'B', 'D'), ('A', 'C', 'E'), ('A', 'B', 'E')]
Similary for policy4 = [['A'], ['B', 'C'], ['D', 'E'], ['F'], ['G']] ; block_list =[('A', 'B', 'E', 'F', 'G'), ('A', 'C', 'D', 'F', 'G'), ('A', 'C', 'E', 'F', 'G'), ('A', 'B', 'D', 'F', 'G')]
I wrote code
from itertools import product
def generate_block_list(policy):
block_set = set()
# Generate block list for each entity in the policy
for entity in policy:
other_entities = [e for e in policy if e != entity]
# Generate all possible combinations of the current entity with other entities
combinations = list(product(entity, *other_entities))
unique_combinations = [tuple(sorted(set(combination))) for combination in combinations]
# Add combinations to the block list
block_set.update(unique_combinations)
block_list = list(block_set)
return block_list
# Example usage:
policy1 = [['A'], ['B', 'C'], ['D']]
block_list1 = generate_block_list(policy1)
print("\nPolicy:", policy1)
print("Block List:", block_list1)
policy2 = [['A', 'B'], ['B', 'C'], ['D']]
block_list2 = generate_block_list(policy2)
print("\nPolicy:", policy2)
print("Block List:", block_list2)
policy3 = [['A'], ['B', 'C'], ['D', 'E']]
block_list3 = generate_block_list(policy3)
print("\nPolicy:", policy3)
print("Block List:", block_list3)
policy4 = [['A'], ['B', 'C'], ['D', 'E'], ['F'], ['G']]
block_list4 = generate_block_list(policy4)
print("\nPolicy:", policy4)
print("Block List:", block_list4)
I got output :
Policy: [['A'], ['B', 'C'], ['D']] Block List: [('A', 'C', 'D'), ('A', 'B', 'D')]
Policy: [['A', 'B'], ['B', 'C'], ['D']] Block List: [('A', 'C', 'D'), ('A', 'B', 'D'), ('B', 'D'), ('B', 'C', 'D')]
Policy: [['A'], ['B', 'C'], ['D', 'E']] Block List: [('A', 'C', 'D'), ('A', 'B', 'D'), ('A', 'C', 'E'), ('A', 'B', 'E')]
Policy: [['A'], ['B', 'C'], ['D', 'E'], ['F'], ['G']] Block List: [('A', 'B', 'E', 'F', 'G'), ('A', 'C', 'D', 'F', 'G'), ('A', 'C', 'E', 'F', 'G'), ('A', 'B', 'D', 'F', 'G')]
It is failing for policy2 where entities are common. Help me fix. Or suggest a better way to do. Block List: [('A', 'C', 'D'), ('A', 'B', 'D'), ('B', 'D'), ('B', 'C', 'D')] is wrong it should be Block List: [('A', 'C', 'D'), ('B', 'D')]
I'm not sure why you're not using the built-in combination method and only calculating certain combinations and not others, but something like this should work:
from itertools import combinations
def all_combinations(lst):
for i in range(2,len(lst)+1):
for combination in combinations(lst,i):
yield set(combination)
def is_allowed(combination,allowed_connections):
for connection in allowed_connections:
if connection == combination:
return True
return False
policy = [['A'], ['B', 'C'], ['D']]
all_nodes = [item for group in policy for item in group]
allowed_connections = [set(group) for group in policy if len(group)>1]
block_list = [combination for combination in all_combinations(all_nodes) if not is_allowed(combination,allowed_connections)]
print(block_list)
this will block everything that is not explicitly allowed.