3. 다중 순환

2023. 3. 30. 16:45·다양한 글들/자료구조와 알고리즘

5. 다중 순환

- 다중 순환이란

  • 순환 함수들은 호출이 발생할 때마다 몇 개의 순환 호출이 이루어지는가에 따라 선형 순환, 이진 순환 그리고 다중 순환으로 나눌 수 있음
  1. 선형 순환(linear recursion): 함수의 호출이 발생하면 최대로 하나의 순환 호출이 이루어지는 경우를 말함(팩토리얼, 거듭제곱)
  2. 이진 순환(binary recursion): 함수에서 두 개의 순환 호출이 발생하는 경우(피보나치 수열, 하오니 탑)
  3. 다중 순환(multiple recursion): 하나의 함수에서 두 개 이상의 순환 호출이 이루어지는 경우

- 영역 채색 문제

영역 채색(blob coloring), 연결 화소 분석법(connected component labeling): g흑과 백의 화소 값만을 갖는 이진 영상(binary image)에서 연결된 객체를 찾는 방법

  • 이진 영상을 스캔하다가 흰 화소를 만나면 어떤 색으로 칠함.
  • 그리고 이 화소와 인접한 네 방향의 이웃 화소에 대해 순환적으로 검사하면서 같은 색을 칠함 -> 즉, 4 방향으로 순환 호출을 하는 다중 호출 사례

<프로그램 2.5.1> 영역 채색 문제 프로그램

#include <cstdio>
#define WIDTH 20
#define HEIGHT 9

using namespace std;

// 순환 호출 함수 (다중 순환의 예)
void labelComponent(unsigned char img[HEIGHT][WIDTH], int x, int y, int label)
{
    if (x < 0 || y < 0 || x >= WIDTH || y >= HEIGHT) // 영상의 밖이면 return
        return;
    if (img[y][x] == 9) { // 처리 안된 전경 화소이면
        img[y][x] = label; // label로 화소 값을 바꾸고
        labelComponent(img, x - 1, y, label); // 순환 호출: 좌측 이웃화소
        labelComponent(img, x, y - 1, label); // 순환 호출: 상측 이웃화소
        labelComponent(img, x + 1, y, label); // 순환 호출: 우측 이웃화소
        labelComponent(img, x, y + 1, label); // 순환 호출: 하측 이웃화소
    }
}

// 이진 영상의 영역 채색(blob coloring) 함수
void blobColoring(unsigned char img[HEIGHT][WIDTH])
{
    int label = 1; // label은 1부터 시작함
    for (int y = 0; y < HEIGHT; y++) { // 영상의 모든 화소에 대해
        for (int x = 0; x < WIDTH; x++) {
            if (img[y][x] == 9) // 처리가 안된 전경 화소이면
                labelComponent(img, x, y, label++); // 연결화소 채색 시작
        }
    }
}

// 영상의 화소 값을 화면에 출력하는 함수
void printImage(unsigned char img[HEIGHT][WIDTH], char* msg)
{
    printf("%s\n", msg);
    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            if (img[y][x] == 0) {
                printf(".");
            } else {
                printf("%-1d", img[y][x]);
            }
        }
        printf("\n");
    }
    printf("\n");
}

// 주 함수
int main()
{
    // 입력 영상 : 자료 !
    unsigned char img[HEIGHT][WIDTH] = {
        0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 9, 9,
        9, 9, 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 9, 9,
        0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 9, 9,
        0, 9, 9, 9, 0, 0, 9, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 9, 9,
        0, 9, 0, 9, 0, 0, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 9, 9,
        9, 9, 0, 9, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9,
        9, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, 0,
        9, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, 0, 9, 9,
        0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 9, 9
    };

    printImage(img, (char*)"<Original image>");
    blobColoring(img);
    printImage(img, (char*)"<Labelled image>");
    return 0;
}

-> 입력 영상의 "자료!"란 글자의 각 연결된 부분들 (ㅈ, ㅏ, ㄹ, ㅛ, 느낌표(!)의 두 영역)이 각각의 객체가 되어 채색되었으며 전체 6개의 객체가 검출된 것을 알 수 있음.
-> 이 프로그램은 실제로 객체 영역의 크기가 크지 않은 경우 매우 안정적으로 실행됨
-> 영상의 크기가 크고, 객체 영역의 면적이 매우 넓은 경우 실행속도가 느려지며 심한 경우 스택 오버플로우가 발생할 수 있음.
-> 따라서, 일반적으로는 주사선 알고리즘(scanline algorithm)을 사용함, 반복문을 사용해서 코드가 매우 복잡하지만 처리시간이 빠르고, 영상의 크기와 상관없이 일정한 시간 안에 결과를 얻을 수 있음.

