How fast can we sort?




                          C3
             조원 : (조장) 11최수영
                      09권용현
                      09홍준표
                      10권희준
                      11전승협
<요약 및 문제 파악>
집합과 그 집합에서 뽑아낼 부분집합의 원소 개수를 입력받아서, 그 개수만큼의
원소를 가진 부분집합들을 모두 출력하는 프로그램 작성



<연구 배경>
프로젝트 진행을 위해 symmetric, reflexive, irreflexive ,행렬 의 기본개념을
연구하였다.


• The Fundamental Principle of Counting
덧셈 법칙 k개의 가능성이 있는 일이 독립적으로 시행될 수 있고, 또 각각의
경우의 수가 m1, m2, ..., mk 일 때, 가능한 전체의 경우의 수는 모두 m1 + m2
+ ... + mk이다. 이것을 합의법칙(the addition principle)이라고 한다.
• k-sample
S가 공집합이 아닌 집합일 때, 중복을 허용하고 순서를 고려하여 r개를
선택한 부분집합을 S의 r표본(r-sample)이라 한다.
S개의 원소의 개수를 n이라 하고, r표본의 개수를 구하여봅시다.
먼저 순서를 고려하므로 r개의 방을 먼저 순서대로 나열하고
□□□ ... □
각 방에는 S의 원소 n개 중에서 임의로 한 개를 선택할 수 있으므로 곱의
법칙에 대하여 n×n×...×n=nr
이며, 이것을 중복순열이라고 부른다.
• k-selection
원소의 개수가 n인 집단으로부터 중복을 허용하여 r개를 고르는 것을
r-선택(r-selection)이라 하고, 이를 중복조합이라고 한다.
이 때, r은 n보다 커도 무방하다. 또, r-선택 중에서 원소가 모두 다른 것을
우리는 r-조합이라고 부른다.
• k-permutations
집합 S의 r-sample 중에서 원소가 모두 다른 것들을 우리는
r-순열(r-permutation)이라고 부른다. 또, S의 원소의 개수가 r인 경우에
S의 r-순열은 단순히 순열(permutation)이라고 한다.
• k-combinations
n개의 원소를 갖는 집합 S로부터 r개의 서로 다른 원소를 순서를 고려하지
않고 선택한 집합을 S의 r-조합(r-combination) r-선택 중에서 원소가 모두
다른 것을 우리는 r-조합이라고 부른다.
<프로젝트 진행일정>
과제수행기간:   ___2___일    총____5___시간

        1day (4/11)                    2day (4/18)
*문제에 대한 분석                    *초안에 대한 문제파악 및 대책 마련 토의 (최
(앞으로 나가야 할 방향에 대한 토의)         종 작성 방향 결정)
*업무 분담                        *과제1 문제 해결방안 토의
자료조사팀 : 과제1에 대한 방법 조사         *코딩에 대한 문제점 보안으로 최종 코딩 완성
알고리즘팀 : 프로젝트 초안 짜기.           *각 조원들의 자료를 모아 최종 보고서 작성




<업무 분담>

                                l 최종보고서 작성
          최수영 <조장>
                                l 과제 1 수행
              5



                                l 토의 첫날, 용어 정리

            권용현                 l 과제 1 에 대한 조사
              5                 l 과제 1 수행



                                l 프로젝트 코딩
            홍준표
                                l 과제 1 수행
              5




                                l 과제 1 에 대한 조사
            권희준
                                l 과제 1 수행
              4




                                l 프로젝트 코딩
            전승협
                                l 과제 1 수행
              5
<프로젝트 진행과정>

<과제1>
질문 : 10~29까지 두 자리 정수가 적힌 20장의 카드가 있다고 하자. 카드를 무작위로 섞었
다. 가장 큰 수가 나올 때까지 찾아서 이 카드를 테이블 위에 앞면이 위로 오도록 놓는다.
이 과정을 모든 카드를 찾을 때까지 반복한다.
1. 전체 카드를 몇 번 보아야 하는가?
2. 시간 복잡도?


