이산수학 프로그래밍
(python)포함-배제 원칙(The principle of Inclusion-exclusion)
komizke
2022. 11. 20. 18:00
1. 개념
포함-배제 원칙은 합집합의 원소의 개수를 구하는 것과 동일하다고 볼 수 있다.
<집합의 개수에 따른 공식>
- 집합 2개: |A∪B| = |A| + |B| - |A∩B|
- 집합 3개: |A∪B∪C| = |A| + |B| + |C| - |A∩B| - |A∩C| - |B∩C| + |A∩B∩C|
- 집합 4개: |A∪B∪C∪D | = |A| + |B| + |C| + |D| - |A∩B| - |A∩C| - |B∩C| - |A∩D| - |B ∩D| - |C∩D| + |A∩B∩C| + |A∩B∩D| + |A∩C∩D| + |B∩C∩D| - |A∩ B∩C∩D|
위의 공식에서 나타나듯이 집합의 개수를 늘려가면서 교집합 연산을 하는 것을 확인할 수 있다.
부호는 양수, 음수를 번갈아 가며 나타난다.
그러므로 집합 n개에 대하여 아래와 같은 공식이 성립한다.
2. 코드 구성
사용자는 만들고 싶은 집합의 개수와 각 집합 별로 구성 원소를 입력하고, 그에 해당하는 공식과 결괏값을 얻을 수 있는 프로그램.
2 - 1. makeSet()
입력 받은 집합의 개수만큼 각 집합의 이름을 설정하고 원소들을 입력받아 집합을 구성하는 함수
#make union acording to input number
def makeSet(lst1, lst2, n):
#make a name of set from 'A'~
for i in range(n):
character = chr(65+i) #using ASCII CODE
lst1.append(character)
#input elements for each set
for i in range(n):
print("Enter the elements of set %c."%lst1[i])
parted_set = set(map(int, input().split())) #input numbers in a line
lst2.append(parted_set)
2 - 2. showPIE()
위의 개념에서의 공식을 적용하여 집합의 개수만큼 그 공식을 출력해주고, 결괏값을 출력한다.
이 코드에서 특징점은 포함-배제 원칙 공식은 교집합의 연산이 중복되지 않기에 combination(집합 리스트, 선택할 개수) 함수를 이용하여 중복을 피하였다.
#show result
def showPIE(lst1, lst2, n):
global res #variavle for result value
res = 0
#showing │A∪B∪C....∪│
for i in range(n):
if i == 0:
print('│', end='')
print(lst1[i], end='')
if i < n - 1:
print('∪', end='')
if i == n-1:
print('│=', end='')
#showing result
for i in range(n):
setting_set = list(combinations(lst1, i + 1)) #calculating combination for the number(i+1)
renew_set = []
for e in setting_set:
renew_set.append(''.join(e)) #using join function for looking string form
for j in range(len(renew_set)): #repeat the number of subsets
temp = {} #temp variable for saving intersection set
#deciding a sign according to even or odd number of set
if (i+1) % 2 == 0:
print('-', end='')
elif (i+1) % 2 != 0:
print('+', end='')
for k in range(len(renew_set[j])): #repeat as many as the tpye of sets
if k == 0:
print('│', end='')
idx = ord(renew_set[j][k]) % 65 #using ASCII and index
temp = lst2[idx]
else:
idx = ord(renew_set[j][k]) % 65
temp = temp & lst2[idx] #intersection operation
print(renew_set[j][k], end='')
if k == len(renew_set[j]) - 1: #calculating result value
if(i+1) % 2 == 0:
res -= len(temp)
else:
res += len(temp)
print('│', end='')
break
print('∩', end='')
2 - 3. main
print('Enter the number of sets you want to make.')
n = int(input())
set_name = [] #list for name of sets
elements_set = [] #list for elements for each set
makeSet(set_name, elements_set, n)
print("Formula:", end='')
showPIE(set_name, elements_set, n)
print("= %d"%res)
2 - 4. 출력 화면
Enter the number of sets you want to make.
3
Enter the elements of set A.
1 2 3 8 9 10
Enter the elements of set B.
3 4 5 6 7 8 9
Enter the elements of set C.
7 8 9 10 11
Formula:│A∪B∪C│=+│A│+│B│+│C│-│A∩B│-│A∩C│-│B∩C│+│A∩B∩C│= 11