3. ※개인별업무
김창헌 회의록작성 및 보고서 작성, 일정 계획
김성현 관련사항 조사 및 복잡도계산
고정현 관련사항 조사 및 복잡도계산
이성욱 프로그램 설계 및 알고리즘 구상
성주희 프로그램 설계 및 알고리즘 구상
※일정계획
4월9일 업무분담 및 문제파악
4월14일 조사내용 정리 및 이해, 소스 및 보고서 초안 작성
4월 16일 소스 문제점 및 해결방안 토의
4. ※회의록
회의일시 2012년 4월 9일 조 A2 작성자 김창헌
참석자 김창헌, 김성현, 고정현, 이성욱, 성주희
내용 비고
1.조원별 업무분담
조원별 업무분담을 하여 각자 맡은 임무를 수행 해 오기로 함.
2.일정 계획
이번 주말에 한번 조원 전체가 모여서 소스 와 보고서 초안 구상 하
기로 함.
3.보고서 계획
자료조사를 한 조원들에게 참고한 자료들과 출처를 조장에게 보내주
어 보고서 작성하기로 함.
소스초안 및 문제점을 주말에 모여서 토의하고 그 내용들을 보고서
회의내용
에 작성하기로함.
4.알고리즘 계획
소스 구상하는 조원들이 대략적인 알고리즘을 구상해와서 주말에 모
여서
조원들과 함께 토의 하여 알고리즘을 완성 시키기로 함.
5. 회의일시 2012년 4월 16일 조 A2 작성자 김창헌
참석자 김창헌, 김성현, 고정현, 이성욱, 성주희
내용 비고
1.조원별 업무 파악
조장은 마지막회의로서 현재 프로젝트의 진행상황을 명확히 설명하고
최종 보고서에 들어갈 내용들을 정리함.
설계 조원들은 소스의 문제점을 설명하고 어떻게 해결할것인지에 대
해 모든 조원들과 함께 토의를 함.
자료조사 조원들은 과제1을 풀어 와서 이번 회의시간에 설명을 함.
2.일정 확인
이번 회의를 마친 뒤 소스를 완성 시킨후 각 조원들이 이해가 잘 안
되는 부분을 설계조원에게 물어보기로 하여 조원 전부가 소스를 이해
하기로 함.
회의내용 지금까지 했던 내용들을 토대로 보고서를 완성시키기로 함.
3.문제점 파악/해결법 토의
4.보고서 확정
조원 개인별의 업무자료들을 조장에게 넘겨 주고 조장이 정리하기로
함.
처음에 구상했던 알고리즘을 바탕으로 소스를 구현 시키고
그에 해당하는 내용들을 보고서에 넣기로 함.
6. ※기본자료
'셈의 기본 원리' 라고 부른다.
여기에는 사건과 집합, 합의 법칙, 곱의 법칙 등이 들어간다.
예를 들어, 많은 경우, 가능한 모든 경우의 수를 세는 문제들(counting problem)은 곱셈법칙(product rules)의 직
접적인 응용으로 풀 수가 있다. 즉, 어떤 임의의 사건이 n1가지 경우로 일어날 수 있고, 두 번째 사건은 n2가지로
일어날 수 있으며, 이런 식으로 해서x k 번째 사건에서는 nk 가지의 경우가 있다고 가정하자. 그러면 총 사건들은
정확하게 n1 x n2 x ․…․ x nk개의 경우 안에서 발생할 수 있다. 이러한 법칙을 셈의 기본 원리라고 한다.
비반복추출
k-순열에서는 집합 S로부터 k개를 선택하는데 반복을 허락하지 않는다. 하지만 선택된 원소들의 순서는 목
록에서 구별한다. 이 목록을 집합 S로부터의 k-순열(k-permutations)이라고 부른다. 다음은 S={x, y, z, w}의 3-순
열이다.
xyz xzy yxz yzx zxy zyx
xyw xwy yxw ywx wxy wyx
xzw xwz zxw zwx wxz wzx
yzw ywz zyw zwy wyz wzy
n개의 원소를 가진 집합으로부터의 k-순열의 수는 P(n, k) 혹은 라는 기호를 사용한다. 셈의 기본 원리
를 이용하여, P(n, k)를 계산해 보자.
n n-1 n-2 … n-k+1
1 2 3 … k
첫 번째 칸에는 S의 n개의 원소들 중 어떤 것이든지 들어갈 수 있다. 반복이 허락되지 않기 때문에 두 번째 칸에는
단지 n-1개의 원소들 중에서 선택할 수 있다. 이런 식으로 해서 k 번째 칸에서는 (n-k+1)개의 원소 중에서 선택해
야 한다. 따라서,
P(n, k) = n․(n-1)․(n-2)․…․(n-k+1)
위 공식을 factorial을 이용해 다시 쓰면,
P(n, k) = n! / (n-k)! for k≤n (i.e. n-k≥0)
집합 S로부터 k개를 선택하는데, 반복을 허락하지 않고 순서에 상관없이 구성이 같은 원소는 똑같이 취급하는 경우
의 목록을 k-조합(k-combinations)라고 한다. 집합 S의 k-조합은 S의 부분 집합과 정확히 일치한다. 다음은 S={x,
y, z, w}의 3-combinations다.
xyz xyw xzw yzw
n개의 원소를 가진 집합에서의 k-조합의 수를 나타내는 기호는 C(n, k) 혹은 이다. C(n, k)를 구하기
위해서, 우선 각각의 k-조합에 대해 많은 수의 k-순열이 존재한다는 것을 알 수 있다. 예를 들어 3-조합 xyz에 대
해서는 x, y, z에 대한 6개의 순열이 존재한다. 각각의 k-조합에 대하여 k-순열에 해당하는 k! = k․(k-1)․…․1이 존
재한다. 따라서 다음과 같은 공식으로 정리할 수 있다.
P(n, k) = C(n, k)․k!
C(n,k)에 대해서 다시 정리하면,
C(n, k) = n! / (n-k)!k!
반복추출
k-samples는 집합 S로부터 k개를 선택하는 작업중 하나이다. 반복을 허락하지만, 다른 순서의 똑같은 원소
- 6 -
7. 는 목록(list)에서 구별된다. 이런 종류의 목록을 k-sample이라고 부른다. 다음은 S={x, y, z, w}이고 k=3일 때,
k-samples이다.
xxx xxy xxz xxw xyx xyy xyz xyw
xzx xzy xzz xzw xwx xwy xwz xww
yxx yxy yxz yxw yyx yyy yyz yyw
yzx yzy yzz yzw ywx ywy ywz yww
zxx zxy zxz zxw zyx zyy zyz zyw
zzx zzy zzz zzw zwx zwy zwz zww
wxx wxy wxz wxw wyx wyy wyz wyw
wzx wzy wzz wzw wwx wwy wwz www
n개의 원소를 포함하고 있는 집합 S로부터 k-samples의 수를 계산하기 위하여 셈의 기본 원리(The
Fundamental Principle of Counting)를 칸을 채우는(filling slots) 아이디어에 적용한다. S의 어떤 원소든지 첫
번째 칸(first slot)에 올 수 있다. k-samples는 반복을 허락하기 때문에 나머지 칸에도 역시 S의 어떤 원소도 모
두 넣을 수 있다. 때문에 각각의 칸을 채우는 방법은 n가지씩 존재한다. k개의 칸이 있기 때문에 모든 칸을 채우는
방법은 총 nk이다. 따라서 S로부터 nk개의 k-samples가 존재한다.
n n n … n
1 2 3 … k
집합 S로부터 k개를 선택할 경우 반복은 허락하지만, 순서에 상관없이 같은 원소는 동일하게 취급하는데, 이 경우
의 목록을 집합 S로부터의 k-selections라고 한다. k-selections는 여러 번 동전 던지기의 결과를 알아보기 등에
유용하다. 아래 집합은 {x, y, z, w}로부터의 3-selection의 예를 나타낸 것이다.
xxx xxy xxz xxw xyy xyz xyw xzw xww
yyy yyz yyw yzz yzw yww zzz zzw www
- 7 -
8. ※과제1
방법1
*가장 큰 수가 나올 때까지 찾아서 이 카드를 테이블 위에 앞면이 위
로 오도록 놓는다. 처음부터 다시 그 다음 큰 수를 찾아서 그 카드
위에 놓는다. 이 과정을 모든 카드를 찾을 때까지 반복한다. 정렬되었는가?
->> 정렬이 됨.
*최악의 경우는 어떻게 초기화 되었을 경우인가
가장 큰 수가 나와야 되는데 뒤집을 때마다 작은 수가 나오는 경우의 수 이다.
10부터 시작해서 29까지 나오고, 다음 10부터 시작해서 28나오는 경우이다.
최악의 경우는 이런 초기화 상태에서 나온다.
*최선의 경우는 어떻게 초기화 되었을 경우인가
가장 큰 수가 나와야 되는데 뒤집을 때마다 큰 수가 나오는 경우의 수이다.
제일 처음 뒤집을 때29, 그다음 뒤집을 때 28이 나오는 경우의 수이다.
최선의 경우는 이런 초기화 상태에서 나온다.
*시간 복잡도는 얼마인가
제일 큰 수를 찾는 경우의 수이니 20번을 반복해야 한다.
그러므로 시간 복잡도는 n²이 된다.
방법 2
*카드를 두 뭉치로 나눈다. 하나는 첫 수가 1인 것이고
다른 하나는 첫 수가 2인 것이다. 각 뭉치를 방법1을
사용하여 두 번째 수를 정렬한다. 첫 번째 뭉치를 두
번째 뭉치 위에 놓는다. 정렬되었는가
정렬이 됨.
*카드의 비교 수는 얼마인가
최선의 경우=20번
최악의 경우=110번
이 나온다.
방법 3
*카드의 두 번째 수를 이용하여 10개의 뭉치(0~9)로
나눈다. 이제 두 번째 수가 0인 뭉치를 집어서 첫 번째
수를 보고 두 뭉치로 나누고 뒤집어 놓는다. 두 번째
수가 1인 뭉치를 집어서 다시 첫 번째 수를 보고 두 뭉
치로 나누어 앞의 뭉치 위에 뒤집어 놓는다. 모든 카드
에 대해 반복한다.
*카드의 비교 횟수는 얼마인가?
카드의 비교횟수는 10번이다.
- 8 -
9. ※알고리즘
{A,B,C,D,F},3가 들어올 경우
1. A,B,C,D,F를 배열에 넣는다. A B C D F
2.A,B를 한 문자로 본다. AB C D F
3. 출력 ABC , ABD, ABF
4. A와 C를 한문자로 보고 D와 F와 함께 출력.
5. 첫 문자(0번에 있는)가 끝나고 나면 B와 C를 한
문자로 보고 출력.
6. 계속 옮겨가면서 반복.
- 9 -
10. ※최종소스
#include <stdio.h>
int main()
{
char arr[200];
char ch;
int ar=0,j,k,i,num,po,x,cnt=0,brt=0; // 사용할 배열 변수들을 선언
for(;;) // 문자 입력 받는다.
{
ch=getchar();
if(ch == 'n') break; // 엔터시 종료
else if(ch >= 65 && ch <=90 || ch >=97 && ch <=122 ) // 영어 일시 배열로 넣음
{
arr[ar]=ch;
ar++;
}
else if(ch >= 48 && ch <= 57) // 숫자를 입력받음
{
num=ch-48;
}
}
po=num-1;
for(i=0;i<ar;i++) // 출력부분
{
for(x=0;x<ar;x++)
{
for(j=i;j<i+num-1;j++)
{
printf("%c" , arr[j]); // 입력받은 숫자가 3이라면 2번 돌게된다.
}
printf("%c" , arr[po]); // 1씩증가하여 집합의 젤마지막을 하나씩 출력한다.
if(i+num == ar) // 마지막일시 더 돌지 않고 종료
{
- 10 -
12. ※출력결과
※참고문헌 및 출처
URL
math.ewha.ac.kr/~skim/FiniteMath/4-comb.hwp
http://www.winapi.co.kr/
참고서적
이산 수학론 – 임해철,정균락 공저(정익사) p282 ~ p292
※반성
세 번째 프로젝트를 마무리 하면서 처음에 프로젝트과제를 수행할 때를 생각해보니 어떤 식으로 프로젝트를 진행
해나가야 할지 감이 잡히는 것 같다.혼자서 다 하기엔 벅차지만 조원들끼리 업무분담을 하여 진행 하면서 개인마다
이해력 차이가 있어 시간이 좀 오래 걸리긴 했지만 서로서로 도움이 되가는 모습이 뭔가 멋있었다. 각자 프로젝트
마다 업무를 바꾸어 가며 하기 때문에 다음 프로젝트의 업무가 무엇이든지 어떤 식으로 풀어나가야 할지를 알게 되
었다.
아직 C언어가 미숙한 조원들이 있기 때문에 많은 공부와 연습이 필요하다고 느꼈다. 그리고 매 수업시간에 회의를
할 때 자신의 업무는 수행해왔지만 정리가 되지 않아서 짧은 시간에 모든 조원들이 이해하기에 부족해서 다음 프로
젝트부터는 좀 더 자신의 업무에 대해 사명감을 가지고 해야겠다고 느꼈다.
- 12 -