해결 방법 :
1. 우선 2,3,4개의 카드를 비교하는 형태를 파악하여 규칙을 찾습니다.
v 2개의 카드를 정렬하기 위해 카드 사이에 1번의 비교를 해야 합니다.
v 3개의 카드를 정렬하기 위해 카드 사이에 비교하는 횟수는?
  = 아직 정렬되지 않은 3개의 카드 사이에 2번의 비교 후 가장 큰 수를 맨 뒤에 위치
    시킵니다.
  = 정렬된 카드를 제외한 2개의 카드 사이에 1번의 비교를 합니다.
  = 그러면 3개의 카드 사이의 비교 횟수는 1+2=3이 됩니다.
v 4개의 카드를 정렬하기 위해 카드 사이에 비교하는 횟수는?
  = 아직 정렬되지 않은 4개의 카드 사이에 3번의 비교 후 가장 큰 수를 맨 뒤에 위치
    시킵니다.
  = 남은 3개의 카드 사이에 2번의 비교를 하고, 남은 카드 중 큰 수를 뒤쪽으로 위치
    시킵니다.
  = 다시 남은 2개의 카드 사이에 1번의 비교를 하고, 정렬합니다.
  = 그러면 4개의 카드 사이의 비교 횟수는 1+2+3=6이 됩니다.
v 마찬가지로 5개 사이에는 1+2+3+4=10회 비교 6개 사이에는 1+2+3+4+5=15회 비교이
  므로,
                                               
                                                         
v n개의 카드 사이의 비교 횟수는      ⋯            가 되는 것이지
                                                  
  요. (정렬 방법 중 “선택 정렬”이라는 방법이 있는데, 그 방법입니다.)
                                               ×    
v 그러면 20개의 카드 사이의 비교 횟수는       ⋯      회입니
                                                    
  다.


2. 시간 복잡도 : 일반적인 다항식에서의 시간 복잡도는 최고차항을 통해 따질 수 있습니다.
예를 들어 n에 대한 함수식 중           의 시간 복잡도는 최고차항만 남기
면 되므로,    이 됩니다.
한편 최고차항에 계수가 있는 경우입니다. n에 대한 함수식 중      의 시간 복잡도
는 최고차항의 계수를 삭제하여    이 됩니다.
                     
이 문제에서 총 비교 수는       이므로, 시간 복잡도는    입니다.
                          
이렇게 풀었지만 교수님이 제시한 방법대로도 해결해보았습니다.



방법1

전체카드를 몇 번 보아야 하는가?


최대210번, 최소20번


최대-> 1 .가장 큰 수가 나올 때까지 뒤집어 본다. 그 수를 뒤집어 놓는다.       20번
        2. 두 번째 큰 수가 나올 때까지 뒤집어 본다. 그 수를 뒤집어 놓는다.    19번
        ...
        3, 가장 작은 수가 나올 때 뒤집어 본다. 1번


    20+19+...+2+1 = 210번


최소-> 1. 첫 장을 뒤집었을 때 가장큰수가 나온다. 1번
        2. 두 번째 장을 뒤집었을 때 두 번때 큰수가 나온다. 1번
        ...
        3. 마지막 장을 뒤집었을 때 가장 작은수가 나온다. 1번


    1+1+...+1+1 = 20번


n = 카드 수일 때
최악의 경우는 어떻게 초기화 되었을 경우인가?
n(n+1)/2


최선의 경우는 어떻게 초기화 되었을 경우인가?
n


방법2
130번

1. 20장의 카드를 다 보고 십의 자리수가 1인 수과 2인수로 나눈다.     20번
2. 각 뭉치를 방법1로 정렬한다 55+55 = 110번


방법3
30번

1, 카드를 다 보고 두 번째 수가 같은 카드를 모은다.       20번

2. 10개의 뭉치를 한번씩 보고 첫 번째 수가 1인지 2인지 확인하고 뒤집어 놓는다.           10번
<프로그램 완성>


