■ 선교사와 식인종 문제* 문제:- 세 명의 선교사와 세 명의 식인종이 강의 한 쪽에 있다.- 강에는 한 명 또는 두 명을 태울 수 있는 보트가 있다.- 모든 사람을 강의 반대편으로 보내야 한다.- 강의 어느 한 쪽이던 식인종의 숫자가 선교사의 숫자를 넘으면 안된다.* 풀이:1. 초기상태선교사를 x, 식인종을 y로 두고 배의 상태 z 로 정한다.처음 초기상태는 3명의 선교사와 3명의 식인종과 출발지점에 배가 있으므로,xxx yyyz으로 표현할 수 있다.2. 목표상태모든 사람(3명의 선교사와 3명의 식인종)이 강을 건너가 있는 상태이어야 하고, 배가 그쪽에 정박해있어야 한다. 즉,xxx yyyz상태로 되어야한다.3. 연산자 및 트리위의 문제에 조건 중에 강에는 한 명 또는 두 명을 태워야 하므로, x, y, xx, xy, yy로 배로 옮겨서 갈 수 있다. 하지만 조건 중에도 강의 한쪽에 식인조의 숫자가 선교사보다 많다면 선교사가 잡아먹히므로 조건에 위배된다. 따라서 쉽게 트리로 표현한다면,xxx yyyz(0)먹 힘먹 힘xx yyyxz(1)xxx yyyz(1)x yyyxxz(1)xx yyx yz(1)xxx yyyz(1).........연산자는 초기의 (s는 숫자)인 상태를 만족하면서, (n은 현재 건녀편 최대수) Move (,)함수를 이용해 초기에 Move() 함수가 실행되면 PC값이 1(강을 건너가진 상태의 배) , 다시 Move() 함수가 실행되면 0(초기 상태의 배) 로 변형되면서, Move() 함수의 실행 횟수에 따라 값이 변하게 된다. 즉, Move()함수가 홀수번 실행되면 1, 짝수번 실행되면 0인 상태가 된다. (Lx의 수 - Ly의 수)0 ,(L은 강을 건너기 전 상태)(Rx의 수 - Ry의 수)0을 만족하는 상태가 되면서 연산이 이루어져야 할 것이다.4. 해결책xx yyx yz→xxx yyzy→xxxyyyz→xxx yzyy→x yxx yyz→xx yyzx y→yyxxx yz→yyyzxxx→yxxx yyz→yyzxxx y→xxx yyyz즉, 다시 문장으로 표현한다면,1. 선교사 1명과 식인종 1명만 배를 타고 강을 건넌다.2. 선교사 1명이 배를 타고 돌아온다.3. 식인종 2명이 배를 타고 강을 건넌다.4. 식인종 1명이 배를 타고 돌아온다.5. 선교사 2명이 배를 타고 강을 건넌다.6. 선교사 1명과 식인종1명이 배를 타고 돌아온다.7. 선교사 2명이 배를 타고 강을 건넌다.8. 식인종 1명이 배를 타고 돌아온다.
■ man1. 효과 : 명령어의 도움말을 보여준다.2. 사용방법 : man [명령어]3. 실행화면■ cd1. 효과 : 디렉터리를 이동할 때 사용한다.2. 사용방법 : cd [디렉터리]3. 실행화면■ cp1. 효과 : 파일이나 디렉터리 복사2. 사용방법 : cp [옵션] [source] [target]-i : 복사대상 파일이 있을 경우, 사용자에게 실행여부 확인-f : 복사대상 파일이 있을 경우, 확인없이 강제실행-r : 디렉터리를 복사할 경우, 하위 디렉터리와 파일 전부 복사-v : 복사진행 상태 출력-d : 복사대상 파일이 심볼릭 파일이면, 심볼릭 정보 유지한 상태로 복사-p : 파일의 퍼미션을 그대로 유지한 상태로 복사-a : 원본 파일의 속성, 링크정보를 유지한 상태로 복사3. 실행화면■ mv1. 효과 : 파일의 이동2. 사용방법 : mv [옵션] [source] [target]-i : 이동할 위치에 동일한 파일이 있을 경우 확인-u : 이동할 파일이 이동할 위치에 있는 파일보다 최근이면 이동-b : 대상 파일이 이미 있어, 지워지는 것을 대비해 백업파일 생성-f : 대상 파일이 있어도 사용자에게 확인하지 않고 처리-v : 파일 옮기는 과정을 출력해줌-S : -b 옵션을 이용하여 백업할 경우, 백업파일에서 사용할 파일의 이름 꼬리문자 지정3. 실행화면■ rm1. 효과 : 파일 및 디렉터리 삭제2. 사용방법 : rm [옵션] 디렉터리or파일-f : 파일/디렉터리 삭제 시 사용자에게 어떻게 할지 묻지않음-r : 일반파일 지움. 디렉터리일 경우 하위폴더도 모두 삭제3. 실행화면■ mkdir1. 효과 : 디렉터리를 생성한다.2. 사용방법 : mkdir [옵션] 디렉터리-m 퍼미션 : 디렉터리의 권한을 지정할 수 있다. 기본 값은 755이다.-p : 필요한 경우 상위 디렉터리까지 만든다. 만약 ~/a/b 라는 경로에 c라 는 디렉터리를 만들기 위해서 mkdir ~/a/b/c 를 입력했을 때 ~/a/b 의 경로가 없다면 디렉터리가 생성되지 않는다.하지만 이 옵션을 사용 하면 경로가 없을 경우 상위 디렉터리까지 생성한다.3. 실행화면■ rmdir1. 효과 : 비어있는 디렉터리를 삭제한다.2. 사용방법 : rmdir [옵션] 디렉터리-p : 상위 경로도 지운다. 단, 상위경로는 비어있는 상태이어야 한다.3. 실행화면■ more1. 효과 : 화면 단위로 분할해서 출력해주는 역할2. 사용방법 : more [옵션] 파일명-n : 여기서 n 은 숫자를 의미하며, 숫자는 출력 윈도우의 행수를 지정한 다.-c : 위에서부터 한 행씩 지운 후, 한 행씩 출력한다. 보통은 화면 전체를 지운 후 각 행을 출력하기 시작한다. 특정한 터미널을 위해 사용한다.-d : [SPACEBAR] q 키를 누르라는 프롬프트를 출력한다.-f : 화면의 행이 아닌 논리적인 행수를 계산한다. 보통은 긴 칼럼의 행은 화면에서 행 바꿈을 하여 새로운 행으로 계산된다. ?f 옵션을 사용하면 이런 행은 계산하지 않는다.-s : 여러 개의 빈 공백 행은 하나로 취급한다.-p : 스크롤하지 않는다. 대신 화면을 지우고 출력한다.-u : 밑줄 치기를 금지한다.3. 실행화면■ cat1. 효과 : 파일의 내용을 화면에 출력한다.2. 사용방법 : cat [옵션] 파일-b : 줄 번호를 화면 왼쪽에 나타낸다. 공백은 제외한다.-e : 제어 문자를 ^ 형태로 출력하면서 각 행의 끝에 $ 를 추가한다.-n : 줄 번호를 화면 왼쪽에 나타낸다. 공백을 포함한다.-s : 중복되고 겹치는 빈 행은 하나의 빈 행으로 처리한다.-v : 탭[TAB] 과 행 바꿈 문자를 제외한 제어 문자를 ^ 형태로 출력한다.-E : 각 행마다 끝에 % 문자를 출력한다.-T : 탭(TAB) 문자를 출력한다.3. 실행화면■ pwd1. 효과 : 현재 위치한 디렉터리의 절대경로를 출력한다.2. 사용방법 : pwd3. 실행화면■ find1. 효과 : 특정한 파일을 찾는 명령어2. 사용방법 : find [시작 디렉터리] [각종 문법]주어진 디렉터리에 [각종 문법]에 해당하는 내용과 일치하는 파일을 찾아 보여준다.부모 디렉터리에서부터 시작해서 하위 디렉터리에 있는 모든 파일들에 대해서 검색하며, 시스템내의 모든 파일들에 대해서 찾고자 할 때는 [시작 디렉터리]를 / 로 지정한다.-name “문자열” : 파일 이름이 문자열과 일치하는 파일을 찾는다.-user “유저이름” : 특정 소유자의 소유권인 파일을 찾을 때 사용한다.-perm “퍼미션” : 명시된 퍼미션으로 된 파일을 찾는다.-exec [사용할 명령] : 해당 문법들로 검색된 파일을 입력 값으로 해서 명령을 수행한다.find 가 검색해 낸 파일의 이름을 인수로 사용하고 싶다면 그 위치에 {} 를 사용한다.-type ? : 형태가 같은 파일을 찾는다. 물음표(?) 부분에 디렉터리는 d, 파이프는 p, 심볼릭 링크는 l, 소켓은 s, 블록 파일은 b, 일반 파일은 f 등의 기호를 사용한다.-links ? : 특정 개수의 링크를 가진 파일을 찾는다. 물음표 부분에 링크의 숫자를 표기한다.-size ? : 파일의 크기가 일치하는 것을 검색한다. 파일 크기는 블록단위로 물음표 부분에 지 정한다. 한 블록은 512바이트로 내정되어 있지만, 블록 숫자 뒤에 단위로 k 자를 붙이면 1KB 크기의 블록 숫자로 간주된다.-atime ? : 최근 몇 일내에 액세스한 파일을 검색한다. 날짜 수는 ? 에 명시한다.
■ 유닉스/리눅스 설치1. VMware를 실행한다.2. 가상머신 새로 만들기를 클릭한다. 다음 그림과 같이 차례대로 진행한다.3. “가산머신을 실행합니다” 를 선택한다.4. boot : _ 에 커서가 깜빡거리는데 여기서 엔터를 눌러주면 자동으로 설치가 된다.(Tip. VMware를 안에 클릭하면 활성화되서 마우스를 움직여도 VMware 밖으로 나오지 않을때는Ctrl + Alt를 동시에 누르면 마우스 커서가 빠져나온다.)5. 중간에 CD Disk를 검사할 것이냐고 Ok // Skip 메뉴가 나오는데 OK를 해도 상관은 없지만 시간이 오래걸리므로 Skip을 한다.- 파티션 설정 (15GB 기준)새로 생성 버튼을 통해 다음과 같이 파티션을 만든다./: 1500/boot: 300/usr: 6000/var: 800/swap: 1024 (시스템 메모리 X 2)/home: 나머지- Boot Loader : GRUB으로 설정하고 다음을 누른다,7. 다음을 누르면 자동으로 설치되고 리눅스(CentOS)가 설치완료된다.■ 리눅스 명령어 실행 및 설명1. passwd패스워드를 지정하는 명령어이다. 문법은 ‘ passwd [user] ’ 이다.슈퍼유저(or # 루트계정)은 다른 계정의 비밀번호를 변경할 수 있지만 일반유저($)는 자신의 비밀번호만 관리할 수 있다. 인자값 없이 passwd 만 쓸 경우 현재 로그인 되어있는 계정의 비밀번호를 변경하는 것이다.변경한 비밀번호 값은 /etc/shadow 파일에 저장된다.2. ifconfig현재 접속한 서버의 IP주소와 MAC주소, 마스크 주소 등의 정보를 알 수 있게 해준다.3. whoami // whowhoami 는 현재 로그인한 계정의 아이디 확인 방법의 명령어이다.who는 whoami보다 더 많은 정보를 출력해준다. 즉, 현재 서버에 로그인한 아이디(UID정보) 와장치명(pts/*), 접속한 일과시간정보, 서버에 접속하기 전의 IP주소를 나타낸다.4. cal달력을 출력해주는 명령어이다. 형식은 cal [-13smjyV] [[month] year] 이고, [-13smjyV]은 옵션인데 어떻게 달력을 출력하기 원하는지에 따라 각각의 옵션형태를 주면 된다. [ ] 은 생략가능하고, 다른 옵션값을 사용하지 않고 기본적인cal 만 사용하면 현재 년도와 달의 형태를 보여준다.5. clear현재 창에 나온 텍스트를 깔끔하게 없애주는 역할이다.6. ls // ls -al (ll)현재 위치에 존재하는 디렉터리와 파일들을 보여준다. ls -al(혹은 ll )명령어를 쓰게 되면퍼미션/서브디렉토리수/소유자/소유그룹/용량/생성날짜/파일 또는 디렉토리명형태로 출력된다.
■ 상태묘사방법 및 연산자, 평가함수, 틱택토의 알파베타 가지치기 설명상태 p에 대한 평가 함수 e(p)라고 하자.만일 p가 양쪽 모두에게 이기는 상태가 아니라면,e(p)= (MAX 에게 가능한 행, 열, 대각선의 수) - (MIN 에게 가능한 행, 열, 대각선의 수)만일 p가 MAX 가 이기는 상태라면,e(p) = ∞ ( ∞ 는 아주 큰 양수를 의미함)만일 p가 MIN 이 이기는 상태라면,e(p) = -∞즉, 만일 p가 다음과 같다면,OXe(p) = 6 ? 4 = 2 가 된다.자식 노드들을 생성할 때는 대칭성을 고려한다. 그러면 다음의 상태들은 모두 동일한 것으로 간주된다.OXOXXOXO게임 초기에는 대칭성 때문에 분기 계수가 작게 되고, 나중에는 가능한 상태가 적기 때문에 분기 계수가 작게 된다. MAX상태의 트리로 표현하자면,시작노드1-11-2xxx01-20-1-121oxoxoxoxoxoxoxxo100-1xoxooxox처음 MAX예제의 트리의 한 부분을 위 그림 에 다시 나타내었다.깊이우선탐색을 사용하며, 노드가 생성될 때마다 e(p)가 계산된다고 가정하자. 또한 어떤 노드가 전달 값을 받을 수 있게 되자마자 전달 값이 지정된다고 하자.노드는 현재 전달 값이 ?1 이다. 알파 값의 제한은 ?1이며, 그보다 작은 값을 가질 수는 없지만, 더 큰 수는 가질 수 있다.첫 번째 자식 노드가 생성되었을 때, 베타값이 ?1이라고 하면 ?1보다 작을 수는 있지만, 더 클 수는 없다. 즉, 정리해서 말하자면,- MAX 노드의 알파 값은 (시작 노드를 포함하여) 절대 감소되지 않는다.- MIN 노드의 베타 값은 절대 증가하지 않는다.이러한 제약조건 때문에, 다음과 같은 규칙에 의하여 탐색을 중단할 수 있다.1. 조상 MAX 노드의 알파 값보다 작거나 같은 베타 값을 갖는 MIN 노드 아래에서는 탐색을 중단할 수 있다. 이 MIN 노드의 최종 전달 값은 현재의 베타 값으로 지정한다. 이 값은 완전한 최대최소 탐색을 수행했을 때 얻어지는 값과는 다를 수도 있지만, 그 값을 사용해도 결과는 같은 행동을 최상으로 선택하게 된다.2. 조상 MIN 노드의 베타값보다 크거나 같은 알파값을 갖는 MAX 노드 아래에서는 탐색을 중단할 수 있다. 이 MAX 노드의 최종 전달값은 현재의 알파값으로 지정한다.탐색이 진행되는 동안 알파 값과 베타 값은 다음과 같이 계산된다.- MAX 노드의 알파값은 자식 노드의 전달값 중 현재까지 가장 큰 값이 된다.- MIN 노드의 베타값은 자식 노드의 전달값 중 현재까지 가장 작은 값이 된다.탐색이 규칙 1 에 의해 중단되면 알파 절단 (alpha cut-off) 이 일어났다고 말한다. 탐색이 규칙 2 에 의해 중단되면 베타 절단 (beta cut-off) 이 일어났다고 말한다. 알파값과 베타값을 기억하면서 절단을 수행해 가는 모든 과정을 일반적으로 알파 베타 방법 (alpha-beta procedure) 라고 한다. 이 과정은 시작 노드의 모든 자식 노드들이 최종적인 전달값을 갖게 되면 종료하며, 그리고 나면 최상의 행동은 가장 높은 전달값을 갖는 자식 노드를 만드는 것이 된다. 이 방법을 적용하면 항상 같은 깊이까지 기본적인 최대최소 방법으로 탐색을 수행했을 때 찾아지는 행동과 같은 수준의 행동을 찾게 된다.+1시작 노드ㅁ : MAXO : MIN0 -3 +3 -3 -2 +2 -5 0 +1 -3 -5 -3 2 3 -3 -2 0 4 -1 -1 -3 -2아래의 숫자는 평가함수 값이고, X표시 된 것은 가지치기가 일어난 곳이다.■ 알파베타 가지치기-휴리스틱 알고리즘 사용한 소스코드#include #include #define String_Length 80#define Squares 9typedef char Square_Type;typedef Square_Type Board_Type[Squares];const Square_Type Empty = ' 'const int Infinity = 1;const int Maximum_Moves = Squares;int Total_Nodes;#define Possible_Wins 8const int Three_in_a_Row[Possible_Wins][3] = {{ 0, 1, 2 },{ 3, 4, 5 },{ 6, 7, 8 },{ 0, 3, 6 },{ 1, 4, 7 },{ 2, 5, 8 },{ 0, 4, 8 },{ 2, 4, 6 }};const double Heuristic_Array[4][4] = {{ 0.1, -0.6, -0.8, -0.9 },{ 0.6, 0.1, 0.1, 0.1 },{ 0.8, 0.1, 0.1, 0.1 },{ 0.9, 0.1, 0.1, 0.1 }};typedef struct {int Square;int Heuristic;} Move_Heuristic_Type;void Initialize(Board_Type Board) {int I;for (I = 0; I < Squares; I++)Board[I] = Empty;}Square_Type Winner(Board_Type Board) {int I;for (I = 0; I < Possible_Wins; I++) {Square_Type Possible_Winner = Board[Three_in_a_Row[I][0]];if (Possible_Winner != Empty &&Possible_Winner == Board[Three_in_a_Row[I][1]] &&Possible_Winner == Board[Three_in_a_Row[I][2]])return Possible_Winner;}for (I = 0; I < Squares; I++)if (Board[I] == Empty)return Empty;return 'C'}Square_Type Other(Square_Type Player) {return Player == 'X' ? 'O' : 'X'}void Play(Board_Type Board, int Square, Square_Type Player) {Board[Square] = Player;}void Print(Board_Type Board) {int I;for (I = 0; I < Squares; I += 3) {if (I > 0)printf("---+---+---n");printf(" %c | %c | %c n", Board[I], Board[I + 1], Board[I + 2]);}printf("n");}int Evaluate(Board_Type Board, Square_Type Player) {int I;int Heuristic = 0;for (I = 0; I < Possible_Wins; I++) {int J;int Players = 0, Others = 0;for (J = 0; J < 3; J++) {Square_Type Piece = Board[Three_in_a_Row[I][J]];if (Piece == Player)Players++;else if (Piece == Other(Player))Others++;}Heuristic += Heuristic_Array[Players][Others];}return Heuristic;}int Best_Move(Board_Type Board, Square_Type Player, int *Square, int Move_Nbr,int Alpha, int Beta) {int Best_Square = -1;int Moves = 0;int I;Move_Heuristic_Type Move_Heuristic[Squares];Total_Nodes++;for (I = 0; I < Squares; I++) {if (Board[I] == Empty) {int Heuristic;int J;Play(Board, I, Player);Heuristic = Evaluate(Board, Player);Play(Board, I, Empty);for (J = Moves-1; J >= 0 &&Move_Heuristic[J].Heuristic < Heuristic; J--) {Move_Heuristic[J + 1].Heuristic = Move_Heuristic[J].Heuristic;Move_Heuristic[J + 1].Square = Move_Heuristic[J].Square;}Move_Heuristic[J + 1].Heuristic = Heuristic;Move_Heuristic[J + 1].Square = I;Moves++;}}for (I = 0; I < Moves; I++) {int Score;int Sq = Move_Heuristic[I].Square;Square_Type W;Play(Board, Sq, Player);W = Winner(Board);if (W == 'X')Score = (Maximum_Moves + 1) - Move_Nbr;else if (W == 'O')Score = Move_Nbr - (Maximum_Moves + 1);else if (W == 'C')Score = 0;elseScore = Best_Move(Board, Other(Player), Square, Move_Nbr + 1,Alpha, Beta);Play(Board, Sq, Empty);//알파베타가지치기수행if (Player == 'X') {if (Score >= Beta) {*Square = Sq;return Score;} else if (Score > Alpha) {Alpha = Score;Best_Square = Sq;}} else {if (Score