- 미로 탐색 문제

  • 미로 찾기 문제도 순환을 이용하여 구현할 수 있음
  • 어떤 위치에서 이웃하는 4 방향에 대해 순환 호출이 이루어지는 지 유의, 현재 위치가 출구의 위치와 동일하면 탐색 성공이며, 탐색이 성공하면 더 이상 순환 호출을 하지 않도록 done 변수를 true로 설정

<프로그램 2.5.2> 순환을 이용한 미로 탐색 프로그램

[Location2D.h]

struct Location2D{
    int row; // 현재 위치의 행 번호
    int col; // 현재 위치의 열 번호

    Location2D(int r = 0, int c = 0) {
        row = r;
        col = c;
    }
    
    void set(int r,int c){
        row = r;
        col = c;
    }

    // 위치 p가 자신의 이웃인지 검사하는 함수
    bool isNeighbor(Location2D &p){
        return ((row == p.row && (col == p.col - 1 || col == p.col + 1)) || (col == p.col && (row == p.row - 1 || row == p.row + 1)));
    }

    // 위치 p가 자심과 같은 위치인지를 검사하는 함수(연산자 오버로딩 사용)
    bool operator==(Location2D& p) { return row == p.row && col == p.col; }
};
#include "Location2D.h"
#include <cstdio> 
const int MAZE_SIZE = 6;

char map[MAZE_SIZE][MAZE_SIZE] = {
    { '1', '1', '1', '1', '1', '1' },
    { '0', '0', '1', '0', '0', '1' },
    { '1', '0', '0', '0', '1', '1' },
    { '1', '0', '1', '0', '1', '1' },
    { '1', '0', '1', '0', '0', 'x' },
    { '1', '1', '1', '1', '1', '1' }
};

bool isValidLoc(int r, int c){
    if(r<0 || c <0||r>=MAZE_SIZE||c>=MAZE_SIZE)
        return false;
    else
        return map[r][c] == '0' || map[r][c] == 'x';
}

Location2D locEntry, locExit; // 입구와 출구 위치
bool done = false; // 탐색 성공 여부

// 순환으로 구현한 미로 탐색 구현
void searchRecur(Location2D pt){
    printf("(%d,%d) ", pt.row, pt.col); // 현재 위치 화면에 출력
    if(done)    // 이미 탐색에 성공했다면 return
        return;
    if(pt == locExit){ // 현재 위치가 출구이면 성공
        done = true;
        return;
    }

    int r = pt.row;
    int c = pt.col;
    map[r][c] = '5';

    // 4방향 이웃에 대해 순환 호출
    if(isValidLoc(r-1,c))
        searchRecur(Location2D(r - 1, c));
    if(isValidLoc(r,c-1))
        searchRecur(Location2D(r, c - 1));
    if(isValidLoc(r+1,c))
        searchRecur(Location2D(r + 1, c));
    if(isValidLoc(r,c+1))
        searchRecur(Location2D(r, c + 1));
}

// 미로 탐색 프로그램 주 함수
int main(){
    locEntry.set(1, 0);
    locExit.set(4, 5);
    searchRecur(locEntry); // 미로 탐색 시작
    if(done)
        printf("\n ==> Find Exit.\n");
    else
        printf("\n ==> Not Find Exit.\n");

    return 0;
}

저작자표시

'다양한 글들 > 자료구조와 알고리즘' 카테고리의 다른 글

9. 기 수 정렬  (0) 2023.04.01
8. 힙 정렬  (0) 2023.04.01
2. 재귀를 활용한 계산  (0) 2023.03.30
1. 재귀(순환)  (0) 2023.03.23
7. 퀵 정렬 (Quick Sort)  (0) 2023.03.23
'다양한 글들/자료구조와 알고리즘' 카테고리의 다른 글
  • 9. 기 수 정렬
  • 8. 힙 정렬
  • 2. 재귀를 활용한 계산
  • 1. 재귀(순환)