#include <stdio.h>
#include <stdlib.h>
#include <string.h>


/*
     배열 출력
*/
void print(char dar[], int N)
{
     int i;
     for(i=0; i < N; i++) {
          printf("%c",dar[i]);
     }
                                      printf(",");
}


/*
     주어진 문자들을 중복없이 num 개 조합
     dar : 조합한 문자들의 배열
     N : 조합할 개수
     num : 조합한 개수
     arr : 뽑히지 않은 m개 문자들의 배열
*/
void combi_nodup(char dar[], int N, int num, char arr[], int m)
{
     if(num == N) {// 다 뽑았으면 출력
          print(dar,N);
     }
     else if(N-num <= m){
          int i;


          for(i=0; i < m; i++)
          {
               dar[num] = arr[i];                        // i 번째 요소 값을 뽑고,
               combi_nodup(dar,N,num+1,arr+i+1,m-i-1);     // 이후 문자들에서 나머지를
뽑음.
          }
}
}


/////////////////////////////////////////////////////////////////////
int main()
{
    char dar[26];
    int m=0;
                                    int i=0,k=0;
                                    char arr[100];
                                    char in[100];
                                    int num;
                                    char nn[2];


                                    gets(in);
                                    for(;;)
                                    {
                                        if(in[i]>=97 && in[i]<=122)
                                        {arr[k]=in[i];
                                        m++;
                                        k++;}
                                        i++;
                                        if(in[i]==NULL)
                                        {break;}
                                    }
                                    i=0;
                                    k=0;
                                    for(;;)
                                    {
                                        if(in[i]>48 && in[i]<57)
                                        {nn[k]=in[i];
                                        k++;}
                                        i++;
                                        if(in[i]==NULL)
                                        {break;}
                                    }
                                    num=atoi(nn);
                                    i=0;
                                    k=0;


    combi_nodup(dar,num,0,arr,m);
}
<과제를 마치며>
이번 과제는 과제 1, 과제 2 로 나뉘어 두 개가 나왔기에 할 일이 많아 보였지만, 분업과
협력을 통하여 과제를 해결하였기에 훨씬 수월하게 과제를 끝낼 수 있었다.




<출처>
이산수학 수학으로 이해하는 디지털논리 – 박주미 지음