smile blog
smile blog
건국대 첨단바이오공학부 & 컴퓨터공학부 BT & IT 기술로 희망을 꿈 꿉니당
  • smile blog
    스마일 블로그
    smile blog
  • 전체
    오늘
    어제
    • 분류 전체보기 (816)
      • 일상 생각들 (2)
      • 학과에 대해 (4)
        • 첨단바이오공학부 (4)
        • 컴퓨터공학부 (0)
      • -------- 프로젝트 -------- (0)
      • [DS] 토이 프로젝트 (1)
      • [Web, Game, XR] 토이 프로젝트 (11)
      • 경진대회 (1)
      • -------- 진로 -------- (0)
      • 생물정보학자 (18)
        • 데이터 과학이란? (0)
        • 되는 방법 (8)
        • 책 추천 (2)
        • 인강 (1)
        • 대학 (2)
        • 회사 (1)
        • 학원 (2)
        • 학회 (2)
      • 디지털 헬스케어 (72)
        • 방법 (8)
        • 생각들 (10)
        • 공부법 (4)
        • 책 추천 (2)
        • 학원 (2)
        • 참고 (2)
        • 대학 (3)
        • 회사 (3)
        • 인강 (2)
        • 게임 엔진들 (1)
        • 게임 프로그래머 개론 (2)
        • 게임 프로그래머 취업 전략 가이드 (7)
        • 취업 서류 (1)
        • 애정하는 게임들 (4)
        • XR 테크니컬 아티스트 (9)
        • 영화, 애니메이션 테크니컬 디렉터 (12)
      • -------- 기초 학문 -------- (0)
      • 생명과학 이야기 (2)
        • 대학 강의 (2)
      • 화학 이야기 (0)
      • 컴퓨터과학 이야기 (0)
      • 통계학 이야기 (0)
      • 수학 이야기 (1)
        • 공학 수학 (1)
      • 영어 이야기 (1)
      • 심리학 이야기 (7)
        • 현대인과 정신건강 (7)
      • -------- 컴퓨터 언어 -------- (0)
      • Python (3)
        • 나도코딩의 파이썬 입문 (1)
        • 파이썬 관련 정보 (1)
      • SQL (0)
      • C 언어 (32)
        • 혼자 공부하는 C언어 요약 (1)
        • [책 정리] 혼자 공부하는 C언어 (31)
      • C++ (33)
        • 명품 C++ 프로그래밍 요약 (1)
        • [책 정리] 명품 C++ 프로그래밍 (27)
        • C++ STL (0)
        • 뇌를 자극하는 C++ STL (5)
      • -------- 생명과학 -------- (0)
      • 생화학 (5)
        • 대학 강의 (5)
      • 분자세포생물학 (3)
        • 대학 강의 (3)
      • 유전자치료공학 (2)
        • 대학 강의 (2)
      • 생명정보학 (5)
        • 대학 강의 (5)
      • 약리학 (2)
        • 대학 강의 (2)
      • -------- 컴퓨터과학 -------- (0)
      • 자료구조와 알고리즘 (8)
        • 자료구조와 알고리즘의 정의 (3)
        • [책 정리] C언어로 쉽게 풀어쓴 자료구조 요약 (1)
        • [인강] 자료구조와 알고리즘 (2)
        • 코딩 테스트 대비하기! (1)
      • 컴퓨터 회로 (0)
      • 컴퓨터 구조 (43)
        • 컴퓨터 구조와 운영체제 요약 (1)
        • ---------------------------------------- (0)
        • [전공 책 정리] 컴퓨터 구조 및 설계 (1)
        • Ch1. 컴퓨터 추상화 및 관련 기술 (8)
        • Ch2. 명령어 : 컴퓨터 언어 (11)
        • Ch3. 컴퓨터 연산 (8)
        • Ch4. 프로세서 (11)
        • Ch5. 메모리 계층구조 (3)
        • Ch6. 병렬 프로세서 : 클라이언트에서 클라우드까지 (0)
      • 시스템 프로그래밍 (15)
        • [책 정리] 시스템 프로그래밍 유닉스 & 리눅스 (0)
        • [인강] 리눅스 시스템 프로그래밍 (2)
        • 리눅스에서 코딩이란? (8)
        • 대학교 강의 정리 (5)
      • 운영체제 (0)
      • 컴퓨터 네트워크 (37)
        • 모두의 네트워크 요약 (1)
        • [책 정리] 모두의 네트워크 (10)
        • ---------------------------------------- (0)
        • [전공 책 정리] 컴퓨터 네트워킹 하향식 접근 8판 (1)
        • Ch1. 컴퓨터 네트워크와 인터넷 (7)
        • Ch2. 애플리케이션 계층 (7)
        • Ch3. 트랜스포트 계층 (8)
        • Ch4. 네트워크 계층 : 데이터 평면 (3)
        • Ch5. 네트워크 계층 : 제어 평면 (0)
        • Ch6. 링크 계층과 근거리 네트워크 (0)
        • Ch7. 무선 및 이동 네트워크 (0)
        • Ch8. 컴퓨터 네트워크 보안 (0)
      • 데이터베이스 (1)
      • -------- 데이터과학 -------- (0)
      • 데이터 사이언스 (8)
        • 인강 (8)
      • 데이터 분석 (2)
        • 인강 (2)
      • 머신러닝 (2)
        • 대학 수업 (2)
      • 인공지능 (11)
        • 대학교 강의 정리 (10)
        • 인공지능 관련 정보 (1)
      • -------- +a -------- (0)
      • Visual Studio Community (7)
        • 설치법 (1)
        • 단축키 (1)
        • 오류 (5)
      • Visual Studio Code (0)
      • 노션 (1)
      • 깃허브 (7)
        • 깃허브 사용법 (5)
        • 유니티, 언리얼 & 깃허브 (1)
        • 깃허브 주의사항 (1)
      • 챗GPT 활용법 (0)
      • 기타 feat. 프로그래밍 (7)
        • 프로그래머로 살아남기 (5)
        • 코딩 vs 프로그래밍 (1)
        • 애플 비전 프로 (1)
      • 메타버스 (5)
      • -------- 예술 -------- (0)
      • 음악 (1)
      • 미술 (0)
      • -------- XR -------- (0)
      • 유니티 이야기 (23)
        • 레트로의 유니티 게임 프로그래밍 에센스 요약 (4)
        • 유니티 관련 정보 (1)
        • 유니티 디버깅 (13)
        • 유니티 인강 (3)
        • 대학교 게임 프로그래밍 강의 (2)
      • 언리얼 이야기 (0)
        • 인생 언리얼 교과서 요약 (0)
      • 컴퓨터 그래픽스 (6)
        • OpenGL (6)
      • 가상현실 & 증강현실 (4)
        • 유니티 vr (4)
      • HCI 와 UI UX (7)
        • [책 정리] HCI 개론 (6)
      • -------- Design -------- (0)
      • 캐릭터 (1)
        • 모델링 (0)
        • 리깅 (1)
      • 포토샵 (3)
      • 3ds Max (7)
      • Maya (9)
        • 블로그 (1)
        • 인강 (6)
        • 대학교 (2)
      • Blender (14)
        • 책 (1)
        • 인강 (7)
        • 기타 (3)
        • 대학교 (3)
      • 아트 작업물들 (2)
      • 에셋 사이트 (1)
      • -------- 건강관리 -------- (0)
      • 건강관리 ft. 정현 (12)
        • 목 디스크 (2)
        • 눈 관리 (2)
        • 일상생활 습관 (6)
        • 일상생활 꿀팁 (2)
        • 사무직 꿀팁 (0)
      • 헬스의 정석 ft. 정현 (28)
        • 헬스와 건강 (8)
        • 헬스 구체화 정보 (6)
        • 헬스 유튜버 (1)
        • 헬스 서적 (1)
        • 도전 바디프로필! (11)
        • 헬스장 패션 (1)
      • -------- etc -------- (0)
      • 진로 관련 잡다한 글들 (34)
        • 진도율 (9)
        • 진로 관련 글들 (15)
        • 학교 강의 관련 글들 (10)
      • 인생 꿀 Tip (23)
        • 컴퓨터 초기 설정 (9)
        • 원격 데스크톱 (1)
        • 노트북 발열 (1)
        • 전자기기 (2)
        • 중고기기 팔기 (1)
        • 아이패드 필기 어플 (1)
        • 에어팟 (1)
        • 커피 (1)
        • 맥북 (1)
        • lg 그램 (1)
        • 검색엔진에서 내 티스토리 검색 (1)
        • hELLO 다크 모드 없애기 (1)
        • 인터넷 연결 문제 (1)
        • 키보드 문제 해결 (1)
      • 유튜브 (3)
      • 청춘 그리고 추억 (1)
      • 인생 계획표 (2)
        • 2024년 2학기 (1)
        • 2024년 여름방학 (0)
        • 2024년 1학기 (0)
        • 2023년 겨울방학 (1)
      • 다양한 글들 (98)
        • C++ STL (6)
        • Win32 API (24)
        • PushPush 게임 (13)
        • 컴퓨터구조 (1)
        • 자료구조와 알고리즘 (50)
        • 게임의 정의 (3)
        • 영상 회사 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

    • Dream
    • 코딩을 시작한 이유
    • 나를 소개합니다!
    • 블로그 공부법
    • IT & 가치 있는 일들
  • 인기 글

  • 태그

    연산자
    첨단바이오공학부
    유니티
    스택
    포인터
    생물정보학
    알고리즘
    블렌더
    C++ STL
    컴퓨터구조
    함수
    리눅스
    생명공학
    코드잇
    데이터과학
    리눅스 터미널
    C언어
    의생명공학
    배열
    unity
    컴퓨터 네트워크
    건국대
    명령어
    의생명공학과
    심리학
    데이터사이언스
    AI
    인공지능
    자료구조
    C++
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
smile blog
3. 다중 순환
상단으로

티스토리툴바