2012 Dm C3 03

  • 1.
    How fast canwe sort? C3 조원 : (조장) 11최수영 09권용현 09홍준표 10권희준 11전승협
  • 2.
    <요약 및 문제파악> 집합과 그 집합에서 뽑아낼 부분집합의 원소 개수를 입력받아서, 그 개수만큼의 원소를 가진 부분집합들을 모두 출력하는 프로그램 작성 <연구 배경> 프로젝트 진행을 위해 symmetric, reflexive, irreflexive ,행렬 의 기본개념을 연구하였다. • The Fundamental Principle of Counting 덧셈 법칙 k개의 가능성이 있는 일이 독립적으로 시행될 수 있고, 또 각각의 경우의 수가 m1, m2, ..., mk 일 때, 가능한 전체의 경우의 수는 모두 m1 + m2 + ... + mk이다. 이것을 합의법칙(the addition principle)이라고 한다. • k-sample S가 공집합이 아닌 집합일 때, 중복을 허용하고 순서를 고려하여 r개를 선택한 부분집합을 S의 r표본(r-sample)이라 한다. S개의 원소의 개수를 n이라 하고, r표본의 개수를 구하여봅시다. 먼저 순서를 고려하므로 r개의 방을 먼저 순서대로 나열하고 □□□ ... □ 각 방에는 S의 원소 n개 중에서 임의로 한 개를 선택할 수 있으므로 곱의 법칙에 대하여 n×n×...×n=nr 이며, 이것을 중복순열이라고 부른다. • k-selection 원소의 개수가 n인 집단으로부터 중복을 허용하여 r개를 고르는 것을 r-선택(r-selection)이라 하고, 이를 중복조합이라고 한다. 이 때, r은 n보다 커도 무방하다. 또, r-선택 중에서 원소가 모두 다른 것을 우리는 r-조합이라고 부른다. • k-permutations 집합 S의 r-sample 중에서 원소가 모두 다른 것들을 우리는 r-순열(r-permutation)이라고 부른다. 또, S의 원소의 개수가 r인 경우에 S의 r-순열은 단순히 순열(permutation)이라고 한다. • k-combinations n개의 원소를 갖는 집합 S로부터 r개의 서로 다른 원소를 순서를 고려하지 않고 선택한 집합을 S의 r-조합(r-combination) r-선택 중에서 원소가 모두 다른 것을 우리는 r-조합이라고 부른다.
  • 3.
    <프로젝트 진행일정> 과제수행기간: ___2___일 총____5___시간 1day (4/11) 2day (4/18) *문제에 대한 분석 *초안에 대한 문제파악 및 대책 마련 토의 (최 (앞으로 나가야 할 방향에 대한 토의) 종 작성 방향 결정) *업무 분담 *과제1 문제 해결방안 토의 자료조사팀 : 과제1에 대한 방법 조사 *코딩에 대한 문제점 보안으로 최종 코딩 완성 알고리즘팀 : 프로젝트 초안 짜기. *각 조원들의 자료를 모아 최종 보고서 작성 <업무 분담> l 최종보고서 작성 최수영 <조장> l 과제 1 수행 5 l 토의 첫날, 용어 정리 권용현 l 과제 1 에 대한 조사 5 l 과제 1 수행 l 프로젝트 코딩 홍준표 l 과제 1 수행 5 l 과제 1 에 대한 조사 권희준 l 과제 1 수행 4 l 프로젝트 코딩 전승협 l 과제 1 수행 5
  • 4.
    <프로젝트 진행과정> <과제1> 질문 :10~29까지 두 자리 정수가 적힌 20장의 카드가 있다고 하자. 카드를 무작위로 섞었 다. 가장 큰 수가 나올 때까지 찾아서 이 카드를 테이블 위에 앞면이 위로 오도록 놓는다. 이 과정을 모든 카드를 찾을 때까지 반복한다. 1. 전체 카드를 몇 번 보아야 하는가? 2. 시간 복잡도? 해결 방법 : 1. 우선 2,3,4개의 카드를 비교하는 형태를 파악하여 규칙을 찾습니다. v 2개의 카드를 정렬하기 위해 카드 사이에 1번의 비교를 해야 합니다. v 3개의 카드를 정렬하기 위해 카드 사이에 비교하는 횟수는? = 아직 정렬되지 않은 3개의 카드 사이에 2번의 비교 후 가장 큰 수를 맨 뒤에 위치 시킵니다. = 정렬된 카드를 제외한 2개의 카드 사이에 1번의 비교를 합니다. = 그러면 3개의 카드 사이의 비교 횟수는 1+2=3이 됩니다. v 4개의 카드를 정렬하기 위해 카드 사이에 비교하는 횟수는? = 아직 정렬되지 않은 4개의 카드 사이에 3번의 비교 후 가장 큰 수를 맨 뒤에 위치 시킵니다. = 남은 3개의 카드 사이에 2번의 비교를 하고, 남은 카드 중 큰 수를 뒤쪽으로 위치 시킵니다. = 다시 남은 2개의 카드 사이에 1번의 비교를 하고, 정렬합니다. = 그러면 4개의 카드 사이의 비교 횟수는 1+2+3=6이 됩니다. v 마찬가지로 5개 사이에는 1+2+3+4=10회 비교 6개 사이에는 1+2+3+4+5=15회 비교이 므로,       v n개의 카드 사이의 비교 횟수는      ⋯          가 되는 것이지   요. (정렬 방법 중 “선택 정렬”이라는 방법이 있는데, 그 방법입니다.)  ×     v 그러면 20개의 카드 사이의 비교 횟수는       ⋯      회입니  다. 2. 시간 복잡도 : 일반적인 다항식에서의 시간 복잡도는 최고차항을 통해 따질 수 있습니다. 예를 들어 n에 대한 함수식 중           의 시간 복잡도는 최고차항만 남기 면 되므로,    이 됩니다. 한편 최고차항에 계수가 있는 경우입니다. n에 대한 함수식 중      의 시간 복잡도 는 최고차항의 계수를 삭제하여    이 됩니다.        이 문제에서 총 비교 수는       이므로, 시간 복잡도는    입니다.   
  • 5.
    이렇게 풀었지만 교수님이제시한 방법대로도 해결해보았습니다. 방법1 전체카드를 몇 번 보아야 하는가? 최대210번, 최소20번 최대-> 1 .가장 큰 수가 나올 때까지 뒤집어 본다. 그 수를 뒤집어 놓는다. 20번 2. 두 번째 큰 수가 나올 때까지 뒤집어 본다. 그 수를 뒤집어 놓는다. 19번 ... 3, 가장 작은 수가 나올 때 뒤집어 본다. 1번 20+19+...+2+1 = 210번 최소-> 1. 첫 장을 뒤집었을 때 가장큰수가 나온다. 1번 2. 두 번째 장을 뒤집었을 때 두 번때 큰수가 나온다. 1번 ... 3. 마지막 장을 뒤집었을 때 가장 작은수가 나온다. 1번 1+1+...+1+1 = 20번 n = 카드 수일 때 최악의 경우는 어떻게 초기화 되었을 경우인가? n(n+1)/2 최선의 경우는 어떻게 초기화 되었을 경우인가? n 방법2 130번 1. 20장의 카드를 다 보고 십의 자리수가 1인 수과 2인수로 나눈다. 20번 2. 각 뭉치를 방법1로 정렬한다 55+55 = 110번 방법3 30번 1, 카드를 다 보고 두 번째 수가 같은 카드를 모은다. 20번 2. 10개의 뭉치를 한번씩 보고 첫 번째 수가 1인지 2인지 확인하고 뒤집어 놓는다. 10번
  • 6.
    <프로그램 완성> #include <stdio.h> #include<stdlib.h> #include <string.h> /* 배열 출력 */ void print(char dar[], int N) { int i; for(i=0; i < N; i++) { printf("%c",dar[i]); } printf(","); } /* 주어진 문자들을 중복없이 num 개 조합 dar : 조합한 문자들의 배열 N : 조합할 개수 num : 조합한 개수 arr : 뽑히지 않은 m개 문자들의 배열 */ void combi_nodup(char dar[], int N, int num, char arr[], int m) { if(num == N) {// 다 뽑았으면 출력 print(dar,N); } else if(N-num <= m){ int i; for(i=0; i < m; i++) { dar[num] = arr[i]; // i 번째 요소 값을 뽑고, combi_nodup(dar,N,num+1,arr+i+1,m-i-1); // 이후 문자들에서 나머지를 뽑음. }
  • 7.
    } } ///////////////////////////////////////////////////////////////////// int main() { char dar[26]; int m=0; int i=0,k=0; char arr[100]; char in[100]; int num; char nn[2]; gets(in); for(;;) { if(in[i]>=97 && in[i]<=122) {arr[k]=in[i]; m++; k++;} i++; if(in[i]==NULL) {break;} } i=0; k=0; for(;;) { if(in[i]>48 && in[i]<57) {nn[k]=in[i]; k++;} i++; if(in[i]==NULL) {break;} } num=atoi(nn); i=0; k=0; combi_nodup(dar,num,0,arr,m); }
  • 8.
    <과제를 마치며> 이번 과제는과제 1, 과제 2 로 나뉘어 두 개가 나왔기에 할 일이 많아 보였지만, 분업과 협력을 통하여 과제를 해결하였기에 훨씬 수월하게 과제를 끝낼 수 있었다. <출처> 이산수학 수학으로 이해하는 디지털논리 – 박주미 지음