CSE(컴퓨터 공학)2010. 7. 26. 18:23
nadir (어떤 순간에서) 최악의 상황, 바닥
nadir point


1. Introduction
 

Multi-objective optimization 과정에서 nadir objective vector라는 것을 추정하는 것이 중요한 task중에 하나 이다. nadir objective vector는 전체 Pareto-optimal set에 상응하는 각 objective value의 가장 나쁜값을 나타낸다. 때때로, 이 point가 전체 search space에서 가장 나쁜 objective value값을 나타내는 point와 혼동이 될 수 있다. 이런점이 때로는 nadir objective vector에 over-estimation이 될 수 있는것이다. 이상적인(혹은 알맞은) objective vector와 함께 (point는 각 objective의 가장 좋은 값에 의해 구성된다), nadir objective vector는 normalize objective function으로 이용이된다. 문제(matter)는 때때로 multiobjective optimization algorithm의 충분한(적절한) functioning을 이상적이게 여기게 된다. 이들 두가지의 extreme value와 함께 objective function은 크기를 변화할 수 있고 그러므로 각 scaled objective는 같은 범위내에서 값을 좀더 또는 덜 가질 수 있다. 이들 scaled value는 weighted-sum approach나 Tchebycheff metric method와 같이 다른 알고리즘과 함께 optimization을 할때 이용할 수 있다. 이런 scaling procedure는 문제를 해결하는 속도를 증가시켜서 computational cost를 줄일 수 있다.  objective function vlaue들을 normalize하는것 말고도, nadir objective vector는 또한 guess method 와 다른것들 같이 서로다른 interactive 알고리즘을 이용해서 Pareto-optimal solution들을 찾는데 이용할 수 있다. 이들 방법의 일반적인 아이디어는 nadir objective vector로 부터 minimum weighted deviation을 최대화하는 것이다. 더욱이 nadir의 knowledge와 이상적인 objective value는 decision maker에 게있어서 각 objective의 범위를 알게 함으로서 실제 level에 대한 그들의 예상(기대)을 조절할 수 있게 도와주고 그러면 실제 이상적인 지역으로 집중하게 할 수 있다. 더욱이 Pareto-optimal solution들을 시각화 하는데에 있어서 nadir objective vector에 대한 지식은 필수적이다. 이상적인 point와 함께, nadir point는 각 objective의 범위를 제공해주고 value path나 bar chart, petal diagram같은 것으로 시각화 할 수 있다. 

nadir point를 추정하는것이 Pareto optimal frontier 전체에 대한 정보를 필요로 하기 때문에 이 point를 추정하는 어떤 procedure이든지 Pareto-optimal solution들을 찾을 수 있는 과정이 필요로 하다. 이것은 ideal point를 찾는것과 비교해서 task를 더 어렵게 만든다. ideal point란 전체 search space를 통틀어서 가장 좋은 objective value들을 이야기하는 것이다. evolutionary multi-objective optimization (EMO) 알고리즘이 Pareto optimal frontier 전체를 찾으려고 시도를 하기 때문에 EMO 는 이런 작업(nadir point를 추정하는 작업)을 하는데 가능한 후보가 될 수 있다. 하지만 nadir objective vector의 추정에는 중간의 Pareto-optimal solution을 찾는 과정을 포함할 필요는 없다. 오직 extreme solution이 필요할 뿐이다. 이 논문에서는 extreme Pareto-optimal solution을 강조하기 위해서  2가지 존재하는 EMO(elist non-dominated sorting GA or NSGA-II)의 수정방안을 제안할 것이다. 그렇게 함으로써 nadir point를 추정할 것이다. 시뮬레이션 결과는 20개의 objective(EMO에서는 거의 시도하지 않는) optimization problem에서 두가지 approach중 하나-the extremized crowded NSGA-II-가 원래 NSGA-II보다 빠르고 신뢰성이 있게 nadir point를 찾을 수 있게 하는것을 입증할것이다. 


2. NADIR OBJECTIVE VECTOR

Multi-objective optimization problem들은 여러가지 서로 대립하는 objective들을 수반하고 있고 이론적으로 Pareto-optimal solution들의 set이 생기게 한다. 이것은 objective간 trade-off를 제공한다. 2개의 objective의 minimization problem를 고려해보자. Figure1에 나타나 있다.
nadir objective vector를 계산하기 위해서 f1, f2 들이 개별적으로 최대화되었을때, 각자 A와 B라는 포인트가 나올 수 있다. 이들 두가지 point가 extreme point zw라는것을 만든다. (그림에서는 Worst objective vector라고 나와 있다.) 이것은 실제 nadir point가 아니다. nadir point라는것은 모든 Pareto-optimal solution들 사이에서 가장나쁜 objective value들을 이용해서 만들어지는것이지, 전체 search space상에서 가장 나쁜 objective value들로 만들어 지는것이 아니다. 그러므로 nadir point를 찾기 위해서는, nadir point를 찾기위한 solution들의 Pareto-optimality를 알 수 있어야 한다. 이것이 nadir point를 찾는것을 보다 어렵게 만든다.

3. Existing Methods
이런 어려움을 극복하기 위해서, 여러가지 method들이 제안되었다. Benayoun et al. [1]-Linear programming with multiple objective functions: Step method (STEM). Mathematical Programming, -은 처음으로 interactive multi-objective optimization method를 소개했다. (저자가 nadir 이라는 용어를 쓰지는 않았지만) 이것은 nadir point를 추정하기 위해서 payoff table이라는 method를 이용을 했다. 이 method에서는 어떤 table이 구성이 된다. 그 테이블은 i번째 objective가 최소인 point에서 다른 모든 objective function의 값이 계산된 값이 table의 i번째 행으로 구성이 된다. 그런 다음에 i번째 열의 최대값은 i번째 objective의 upper bound의 추정값으로 할 수 있고 이들 최대값들은 함께 nadir vector를 구성하는데에 이용이 된다. 이런 접근방식에서 주로 문제가 되는것은 어떤 objective의 minimum solution에 상응하는것이 다른 objective에 서로 다른 값에 따라 하나 이상은 존재하게 되는 것이다. 특히 문제가 2개이상의 objective를 가질때 이야기이다. Figure2에 있는 전형적인 3개의 objective에 대한 Pareto-optimal front를 한번 살펴보자.
첫번째 objective function의 minimum value는 f1 = 0 일 때이다.  그림에서 봐서 알 수 있듯이 f1=0일 떄 f2와 f3이 각각 서로 다른 값을가지게 되는 수많은 solution들이 존재를 한다. (선 BC라인에 있는 모든 솔루션들이 그러하다.) payoff table method에 의해서, 다음의 세가지 solution이 나타날 수 있다. f(1) = (0, 0, 1)T => point C, f(2) = (1, 0, 0)T => Point A, f(3) = (0, 1, 0)T(point B), 즉 nadir point, znad = (1, 1, 1)T로 나타낼 수 있다. 하지만 solutions이  f(1) = (0, 0.2, 0.8)T, f(2) = (0.5, 0, 0.5)T 그리고 f(3) = (0.7, 0.3. 0)T (이것은 그림에서 하얀 동그라미로 표시가 되어있다) 와 같이 f1, f2, f3가 각각 minimization 되는 해를 찾았다면 이것의 nadir point는 z' = (0.7, 0.3, 0.8)T로 나타낼 수 있을것이다. 이 그림에서 잘못된 nadir point는 오직 Pareto-optimal front의 부분에서만 나타난다는것을 보여주고 있다. 

후에 Iserman 과 Steuer [9] - Computational experience concerning payoff tables and minimum criterion values over the efficient set - 에서는 linear problem 조차도 nadir point를 찾는데 어려움이 있다는 것을 증명했고 payoff table 보다 더 나은 method를 이용해야 한다고 강조를 했다. Dessouky et al. [7] - Estimates of the minimum nondominated criterion values in multiple-criteria decision-making.- 에서는 3가지의 heuristic method를 제안했고 Korhene et al. [10] - A heuristic for estimating nadir criterion values in multiple objective linear programming.- 에서는 nadir point를 찾기 위해서 또다른 method를 제안했다. 중요한 것은 이들 method 모두가 모든 objective들과 constraint들이 linear function인 multi-objective linear problem들을 위해서 제안 되었다는 것이다.

Ehrgott 와 Tenfelde-Podehl [8] - Computation of ideal and nadir values and implications for their use in MCDM
methods.
 - 에서는 subproblem에 기반을 둔 알고리즘을 제안했다. 즉, M-objective problem에서 nadir point를 찾기 위해서더 낮은 dimensional problem의 Pareto-optimal solution들을 이용했다. 이런 요구사항이 알고리즘을 objective가 3개 이상일 때는  계산적으로 실현 불가능하게 할수 도 있다. 더욱이 저자는 nonlinear problem에 대해서 확장할 수 있는 알고리즘을제안하지않았다. 비록 nadir point를 찾는것이 Pareto-optimal solution들의 set에서 가장 나쁜  objective value를 찾는 것이고, 이것이 linear problem에 적용하는 것이라 할 지라도 이것은 반드시 다루어져야 하는 내용이다. 이것은 또 한 매우 어려운 task이다. 

4. Evolutionary Approach
nadir point를 결정하는 것은 Pareto-optimal solution들과 관련이 있다 그 때문에 Pareto-optimal set의 결정에 대한 힌트를 주는것은 nadir point를 추정하는 것을 가능하게 한다. 과거 십수년전에는 EMO 알고리즘은 그들의 multiple, wide spread 한 Pareto-optimal solution들을 한번의 simulation run동안에 동시에 찾을 수 있는 기능에 인기를 얻었다. 그들 알고리즘이 Pareto-optimal solution들의 set을 찾는것이기 때문에, EMO procedure는 nadir objective vector를 찾기 위한 이상적인 방법이라고 할 수 있다. 하지만 먼저 Pareto-optimal set을 찾고 다음에 set에서 nadir objective vector를 찾는  naive procedure는 딜레마를 야기시키는 듯 하다. 자 여기서 nadir objective vector의 목적에 대해서 상기시켜 보자. 그것은 objective들을 normalize해서 interactive multi-objective optimization algorithm을 이용해서 이상적인 Pareto-optimal solution을 찾는것이다. 하지만 EMO가 대표적인 Pareto-optimal set을 찾는데 사용이 된다면 nadir point를 찾을 이유가 더 이상 없다는 것이다. 상호적인 의미에서는 EMO procedure의 application은  Pareto-optimal set의 본질에 대한 idea를 제공해줄 수 있고 차후에 이상적인 Pareto-optimal 지역을 위한 EMO procedure가 nadir point 기반을 한 interactive method들과 같다고 정할 수 있을것이다. 

하지만 EMO procedure들은 그들의 작업 원칙에서 Pareto-dominace의 concept를 이용하고 많은 수의 objective들(5개 이상)을 다루는데 있어서는 그것의 비효율성으로 많은 비판을 받아왔다. high-dimensional Pareto-optimal front를 나타내기 위해서는 exoponential 한 큰 수가의 point가 필요하다. 이것이 EMO procedure가 first place에서 완벽한 Pareto-optimal front를 찾을 수 없게 한다. 그러므로, 많은 수의 objective에서 Pareto-optimal front를 찾고 이상적인 지역을 강조하기 위해서 두개의 갈라진(pronged) EMO procedure를 이용하는것은 별로 장점이 없다. 대신에 EMO procedure가 하나의 application에서 이 두가지 작업을 동시에 수행하도록 이용할 수 있을 것이고 이 과정에서 main focus는 Pareto-optima set의 지역으로 population을 퍼트리는것이다. 그리고 이 Pareto-optima set은 nadir point를 올바르게 구축할 것이다. 그림 2에서 3개의 objective의 minimization problem에서 제안한 EMO procedure는 그것의 population member들을 전체의 Pareto-optimal set 대신에  A,B,C 지역 근처에 퍼트려야 한다. 그렇게 해서 nadir point가 빠르게 발견될 수 있다. 다음 section에서는 우리는 이를 위한 2가지 EMO procedure에 대해서 알아볼 것이다.

5. Elitist Non-dominated Sorting Genetic Algorithm (NSGA-II)
제안방안 두가지 다 NSGA-II를 이용할 것이다. 이 알고리즘은 최근에 매우 각광을 받고 있는데, 그 이유는 그것의 간단하고 계산적으로도 매우 빠르며 source code의 이용가능성에 있다고 할 수 있다. 

5.1 NSGA-II Crowding Distance Calculation
multi-objective optimization problem의 주된 목적 중 하나는 front에 따라 diversity를 유지하는 것이다. diversity를 보존하기 위해서 non-dominated front에서 solution의 density(밀도) 측정할 수 있어야 한다. 가장 간단한 방법으로는 solution 간의 Euclidean distance를 계산해서 clustering 하는것이다. 하지만 계산량이 엄청나게 많아진다. 그래서 NSGA-II에서는 매우 빠른 계산 방법을 이용한다. Crowding distance는 어떤 솔루션 i의 두개의 이웃 solution 사이의 objective-wise normalize distance를 구한다. extreme solution들의 경우에는 임의로 엄청나게 큰 수를 할당해준다. 그리고 나서 솔루션들은  crowding distance 높은 순으로 정렬을 정렬된 순서되로 필요한 수만큼 선택이 되는 구조이다. 

6. Modifications To NSGA-II
NSGA-II가 non-dominated front의 extreme solution들에 대한 중요성을 제공하기는 하지만 주로 강조하는것은 전체 front에서 솔루션들의 diversity를 좋게 유지하는것이다. 하지만 위에서 이야기 했었듯이 nadir point를 찾기위해서는 nondominated-fornt에서의 extreme solution들 사이에서 NSGA-II population member을 퍼뜨려야 한다. 그러므로 계산적으로 효율적으로 nadir point를 찾기위해서 기존 NSGA-II 보다 더  extreme non-dominated solution들 근처를 강조하는 효율적인 방법을 이용해야 한다. 이런 concept를 구현하기 위해서 crowding distance calculation이 수정되어야 한다. 

6.1 Worst Crowded NSGA-II 
Pareto-optimal solution들에 대한 가장 나쁜 objective value들이 nadir point를 구성하므로 우리는 front-wise에 가장 나쁜 objective value를 강조한다. 특정 front에 있는 solution은 먼저 각 objective에 기반으로 minimum으로 부터 maximum까지로 정렬이 되고(minimization problem일때) 정렬된 리스트 내에서 솔루션의 위치가 rank(순위)가 된다. 그런 다음에 가장 큰 랭크가 솔루션에 assign된다. 이것은 crowding distance measure에 로 모든  objective가 선언되었기 때문이다. 이런 방식으로 어떤 objective의 가장 큰 objective value가 가장 큰 crowded distance를 가지게 된다. NSGA-II procedure가 non-dominated solution들을 강조하고 crowding distance value가 더 큰 솔루션들을 선호하기 때문에, 모든 fornt에서 모든 가장 나쁜 objective value들은 강조되어야 한다. 그렇게 함으로써 nadir point를 구하는 것에 도움이 될 수 있다. 

6.2 Extremized Crowded NSGA-II
하지만, 이런 가장 나쁜 objective solutions front-wise에 대해서만 강조를 하는것은 적어도 두가지 어려움이 생기게 된다 
(i) 각각의 가장 나쁜 objective vector 근처의 subpopulation 에서 diversity를 유지하기 어렵고(이로 인해 sub-optimal solution으로의 이른 수렴이 발생 할 수도 있다.) (ii) 가장 나쁜 objective vector들의 individual에 해당하는 솔루션 단독으로 는 많은 수의 non-Pareto-optimal solution을 dominate 할 수 없을 것이다. 그것 때문에 원하지 않은 솔루션과 함께 non dominated front를 찾을 수 있다. 이와같은 front는 nadir point를 잘못 추측하게 만들 수 있다. 이런 두가지 가능성을 피하기 위해서 다른 crowding distance measure를 제안한다. 특정 front의 solution들은 각 objective에 대해서 최대부터 최소의 순으로 정렬을 한다. 솔루션이 각 extreme objective vector에 가까워 질 수록(minimum or maximum objective values) 중간에 있는 솔루션들 보다 좋은 높은 랭크를 받을 것이다. 그러므로 모든 objective에 대한 2개의 extreme solution들은 N'(front에서 솔루션의 수)라는 rank를 부여 받을 것이다. extreme solution들 다음에 있는 솔루션은 N'-1의 랭크를 받게 되는것이다. 그림 3은 이 rank assignment procedure를 보여줘고 있다. 
각 objective 에 대한 솔루션에 랭크가 부여가 되면 할당된 rank의 최대값은 crowding distance로서 선언 crowding distance value들은 그림에서 괄호 내의 값으로 보여 지고 있다. 이 procedure는 각 objective에 대해서 extreme solution들을 강조(minimum과 maximum) extreme solution들에 대해서 가까운 솔루션을 강조할 수 있는 계층구조를 만들어 낸다. 

one-dimensional Pareto-optimal front를 가지는 2개의 objective 문제와 그 이상의 objective 문제에 대해서(즉, M-2 redundant objective들을 가지는 M-objective 문제), 이 crowding distance assignment는 worst crowding distance assignment scheme과 유사할 것이다. (하나의 objective의 minimum rank solution이 다른 하나의 objective의 maximum rank solution이 되는) 하지만 large-dimensional Pareto-optimal hyper-surface, 를 가지는 문제에 대해서는 extremized crowding 은 worst crowding scheme과 다르다. 그림 2에서의 3개의 objective에 대한 문제에서 extremized crowding scheme은 오로지 A, B, C만 강조하지 않고 선, AB, BC, CA와 그들 근처에 있는 솔루션들을 강조할 것이다. 이렇게 되면 두가지의 장점이 생긴다 : (i) solution들의 좋은 diversity가 유지가 될 것이고 그것 때문에 좀 더 좋은 솔루션을 찾기 위한 genetic operator들이 가능해질 것이다.(crossover, mutation같은) 그리고 너무 이른 수렴이 발생하지 않을것이고 이들 솔루션들의 존재는 겉으로만 그럴싸한 non-Pareto-optimal 솔루션들을 가질 기회도 없어진다는 이야기가 된다. 더욱이 Pareto-optimal 지역에서 중간 지역의 대해서 강조가 되지 않기 때문에 실제 original NSGA-II 알고리즘에 보다 extreme solution들을 빠르게 찾을 수 있다. 특히 많은 objective들을 가지는 문제에서 말이다. 

6.3 VEGA Based Approach
신중하게 생각하보면 위에서 봤던 worst crowding distance calculation method는 다른 multi-objective GA와 유사하다, 잘알려진 VEGA(vector evaluated GA)이다. 이 approach에서, GA population은 각 세대에서 objective function의 수와 같은 더 작은 그룹으로 세분화 된다. 첫번째 그룹에 있는 individual들은 first objective를 기반으로 reproduce되고 두번째 그룹은 두번째 objective를 기반으로, 이런 식으로 재생산을 한다. VEGA의 selection operator는 각 group에 대해서 제한적이지만 crossover 라든지 mutation operator같은 경우는 전체 space에서 적용 가능하다. selective search가 subpopulation대해서 각 objective에 독립적이기 때문에 각 objective에 대해서 더 좋은 값을 가지는 individual들이 강조가 된다. VEGA가 Pareto-optimal front에서 extreme solution 으로 수렴하는 성향을 가지고 있지만 domination check 나 explicit diversity-preserving mechanism(NSGA-II 처럼)이 없다. 이 연구에서 우리는 nadir point를 추정하기 위해서 VEGA approach를 evaluate해볼 것이고 original NSGA-II와 두가지의 제안된 NSGA-II의 수정방안을 비교해 볼 것이다.


'CSE(컴퓨터 공학)' 카테고리의 다른 글

[HCI] Evaluation techniques  (0) 2010.04.14
Posted by 태씽
CSE(컴퓨터 공학)2010. 4. 14. 18:25
유저가 그룹단위일때 어떻게 할것인가?

지금까지 우리는 single-user system에서의 실험을 어떻게 하는가에 대해서 알아보았다. group system의 단위에서 실험을 evaluation 하기 위한 실험은 추가적인 문제를 야기시킨다. 인간 끼리의 의사소통과 group working의 복잡성이 주어졌을 때, single-user system보다 어렵고 복잡한 것은 놀라운 일이 아니다. 토론의 목적으로 실험 참가자들 사이에서 video connection을하는 application을 evaluate한다고 해보자. 그리고 몇몇 가지 문제들에 직면할 것이다.

The participant groups 
10번의 실험을 하는 single-user system은 10명의 실험 참가자가 필요하다. 3개의 그룹이 포함되는 실험에서는 30명의 참가자가 필요할 것이다. 게다가 group working 내에 실험은 single-user 실험보다 길다. 그 이유 중하나가 될 수 있는게 바로 settle-down이라는 것이 있는데, 이것의 실험의 결과가 안정되는것을 이야기 한다. 이 시간이 소요 되므로 길 수 있고  실험 참가자들에게 지장을 주고 이것이 비용이 더 많이 들게 하는 요소가 된다. 

참가자와 시스템간의 일정을 맞추는데에도 어려움이 생기게 된다. 실험에 사용 되는 워크스테이션이 동료의 개인적인 시스템이어서 우리는 적어도 6명의 사람을 포함 시킬려고 시도 했다. 실험자들에게 언급하지 않았다. 
많은 group working에 대한 report들이 3개 또는 4개의 그룹만을 포함한것은 놀라운일이 아니다 이것은 명백히 통계적인 측면으로 봤을때는 문제가 있지만 주된 장애가 되지는 않는다. 

The experimental task
알맞는 task을 선택하는것 역시 어렵다. 우리는 여러 종류의 task을 테스트하기를 원했다 : creative, structuredm information passing등등. 물론 task은 협력을 장려해야한다. 상호 합의가 필요한 task이거나 정보나 control이 실험 참가자들 사이에 분배가 되기 때문이다. 또한 명백하게 tassk는 groupware system의 속성에 의존한다 : 가능한 채널이 여러가지라면, 우리는 넓게(될 수 있으면 다 쓸 수 있게)장려받는다. 예를 들어서 가정한 video application의 경우에는 application을 사용하지 않고는 task의 수행이 불가능할 수 밖에 없다. 사용한다면 video conferencing에 대한 조사가 한결 수월 해 진다.
 
creative task는 '~에 대해짧은 레포트를 쓴다' 혹은 '~에 관한 연구 제안서를 작성한다'와 같을 수 있다. 때때로 이것이 매우 효과적인데, 예에서 실험 참가자들이 합의에 도달해야만하는 경우 공유 application을 이용한 final report를 쓰라고 요청할 수 있다.

Design task들 역시 사용된다. 어떤 디자인에 대해서 변경 요청같은것에 이용이 될 수 있다.
Decision game은 협동적인 활동을 테스트하고 훈련하기 위해서 만들어진것이다. Decision game은 개인의 활동이 아닌 그룹 협동에 성공이 좌지우지가 된다. 예를 들어서 사막 서바이벌 task에서, 참가자들이 사막에서 곤경에 처했다고 하자. 그들은 그들이 가진 아이템을 그들의 생존에 도움이 되는 순서대로 순위를 매길것이다: 칼, 플라스틱 시트 등등.. 참가자들은 이 아이템들 중에서 하나의 리스트를 만들어야한다, 참가자들이 혼자서 그일을 진행 할 순 없다. 

time-critical simulated process control task는 실험 참가자들이 모델의 다른 파트들을 제어함으로 더 높은 페이스의 상호작용을 가능하게 하는것이다. 


Data gathering 
single-user 실험에서도 우리는 여러대의 비디오 카메라에 application의 직접적인 로깅까지 이용을 할 수 있다. 그룹의 세팅의 경우에는 single-user의 경우를 각각의 실험 참가자들에게 그대로 적용하면 된다. 우리는 6개이상의 비디오 소스와 3개의 keystroke log를 동기화를 시킬려고 해봤다. 합성하는데에 문제는 각각 어떤 실험이나 장소에 따라 달라질 것이다. 기술적인 문제가 큰것은 당연하다. -> 4-into-1 비디오 레코딩은 가능하고 화면의 각 4분면에서 다른 이미지를 저장을 하지만 우리가 바라는 채널 수에서 부족했다. 

실험 참가자들의 개인적인것에 집중했을 때 녹화 각 참가자마다 이루어 지고 비디오 이미지나 사운드는 각 시스템의 부분으로 중계가되었다.(video connection이 있다고 가정을 했다.) 이들은 특별한 실험참가자들의 keystroke과 추가적인 video 탐색과 함께 동기화가 되었다. 그러므로 우리는 이런 상황을 재창조를 할수 있다. 

충분한 레코딩 장비가 주어졌으면 이것은 각 참가들에게 반복이 될수있다.  행복하게도 각 참가자들의 동기화의 레벨은 중요하지 않다. 중요한것은 각 개인의 동리화 레벨이 될것이다. 

=> 보니까 각각의 실험 참가자들 사이의 동기화는 걱정할 것이 안되고 각 개인의 동기화(비디오, 소리, log->keystroke등)이 매우 중요한 요소가 된다는것이 핵심이다.

Analysis 
실제 실험을 따라 우리는 실험 조건사이에서의 차이를 통계적으로 분석해보려고 한다. 우리는 이전에 single-user experimental에서는 개인적인 차이가 문제를 발생시킬 수 있다고 했는데 그룹 에서는 variation이 더욱 극단적이다. 무작위로 혼합된 그룹에서, 어떤 그룹은 민주적 성향이 나타나고; 다른 곳에서는 틀별한 pair가 토론을 지배할 수 있다; 세번째로 참가자들중 한명이 진행자가 되어서 다른 사람들의 의견을 정리할 수도 있다. variation의 정도는 어떤 컨디션 하에서는 매우 비극적일 정도로 실패고 다른 조건하에서는 기가 막히게 성공을 할수 있다. 그러므로 variation의 정도는 항상 통계적으로 중요한 의미를 이끌어내진 못한다. 
이것의 예로  우리가 output의 quality의 몇몇 양적인 measure가 있다고 하자. 우리는 거의 확실하게 non-parametric test들 하게 될 것이고 그러므로 우리가 어느 한 조건에서의 모든 그룹이 다른 조건의 그룹보다 점수가 높다고 가정해보자. 5%의 의미를 얻기 위해서는 적어도 각 조건에 4개는 필요하다.(아마도 measure가)
이제 하나의 조건만 고려하는 예제가 있고 여기서 최고의 결과를 가능해보자. 일반적으로 우리는 컨디션내에서 그룹사이의 spread(다양성)가 더 좋아지길 기대한다, 그리고 우리는 한먼에 더많은 조건을 테스트 하기를 원할것이다. 우리의 10 그룹은 어떤 통계적으로 의미가 있는 결과를 세우기 위해서 빠르게 증가를 할 것이다. 하지만 우리는 10개의 실험 그룹을 얻는것이 상당한 문제가 있다는것을 알아냈다.

이 문제를 해결하기 위해서는 세가지 가능한 솔루션이 있다. 먼저 하나는 within-group experiment를 이용하는것이다. 이것은 은 각 그룹이 여러컨디션 하게에서 실험이 진행이 된다. 두번째로 우리는 micro analysis같은 것을 통해서 발언(의견) 사이의 차이와 같은 특징을 볼 수도 있다. 이와 같은 measure들은 standard distribution에 좀더 적합하게 들어 맞을 수 있고 그러므로강력한 parametric test들을 해볼 수 있다. 게다가 그들은 그룹 사이에 큰스케일의 social difference(사회적 차이)에 더욱 확실하다.
세번째 솔루션은 좀 더 입증되지 않은 분석을 할 때 택할 수 있다. 뭔가 데이터 내에 critical한 사건을 찾는다- 예를 들어서, 흥미로운 이벤트나 고장같은 경우;;; 그룹 차이를 문제로서 간주하는데신에 그들이 분석에 포함 될 수 있다. 즉, 우리는 그들이 사용하는 통신 미디어와 어플리케이션과 상호작용하는 다른 그룹 구조를 찾는 체계적인 방법을 찾기를 시작할 수 있다.

물론 실험은 양적이고 질적인 방법을 둘다 이용해서 분석이 가능하다. 정말 구체화된 입증되지 않은 로그의 분석은 통계적인 분석을 하는데 있어서 생산적인 measure로 나타낼수 있다. 하지만 실험 그룹의 수가 제한 되면 제한된 실험을 시도하는것은 생산적이지 않을 수 있다. 그리고 낭비가 될 수가 있다. group-working 실험의 높은 비용이 주어졌다면, 흥미로운 결과를 낼 수 있는 조건을 선택해야할 것이다. 통계적이 분석이 불가능할 지라도 말이다.

Field studies with group
물론 그룹 실험을 할때 그들을 실험 환경에 집어넣기가 문제가 발생할 수 있다. group이 임의적으로 섞이면 우리는 그룹 편성의 프로세스를 일반적인 워킹그룹보다 효율적으로 조사한다. 심지어 먼저 존재했던 그룹이 이용되어도 그들의 일반적인 작업 환경으로부터 사람들을 제외하는것은 그들의 일하는 패턴을 바꿀 수 있다. 새로운 시스템을 위해서 일반적인(정상적이) workplace는 없을 수 있고 우리가 하는 모든것은 인공적인 환경을 조성하는 것이다. 하지만 이런 새로운 시스템이라도 우리는 좋은 실험이나 자연스러운 세팅을 선택할 수 있다. 전통적인 실험적 심리학은 이들 더 질적인 사회적 분석과 함께 이용될 수 있다. 
그룹실험 같은 경우에는 오직 컨텍스트 안에서만 연구될 수 있다고 주장할 수 있다. 실제 상황에서 벗어나는것은 실제 작업의 
본질을 바꾸는 것이 될것이다. enthnography라는 것은 사람들, 그들의 환경 그리고 서로서로 사이에 매우 상세한 상호작용의 기록을 하는것이다. 

Observational technique
시스템의 실제 사용에 대한 정보를 얻기 위해 사용하는 인기있는 방법은 유저가 시스템과 상호작용하는 것을 탐색을 하는것이다. 

Protocol analysis 
유저의 행동을 기록하는 여러가지 방법이 있다.
- 종이, 연필
- 오디오 레코딩
- 비디오 레코딩
- 컴퓨터 로깅

Automatic protocol analysis tools
프로토콜을 분석하면서 비디오, 오디오나 시스템 로그 둘중하나는 시간을 소비를 하거나 손으로 하게 되어서 지루해질 수 있다. 이것은 동기화해야하는 데잉터가 한개 이상일 때 매우 어려워 지게 되는데 이럴때는 automatic analysis tool을 이용하면 해결할 수가 있다. 이런 툴들은 상세한 분석을 위해서 수정과 비디오, 오디오 주석다는 작업이나 이것들을 동기화하는 그런 수단을 제공한다. 
EVA라고 그런 예가 하나 있는데 이것의 특징은 평가자가 tag버튼을 이용해서 흥미있는 일이 일어나면 그것에 대해서 따로 주석을 달아놓을 수 있다는것이다. 세션이 끝나고 리뷰를 하면서 태그를 달아놓으면 그것으로 검색 역시 가능하다. 
이와 같은 시스템은 비디오 분석에서의 부담은 완화를 시켜주지만 문제가 그것만은 아니다. 태깅하고 주석은 다는 행위는 그들 자신에게 일어나는 이벤트들에 대해서 집중하는것을 방지할 수 있다. 한마디로 이벤트를 놓치거나 나중에 대그가 될 수 있다는 이야기이다. 

Post-task walkthrough
때때로 데이터는 직접적인 탐색을 통해 해석이 결여된채로 획들되었다. 우리는 어떤 수행된 basic action을 가지고 있다. (왜 그런지에 관해 약간의 지식을 가지고) 참가자가 작을을 통해서 think aloud를 장려 을지라도  정보가 잘못될 수가 있다. 예를 들어서 참가자들은 "그리고 지금 내가 undo 메뉴를 선택하고 있어요" 라고 이야기할 수 있다. 하지만 우리에게 어떤 잘못이 undo메뉴를 필요한가는 이야기를 하지 않는다. 게다가 think aloud는  대안같은 정보를 가지고 있지 않다.
walkthrough의 시도는 이러한 문제들을 완화 시키기위한 시도이다, 이벤트 후에 참여자들의 액션을 다시 생각하게 하는것이다.  써졌거나 레코딩된 transcrip은 커멘트를 하러온 실험 참가자들에게 리플레이가 된다. 혹은 질문자들은 바로 질문을 받게 된다. 이것은 참가자가 행동을 하게 된 이유를 알게 된다면  매우 간단하게 해결이 되거나 간격 후에 사용자들의 일정 시간이 지난후의 해석까지 덭붙여서 대답을 받을 수 있다. 지연된 walkthrough의 장점이라고 한다면 분석가가 적합한 질문을 구성하고 어떤 명확한 사건에 초점을 맞춘다는데 있다. 단점이라면 freshness가 떨어지게된다. 시간이 좀 지나서 하는것이기 때문이다.  
실제 observation을 하는 동안 참가자들이 이야기하는것을 기대할 수 없을때는 몇몇 환경이 있다. 예를 들어서 critical task동안에 또는 task가 집중적(많이 모여)일 때 post-task walkthrough가 유저의 행동을 주관적인 관점에서 얻을 수 있는 유일한 방법이 될 수 있다. 가능한한 좋은 퍼포먼스를 얻기 위해서  direct observation동안에 task와 관련없는 이야기를 최소한으로 하는것이 더 선호되는 주장도 있다. 이것이 walkthrough를 필수로 여기게 한다.
Posted by 태씽

'CSE(컴퓨터 공학) > 졸업과제' 카테고리의 다른 글

항해항만학회학술지  (0) 2009.09.14
졸업과제  (0) 2009.06.24
Posted by 태씽
설계문서
Posted by 태씽

'CSE(컴퓨터 공학) > 졸업과제' 카테고리의 다른 글

기존논문  (0) 2009.10.22
졸업과제  (0) 2009.06.24
Posted by 태씽

중간 보고 내용

문제 분석 및 학습 결과 보고

- 컨테이너, 크레인 환경 분석

- 고려해야할 사항(크레인 간섭 확률, 크레인 작업용이성, 컨테이너 그룹, 높이)

- 등등...

stacking strategy를 선택하고 학습한 내용과 의문점을 발표.

회피 방지의 모듈 제공 여부 확인,

가정
(
크레인이 선석까지 움직이는 거리와 시간은 일정하다고 가정한다.


블록 정보 : 6단 9열 41베이

컨테이너의 정보 : 무게, 목적지, 컨테이너의 높이, 적하 시간, 출하 시간

크레인(2대) 정보 : 현재 작업중인 컨테이너, 앞으로의 작업 일정, 현재 위치정보, 생산성(box/hour)
opt)속도, 가속도
)


설계 내용 보고

GUI, 시뮬레이션 엔진, 실험 데이터 , 장치위치 결정전략, 크레인간섭회피(불확실)


각각의 모듈에 어떤 요소가 있을지 분석을 한다.(알고리즘, 어떤데이터가 들어갈 것인가)

GUI의경우 프로토 타입 제작.



 

'CSE(컴퓨터 공학) > 졸업과제' 카테고리의 다른 글

기존논문  (0) 2009.10.22
항해항만학회학술지  (0) 2009.09.14
Posted by 태씽
hared memory와 semapore를 사용하여 데이터를 공동관리 하는 두개이상의 프로세스로 구성된 프로그램을 작성하시오
(예 : 계산담당 프로세스와 디스플레이 담당 프로세스)


이과제를 해결하기 위해서 shared memory와 semapore에 대해서 확실히 알고 넘어가야한다.

먼제 세마포어(semapores)에 대해서 알고 넘어가도록 하자.


Semaphores
세마포어
A counter used to provide access to a shared data object for multiple process.
세마포어란 여러 프로세스가 공유된 데이터를 Access 할 수 있게 하는 Counter이다.

To obtain a shared resource a process
프로세스가 공유된 자원을 얻기 위해서는
1.Test the semaphore that controls the resource
세마포어를 테스트 해봐야하는데 그것은 리소스를 컨트롤 한다.
2. If the value of the semaphore is positive, the process can use the resource
세마포어의 값이 양수(positive)이면 프로세스는 자원을 이용할 수 있다.
-The process decrement the semaphore value by 1, indicating that it has used one unit of the resource.
프로세스는 세마포어의 값을 1을 감소시킨다, 그것은 리소스의 하나의 unit을 이용했다는것을 나타낸다.
3.If the value of the semaphore is 0, the process goes to sleep until the semaphore value is greater than 0
만약 세마포어 값이 0이라면 프로세스는 세마포어의 값이 0보다 커질때까지 슬립을 한다.
-When the process wakes up, it returns to sleep
프로세스가 깨어나면 그것은 슬립을 리턴시킨다.

To implement semaphores correctly,
세마포어를 올바르게 구현하려면
The test of a semaphore’s value and the decrementing of this value must be an atomic operation.
세마포어의 값의 테스트와 이값의 감소가 atomic operation이어야 한다.
For this reason, semaphores are normally implemented inside the kernel.
이런 연유로 세마포어는 커널 안에서 일반적으로 구현이 된다.


이론적 형태의 세마포어

-네덜란드의 이론가 E.W.Dijkstra가 프로세스의 동기화 해결책으로 제안
-세마포어 (sem)은 다음과 같이 연산이 허용되는 정수형 변수

p(sem) or wait(sem)
if (sem != 0)
    decrement sem by one
else
    wait until sem becomes non-zero

v(sem) or signal(sem)

if (queue of waiting processes not empty)
restart first process in wait queue
else
increment sem by one

-두 연산은 모두 atomic operations
`sem을 변경할 수 있는 프로세스는 한 순간에 오직 하나뿐이다.

세마포어의 좋은점: 세마포어의 불변특성 (unvariant)
-(semaphore’s initial value + number of v operations – number of completed p operations) >= 0
세마포어는 다방면으로 사용될 수 있다.
-가장 단순한 경우는 프로그램의 특정한 부분을 수행하는 프로세스가 한 순간에 오직 하나만 존재하도록 하는 mutual exclusion (상호배제)를 보장.

-예제:
(number of completed p operations – number of v operations) <= initial value of semaphore sem의 초기값이 1이면
(number of completed p operations – number of v operations) <= 1
즉 P와 V사이에 있는 문장들은 한 순간에 오직 하나의 프로세스에 의해서만 수행된다.

이런 이론으로 Unix에는 세마포어가 구현이 되어 있다. 유닉스에 세마포어 시스템 호출은 어떻게 이루어지는지 한번 살표보도록 하자. 커널에서는 세마포어를 위한 스트럭처를 이용하여 세마포어를 관리하게 된다. 이때 사용하는 스트럭처가 다음의 smid_ds이다.

struct semid_ds{
  struct ipc_perm sem_perm; //세마포어에 대한 접근권한
  struct sem *sem_base; /* ptr to first semaphore */
  ushort sem_nsems;     /* # of semaphores in set */
  time_t sem_otime;     /* last-semop() time *///마지막으로 세마포어와 관련된 작업을 수행하는 시간
  time_t sem_ctime;     /* last-change time *///마지막으로 스트럭처의 데이터들이 업데이트 된 시간
};

이제 Shared Memory에 대해서 알아보자.

Shared memory란 말그대로 프로세스들이 특정 메모리 영역을 공유하도록 만든 뒤, 이 공간을 이용하여 통신을 수행하는 기법이다. 메모리를 서로 공유하는 프로세스들은 공유 가상 메모리를 가리키는 테이블 엔트리를 가지게 된다.

다른 IPC 기법들과 마찬가지로 공유메모리는 킷값을 이용하여 잡근 및 관리가 된다. 공유 메모리 또한 프로세스 동기화가 필요하기 떄문에 세마포어 등을 이용하여 자원에 대한 관리를 해주어야 한다. 

유닉스 시스템은 shm_segs라는 벡터를 이용하여 공유 메모리를 관리하게 된다. 그리고 벡터속에는 shmid_ds라는 스트럭처가 저장이 되는데 shmid_ds를 이용하여 공유메모리 정보를 저장하게 된다. 

이것을 토대로 프로그램을 작성해보자.  프로그램은 두개의 프로그램으로 나뉘고 하나의 프로세스는 메시지를 받으려고 기다리는 프로세스이고 다른 하나는 메세지를 입력하는 프로세스가 될것이다. 이것을 shared memory와 세마포어를 이용해서 작성 하였다.

메시지를 보내는 프로그램은 우선 프로그램이 실행이 되면 세마포어의 값을 1감소시키고 메시지 입력을 대기한다. 메시지를 입력하면 세마포어의 값을 하나더 증가 시킨다.

메시지를 받는 프로그램은 세마포어를 감소하고 메시지를 출력한뒤 세마포어를 증가시키는데 세마포어가 보내는 프로그램쪽에서 차지하고 있다면 계속 대기상태가 되게 될것이다. 프로그램의 소스코드는 다음과 같다.


메시지를 보내는 프로그램
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
 
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
//공유 메모리 사이즈 설정
#define SIZE 64
 
//이프로세스는 상대편 프로세스가 메시지를 입력할때까지는 process가 돌면 안된다. 
//세마포어를 이용해서 막아보자
 
int main(int argc, char *argv[])
{
    //세마포어와 shared memory 변수선언
    void *s_memory = (void *)0;
    char *buffer;
    int semId, proId, smId;
    int isRun = 1;
 
    struct sembuf semB;
     
    //shmget을 이용하여 공유메모리를 확보한다.
    smId = shmget((key_t)9000, SIZE, 0666|IPC_CREAT);
    if(smId == -1)
    {
        printf("shmget 실행실패\n");
        return 0;
    }
 
    //shmat을 이용하여 공유 메모리 주소 얻기
    s_memory = shmat(smId, (void *)0, 0);
    if(s_memory == (void *)-1)
    {
        printf("shmat 실행실패\n");
        return 0;
    }
 
    //공유메모리 주소와 내부 변수 포인터연결
 
    buffer = (char *)s_memory;
 
 
    //sembuf의 초기값 설정
 
    semB.sem_flg = SEM_UNDO;
    semB.sem_num = 0;
 
    //semget을 이용해서 세마포어 ID를 구한다.
    semId = semget((key_t)1234, 1, 0666 | IPC_CREAT);
 
    //세마포어 초기값 설정
    if(semctl(semId, 0 , SETVAL, 1) == -1)
    {
        fprintf(stderr, "세마포어 초기화 실폐\n");
        exit(0);
    }
    //본프로세스의 PID출력
    printf("본프로세스의PID값은 : %d\n", getpid());
     
     
 
 
    //프로세스의 입무를 수행하기 전에 세마포어값을 감소 후 수행 그다음 세마포어 값을 다시 증가 시킨다.
    while(isRun)
    {
        //세마포어에 마지막으로 수정을 가한 프로세스 PID 출력
        proId = semctl(semId, 0, GETPID, 0);
        printf("세마포어를 변경한 마지막 PID: %d\n", proId);
 
             
        //세마포어의 값을 감소시킨다.
        semB.sem_op = -1;
        if(semop(semId, &semB, 1) == -1)
        {
            fprintf(stderr, "세마포어 값감소 실패\n");
            exit(0);
        }
         
        printf("메시지입력 : "); 
        scanf("%s",buffer);
               
        //quit을 보내면 종료
        if(!strcmp(buffer, "quit"))
        {
            break;
        }

 

        //세마포어 값을 증가시킨다.
        semB.sem_op = 1;
        if(semop(semId, &semB, 1) == -1)
        {
            fprintf(stderr, "세마포어 값증가 실패\n");
            exit(0);
        }
    }
 
    //프로세스와 공유메모리 분리
 
    if(shmdt(s_memory) == -1)
    {
        printf("shmdt 실행실패\n");
        return 0;
    }
 
    return 1;
}


메시지를 받는 프로그램

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
 
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
//공유 메모리 사이즈 설정
#define SIZE 64
 
//이프로세스는 상대편 프로세스가 메시지를 입력할때까지는 process가 돌면 안된다. 
//세마포어를 이용해서 막아보자
 
int main(int argc, char *argv[])
{
    //세마포어와 shared memory 변수선언
    void *s_memory = (void *)0;
    char *buffer;
    int semId, proId, smId;
    int isRun = 1;
 
    struct sembuf semB;
     
    //shmget을 이용하여 공유메모리를 확보한다.
    smId = shmget((key_t)9000, SIZE, 0666|IPC_CREAT);
    if(smId == -1)
    {
        printf("shmget 실행실패\n");
        return 0;
    }
 
    //shmat을 이용하여 공유 메모리 주소 얻기
    s_memory = shmat(smId, (void *)0, 0);
    if(s_memory == (void *)-1)
    {
        printf("shmat 실행실패\n");
        return 0;
    }
 
    //공유메모리 주소와 내부 변수 포인터연결
 
    buffer = (char *)s_memory;
 
 
    //sembuf의 초기값 설정
 
    semB.sem_flg = SEM_UNDO;
    semB.sem_num = 0;
 
    //semget을 이용해서 세마포어 ID를 구한다.
    semId = semget((key_t)1234, 1, 0666 | IPC_CREAT);
 
    //세마포어 초기값 설정
    if(semctl(semId, 0 , SETVAL, 1) == -1)
    {
        fprintf(stderr, "세마포어 초기화 실폐\n");
        exit(0);
    }
    //본프로세스의 PID출력
    printf("본프로세스의PID값은 : %d\n", getpid());
     
     
 
 
    //프로세스의 입무를 수행하기 전에 세마포어값을 감소 후 수행 그다음 세마포어 값을 다시 증가 시킨다.
    while(isRun)
    {
        //세마포어에 마지막으로 수정을 가한 프로세스 PID 출력
        /*proId = semctl(semId, 0, GETPID, 0);
        printf("세마포어를 변경한 마지막 PID: %d\n", proId);*/
 
            
        if(!strcmp(buffer,""))continue; //일단 버퍼가 없으면 그냥 계속 지나쳐간다.
        
        //세마포어의 값을 감소시킨다.
        semB.sem_op = -1;
        if(semop(semId, &semB, 1) == -1)
        {
            fprintf(stderr, "세마포어 값감소 실패\n");
            exit(0);
        }
 
        
        printf("받은 메시지 : %s\n", buffer); //메시지를 출력해준다.
        
        //quit을 받으면 종료
        if(!strcmp(buffer, "quit"))
        {
            break;
        }
        
 
        //세마포어 값을 증가시킨다.
        semB.sem_op = 1;
        if(semop(semId, &semB, 1) == -1)
        {
            fprintf(stderr, "세마포어 값증가 실패\n");
            exit(0);
        }
        
 
    }
 
    //프로세스와 공유메모리 분리
 
    if(shmdt(s_memory) == -1)
    {
        printf("shmdt 실행실패\n");
        return 0;
    }
 
    //공유메모리 제거
    if(shmctl(smId, IPC_RMID, 0) == -1)
    {
        printf("shmctl 실행실패\n");
        return 0;
    }
     
 
    //세마포어를 제거한다.
    if(semctl(semId, 0, IPC_RMID, 0) == -1)
    {
        fprintf(stderr, "세마포어 제거 실패\n");
        exit(0);
    }
 
 
    return 1;
}


실행 결과는 다음과 같다.



다음과 같이 메시지를 주고 받을 수 있게 프로그램이 수행된다.







'CSE(컴퓨터 공학) > 유닉스 시스템' 카테고리의 다른 글

유닉스 과제 #3  (0) 2009.05.06
유닉스 과제2  (0) 2009.04.08
Posted by 태씽

(1) 주어진 파일을 Copy 하는 프로그램을 작성하되, copy SIGINT SIGQUIT을 받아도 죽지않고 COPY를 모두 마치닣후 종료하는 프로그램을 작성하라.

주어진 파일을 카피하는 과정이야 어떤 파일명을 받아서 그파일을 바이너리로 읽어 그대로 다른 파일명으로 써주면 된다. 쉽게 할 수 있는 과정인데 이꽈제는 SIGINT SIGQUIT의 기능을 먼저 이해를 해야 한다.

유닉스에서는 signal.h 헤더파일에 정의된 시그널 이름들이 있는데 그중에 SIGINT, SIGQUIT이 있다


#define SIGINT :
인터럽트를 위한 시그널로 유저가 인터럽트를 발생시키는 키를 입력했을 때 그와연결된 프로세스에세 커널이 보내는 시그널이다. 이 시그널은 프로세스를 종요할 때 많이 사용되는 시그널이다.이것은 터미널에서 ctrl+c와 같은 역활을 한다.

#define SIGQUIT : Quit
를 위한 시그널로 유저가 터미널에서 Quit키를 치면 커널이 프로세스에게 SIGQUIT 시그널을 보낸다


그러면 C언어상에서 이들 시그널을 어떻게 이용을하는가 하는것에 대한 궁금증이 생길텐데 한번 예제코드를 이용해서 살펴보도록하자.

signal()
이라는 함수가 있는데 이 함수는 이름그대로 시그널을 처리하는 함수 이다. signal 함수는 다음과 같이 나타낼 수 있다.

 int sigkind;
int function();
signal(sigKind, function);


여기서 sigKind에 바로 SIGINT, SIGQUIT같은 것이 들어가는것이다.
그리고 function sigKind의 함수가 호출 되었을때 실행되는 함수 이다
.

이제 이 signal함수를 이용해서 간단한 코드를 작성해 보자

 

 #include<stdio.h>
#include<signal.h>

int handler()
{

//필요한 작업을 처리한후에 프로그램을 종요한다.
printf("\n\nSIGINT
핸들러 호출
\n");
printf("\n<<
작업 종료 시작
>>>\n");
sleep(1);
printf("\n\n
실행되는 모든 프로세스 종료
\n\n");
printf("All open file closed\n\n\n");
exit(1);

}

int main()
{

int result, step =0;
//signal
함수를 사용하여 SIGINT 핸들러와 SIGQUIT핸들러를 등록한다.
printf("signal
함수를 사용하여 SIGINT 핸들러를 SIGQUIT핸들러를 등록한다
.\n\n");
result = signal(SIGINT, handler);
result = signal(SIGQUIT, handler);

//
무한루프 프로그램을 돌린다
.
printf("
메인 프로세스 실행
.\n");
while(1)
{

step++;
printf("%d
번째 작업 수행\n", step);
sleep(1);

}
return 1;

}




위의 코드를 실행하면 무한 루프대로 작업수행 메시지가 뜰것이고 시그널이 들어오면 핸들러 함수가 동작 하고 프로그램이 종료가 될 것이다. 실행을 시켜보자. 프로그램 실행도중 ctrl + c 또는 ctrl + \ 키를 눌러보자.

 ktss1023@ktss1023-desktop:~/바탕화면$ ./a.out
signal
함수를 사용하여 SIGINT 핸들러를 SIGQUIT핸들러를 등록한다
.
 
메인 프로세스 실행
.
1
번째 작업 수행

2
번째 작업 수행
3
번째 작업 수행


SIGINT
핸들러 호출

<<
작업 종료 시작>>>


실행되는 모든 프로세스 종료


All open file closed



다음과 같이 잘 실행이 될 것이다.

그런데 이것으로는 과제의 내용에 합당하는 문제를 풀수가 없다. 그러면 어떤 시그널이 들어올때 그시그널을 미리 block을 시킬수 있는 함수가 있다면 좋을 것이다. 바로 그것이 문제를 해결 하기위한 함수이다. 어떤함수가 있는지 한번 살펴 보자.

int sigemptyset(sigset_t * set)

set 이 가리키고 있는 시그널 집합을 초기화 한다.

성공시에 0 return 하고, 실패시에 -1 return 한다.

int sigaddset(sigset_t * set, int signum)

set 이 가리키고 있는 시그널 집합에 signum을 추가한다.

성공시에 0 return 하고, 실패시에 -1 return 한다.

int sigdelset(sigset_t * set, int signum)

set 이 가리키고 있는 시그널 집합에 signum을 삭제한다.

성공시에 0 return 하고, 실패시에 -1 return 한다.

int sigprocmask(int how, const sigset_t * set, sigset_t * oldset)

시그널 마스크를 검사하고 변경하기 위해서 사용된다. 간단히 말해서 해당 시그널에 대해서

BLOCK, UNBLOCK 를 하기 위해서 사용한다.

 

how option

SIG_BLOCK

새로운 시그널 마스크는 현재의 시그널 마스크와 set에 의해 지정된 시그널 마스크의 합집합이다.

, set는 블록 시키고자 하는 추가적인 시그널들을 포함한다.

SIG_UNBLOCK

새로운 시그널 마스크는 현재의 시그널 마스크와 set로 지정된 시그널 마스크의 보수의 교집합이다.

, set는 블럭에서 해제시킬 시그널들을 포함한다.

SIG_SETMASK

새로운 시그널 마스크는 set로 지정된 시그널 마스크이다.

시그널 마스크를 변경하였다가 이전 시그널 마스크로 복귀시키고자 할 때, 원래의 시그널 마스크를

저장하였다가 SIG_SETMASK 옵션을 사용해야 한다

sigprocmask 는 성공시에 0 return 하고, 실패시에 -1 return 한다.


바로 이런 함수이다. sigset_t * set 집합을 하나 선언하고 집합에 SIGINT, SIGQUIT을 추가 한뒤int sigprocmask(int how, const sigset_t * set, sigset_t * oldset) 함수를 이용해서 SIG_BLOCK을 해주면 된다.

문제를 풀기 전에 이 함수를 이용해서 아까의 프로그램을 약간 변형하는 형태의 프로그램을 작성해보자.

 

 #include<stdio.h>
#include<signal.h>

int main(void)
{
int result, step =0;
sigset_t* set, oldset, pendset;//BLOCK
signal set의 변수를 선언,

//
셋을 초기화 시킨다
.
if(sigemptyset(&set)<0)
{
printf("sigemptyset error\n");
exit(1);
}

//
블록할 시그널 등록

if(sigaddset(&set, SIGINT)<0)
{
printf("sigaddset error\n");
exit(1);
}

//
블록할 시그널 등록
if(sigaddset(&set, SIGQUIT)<0)
{
printf("sigaddset error\n");
exit(1);

}

//
시그널 블록을 해준다.
printf("
시그널 블록 시작
\n\n");
printf("5
초만기다려봐
\n");
if(sigprocmask(SIG_BLOCK, &set, &oldset)<0)
{
printf("
블록 에러
");
exit(1);
}



sleep(5);

if(sigpending(&pendset)<0)
{
printf("sigpending error");
exit(1);
}

if(sigismember(&pendset, SIGINT)||sigismember(&pendset, SIGQUIT))
{
printf("
작업이 진행중이다
.\n");
}


//
무한루프 프로그램을 돌린다
.
printf("
메인 프로세스 실행
.\n");
while(1)
{
step++;
printf("%d
번째 작업 수행
\n", step);
sleep(1);
if(step==20)break;

}


if(sigprocmask(SIG_SETMASK, &oldset, NULL) <0)
{
printf("unblock error");
exit(1);
}
printf("SIGQUIT,SIGINT
가 언블록되었다
\n\n");


return;
}



위의 프로그램은 처음 5초간 기다리면서 신호를 받아 그신호가 SIGINT, SIGQUIT이면 메시지를 출력할려고 그랬는데 이걸지속적으로 할려면 타이머나 스레드를 돌려서 해야 될 듯 하다. 그리고 sigprocmask 함수를 이용해서 SIGINT,SIGQUIT의 신호를 막았다. 그러므로 실행하면 작업이 끝나기전에는 신호가 블록이 되어 동작하지 않는다.
자 그렇다면 이제 위를 토대로 문제를 해결하면 된다. 작업에 파일을 복사하는 작업을 하면 되는것이다. 처음에 폴더내에있는 파일명들을 출력해주고 파일명을 입력 받고 복사해주면 되는 형식으로 작성을 해보자.

#include<stdio.h>
#include<signal.h>
#include<fcntl.h>

#define LENGTH 256

static void sig_int(int);

int main()
{
char filename[LENGTH];//
파일이름은 100자를 초과할 수 없다.

char c_filename[LENGTH];//
복사할 파일 이름


char buf[LENGTH];//
버퍼


int result= 0;
int readCnt, writeCnt, orgFile, newFile;

sigset_t* set,oldset;//BLOCK
signal set의 변수를 선언,    

//
복사할 파일 오픈

printf("
복사할 파일 이름을 입력하시오 : ");
scanf("%s",filename);
orgFile = open(filename, O_RDONLY);

if(orgFile<0)
{
    printf("
없는 파일입니다
.\n");
    return -1;
}

//
복사 당할 파일 생성

printf("
생성할 파일 이름을 입력하시오 : ");
scanf("%s",c_filename);
newFile = open(c_filename, O_WRONLY|O_CREAT|O_APPEND);

if (signal(SIGINT, sig_int) == SIG_ERR)
{
printf("signal error\n");
return -1;
}
if (signal(SIGQUIT, sig_int) == SIG_ERR)
{
printf("signal error\n");
return -1;
}

//
셋을 초기화 시킨다
.
if(sigemptyset(&set)<0)
{
printf("sigemptyset error\n");
return -1;
}

//
블록할 시그널 등록

if(sigaddset(&set, SIGINT)<0)
{
printf("sigaddset error\n");
return -1;
}

//
블록할 시그널 등록
if(sigaddset(&set, SIGQUIT)<0)
{
printf("sigaddset error\n");
return -1;

}

//
시그널 블록을 해준다.



/*
sleep(5);

if(sigpending(&pendset)<0)
{
printf("sigpending error");
exit(1);
}

if(sigismember(&pendset, SIGINT)||sigismember(&pendset, SIGQUIT))
{
printf("
작업이 진행중이다
.\n");
}
*/
printf("
시그널 블록 시작
\n\n");
if(sigprocmask(SIG_BLOCK, &set, &oldset)<0)
{
printf("
블록 에러
");
return -1;
}


//
프로그램을 돌린다
.
printf("
복사 시작
!\n");

for(readCnt=1;readCnt>0;)
{

    readCnt = read(orgFile, buf, LENGTH);
    writeCnt = write(newFile, buf, LENGTH);
    
    /*
    step++;
    if(step%2==0)
    {
        printf("1
초만쉬어요
.\n");
        sleep(1);
    }
*/
    printf("%d, %d\n", readCnt, writeCnt);


}

printf("SIGQUIT,SIGINT
가 언블록되었다
\n\n");
}

printf("
복사끝
\n");

close(orgFile);
close(newFile);

if(sigprocmask(SIG_SETMASK, &oldset, NULL) <0)
{
printf("unblock error");
return -1;
}

static void sig_int(int signo)
{
    printf("
신호확인
\n");
    return;
}

하지만 이코드로는 왠일인지 파일 복사가 진행이 되지 않는다. 대체 무슨 연유일까? 이것만으로는 해결하기가 어렵다는 결론으로 sigaction이라는 함수를 찾아 보았다.

sigaction()

sigaction은 시그널을 취급할 방법을 선택 할 수 있다.

헤더파일

#include <signal.h>

원형

int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);

인자

첫번째 : 행동을 지정할 개개의 시그널

두번째 : 지정하고 싶은 행동

세번째 : 나중에 복구를 위해 현재 값을 저장한다.

다음과 같이 시그널의을 취급하는 방법을 선택하는 함수이라고 하는데.
일단, sigaction 구조체에 대해서도 알아봐야 할 것이다.

struct sigaction {
    void (*sa_handler)(int);
    void (*sa_sigaction)(int, siginfo_t *, void *);
    sigset_t sa_mask;
    int sa_flags;
    void (*sa_restorer)(void);
}
sa_handler

signum번호를 가지는 시그널이 발생했을 때 실행된 함수를 설치한다. 함수외에도 SIG_DFL SIG_IGN을 지정할 수 있다. 전자는 시그널에 대한 기본행동을 후자는 시그널을 무시하기 위해서 사용한다.

sa_mask 

sa_handler에 등록된 시그널 핸들러 함수가 실행되는 동안 블럭되어야 하는 시그널의 마스크를 제공한다. SA_NOMASK가 적용되어 있지 않다면

sa_flags 

시그널 처리 프로세스의 행위를 수정하는 일련의 플래그들을 명시한다. 다음중 하나 이상의 것들에 의해서 만들어 진다.

SA_NOCLDSTOP 

만약 signum SIGCHLD라면, 자식 프로세스가 SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU등을 받아서 중단되었을 때 이를 통지 받을 수 없게 된다.

SA_ONESHOT, SA_RESETHAND

일단 시그널 처리기가 호출되면, 기본 상태에 대한 시그널 액션을 재 저장한다. 이는 signal(2)호출에 대한 기본 행위이다.

SA_RESTART 

일부 시스템 호출들이 시그널을 통해 재시작할 수 있도록 함으로서 BSD 시그널과 호환되도록 한다.

SA_NOMASK, SA_NODEFER

시그널이 자체 시그널 처리기로부터 수신 받지 않도록 한다.

SA_SIGINFO 

시그널 처리기가 하나가 아닌 3개의 인자를 취할경우 sa_handler대신 sigaction siginfo_t를 이용할 수 있다. siginto_t는 다음과 같이 정의된 구조체이다.

[

 

다음과 같은 구조체를 지니는데 각구조체의 역확은 예제 코드에서 알아보자.

-------------------------------------------------------

---------------------test.c----------------------------

-------------------------------------------------------

//sigaction() 사용하기
//
시그널을 취급할 방법을 선택할 수 있다.
#include <stdio.h>
#include <signal.h>
//sigaction()

int main(void)
{
 static struct sigaction act;
//행동을 지정할 구조체

 void catchint(int); //행동할 함수(함수를 바꿈으로 인터럽트시 행동을 조절 할 수 있다.)

 act.sa_handler = catchint; //구조체 변수에 취해질 행동을 지정한다.
 
 sigfillset(&(act.sa_mask));
//시그널을 포함하도록 집합을 완전 채운다.(?)
 
 //SIGINT : 인터럽트를 프로세스에게 보낸다.
 //&act
지정된 행동
 //
현재값은 0으로(나중에 복구하기 위해 지정할 수 있다.)
 sigaction(SIGINT, &act, NULL);
 
 //프로세스 실행
 printf("sleep call #1\n"); sleep(5);
 printf("sleep call #2\n"); sleep(5);
 printf("sleep call #3\n"); sleep(5);
 printf("sleep call #4\n"); sleep(5);

 printf("Exlting\n");
 exit(0);
}

//실행 함수
//
인터럽트를 칠때 커널에 의해 프로세스에게 보내진다.
void catchint(int signo)
{

 printf("\nCATCHINT : signo = %d\n", signo);
 printf("CATCHINT : returning\n\n");
}

==================================================================


다른 블로그의 글을 퍼온 코드인데 이해 하기가 쉬울것이다. 그러니까 sigaction signal 함수를 좀더 발전? 시킨것이다. 이를 토대로 코드를 한번 작성해보자.

#include<stdio.h>
#include<signal.h>
#include<fcntl.h>
#include<stdlib.h>

#define LENGTH 256

void sigcatch(int); //
행동할 함수(함수를 바꿈으로 인터럽트시 행동을 조절 할 수 있다.)

int main(void)
{
    char filename[LENGTH];//
파일이름은 100자를 초과할 수 없다
.

    char c_filename[LENGTH];//
복사할 파일 이름


    char buf[LENGTH];//
버퍼

    int result= 0;
    int readCnt, writeCnt, orgFile, newFile;

    static struct sigaction act; //
행동을 지정할 구조체
    
    act.sa_handler = sigcatch; //
구조체 변수에 취해질 해동을 지정한다.
 
    sigfillset(&(act.sa_mask)); //sigaction
구조체의 sigset을 모든 신호를 다 채운다
.
    //
이는 sigaddset함수를 이용해 SIGINT SIGQUIT만 선택해도 된다
.
    act.sa_flags = 0;
   
    //SIGINT :
인터럽트를 프로세스에게 보낸다
.
    //&act
지정된 행동

    //
현재값은 0으로(나중에 복구하기 위해 지정할 수 있다.)
    if(sigaction(SIGINT, &act, NULL)==-1)
    {
        perror("sigaction error\n");
    }
    if(sigaction(SIGQUIT, &act, NULL)==-1)
    {
        perror("sigaction error\n");
    }
    //


    //
복사할 파일 오픈

    printf("
복사할 파일 이름을 입력하시오 : ");
    scanf("%s",filename);
    orgFile = open(filename, O_RDONLY);
    
    if(orgFile<0)
    {
        printf("
없는 파일입니다
.\n");
        return -1;
    }
    
    //
복사 당할 파일 생성

    printf("
생성할 파일 이름을 입력하시오 : ");
    scanf("%s",c_filename);
    newFile = open(c_filename, O_WRONLY|O_CREAT|O_APPEND);


    //
프로그램을 돌린다
.
    printf("
복사 시작
!\n");

    for(readCnt=1;readCnt>0;)
    {
        readCnt = read(orgFile, buf, LENGTH);
        writeCnt = write(newFile, buf, LENGTH);
    
           /*
             step++;
            if(step%2==0)
            {
                printf("1
초만쉬어요
.\n");
                sleep(1);
            }
        */
        printf("%d, %d\n", readCnt, writeCnt);

    
    }

    printf("
복사끝
\n");

    close(orgFile);
    close(newFile);
}

//
실행 함수

//
인터럽트를 칠때 커널에 의해 프로세스에게 보내진다.
void sigcatch(int signo)
{

 printf("\nsigno = %d
신호가 들어왔습니다
.\n", signo);
 printf("
파일 복사가 진행중입니다.\n\n");

}

단순히 텍스트 파일 복사를 시험하였고 복사가 빨리 진행되므로 255바이트 마다 1초간 sleep함수를 실행했다.
결과는




(2) alram() SIGALRAM을 사용하여 timeout을 가지고 file read하는 함수를 작성하시오.

일단 alarm() SIGALRM에 대해서 알아 보아야 할것이다. 우선 alarm함수는 시그널을 전달하기 위해서 사용하는 함수로 전달되는 시그널이 SIGALRM이다.

alarm seconds 초 후에 프로세스에 SIGALRM 을 전달한다. 만약 seconds 0이라면 결코SIGALRM 이 전달되지 않을것이다. 만약 alarm 이 여러개 쓰인다면 기존에 설정되었던 alarm 설정값은 취소되고가정최근의 alarm 설정값으로 지정된다.

그러므로 alarm 을 사용할때는 alarm 이 겹치지 않도록 주의해야 한다.

SIGALRM 의 기본 행동은 프로세스 종료이다.

이렇게 나와 있는 예제프로그램을 한번 보자.

#include <unistd.h>
#include <signal.h>

void myalarm()
{
   
printf("ding dong dang\n");
}

int main()
{
   
printf("alarm setting\n");
    // SIGALRM
이 발생하면 myalarm() 함수를 실행한다.
   
signal(SIGALRM, myalarm);
    //
알람을 1초로 설정한다.
   
alarm(1);
  

 while(1)
    {
       
printf("ok\n");
        //
신호를 기다린다.
       
pause();
        // alarm
2초로 설정한다.
       
alarm(2);
    }
}

다음과 같이 signal 함수를 이용해서 SIGALRM이 발생할 경우 myalarm함수가 발생하도록 했다.
위코드를 토대로 타임아웃을 주는 파일을 리드하는 프로그램을 작성하자. 읽은 파일은 화면에 출력하는것으로 한다.

#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>

void myalarm()
{
    printf("\n
파일리드를 종료합니다.\n");
    exit(0);
}

int main()
{
    FILE *fp;//
리드할 파일포인터

    char f_name[200];//
파일이름
    char buf;//1
바이트짜리 버퍼
    int limit;//alarm
의 수를 결정

    printf("
읽을 파일이름을 입력하세요 : ");
    scanf("%s",f_name);
    
    if(!(fp = fopen(f_name,"r")))
    {    
    printf("
파일이 잘못되었습니다
.\n");
    return -1;
    }    

    printf("
몇초후 타임아웃하실건가요
: ");
    scanf("%d",&limit);

    signal(SIGALRM, myalarm);
    
    alarm(limit);
    printf("alarm setting\n");
    // SIGALRM
이 발생하면 myalarm() 함수를 실행한다
.
   

    while(!feof(fp))//
파일은 1바이트씩 읽고 출력한다
.
    {
        printf("%c",fgetc(fp));
        sleep(1);
    }
    return 0;    
}

위 프로그램은 미리 alram을 설정하고 그동안 1바이트씩을 읽고 출력한뒤 sleep(1)을해주는 프로그램으로 20초동안만 파일을읽고 출력이 된다.

 

 

 

'CSE(컴퓨터 공학) > 유닉스 시스템' 카테고리의 다른 글

유닉스 과제 #4  (0) 2009.05.30
유닉스 과제2  (0) 2009.04.08
Posted by 태씽
줄여서 약자 CSP 이야 이번장 부터는 문제를 이용해서 이론을 도출하는 식으로 한번 공부를 해볼려고 한다.

먼저 기본적인 개념을 잡고 가자
우선 Constraint satisfaction problems(CSP) 문제를 푸는데 있어서 어떤 제약을 만족해야 되는 그런 문제를 말한다.

state는 Variable Xi 로 나타내고, domain Di 에서 오는 value 값을 지닌다.
goal테스트를 만족하기 위해서 set of constarint를 만족 하여야 한다.

이것을 간단히 Map-coloring 예제로 나타내면 다음 그리과 같다.

다음과 같이 Varialble은 지도의 지역들 지역들이 가지는 색깔값들은 domain Di에서 오게 되고 Constraint는 위와 adjacent 하는 지역은 다른 컬러를 지녀야 한다는 것이다.


1. 강의록 12 ~ 13 페이지에 소개된 backtracking search를 이용하여 4-queens problem을 풀면 어떻게 될지 강의록 17 페이지에 보인 것과 같은 형태로 그려보라.

먼저 backtracking search가 어떻게 돌아가는건지 한번 알아보도록 하자.

다음과 같이 Varialble은 지도의 지역들 지역들이 가지는 색깔값들은 domain Di에서 오게 되고 Constraint는 위와 adjacent 하는 지역은 다른 컬러를 지녀야 한다는 것이다. 이것을 토대로 이제 문제도 한번 풀어보자.

이런식으로 문제를 쉽게 풀 수 있다.

2. Backtracking search를 이용하여 graph coloring problem을 풀기 위해 most constrained variable과 most constraining variable 및 least constraining value heuristic을 모두 사용하면서 forward checking까지 적용하고자 핚다. 아래 graph의 node들에 {Blue, Green, Red}를 칠핛 경우 생성되는 search tree를 그려보라. 단, variable이나 value의 우선 순위가 같을 경우에는 그 이름의 alphabet 순을 따라 선택핚다.
이문제를 풀기위해서 백트래킹도 알아야 하겠지만 most contrained variable 과 most contraining variable, least constraining value heuristic, forward cheking 까지 알아야 한다.

most constrained variable
fewest legal value를 선택을 한다.

most constraining variable
영향을 제일 많이 주는 variable 부터 선택을 한다.

least constraning value
영향을 가장 적게 주는 value 부터 선택한다.
-> 남아 있는 variable중 fewest value 선택

forward cheking
어떤 variable 이든 더이상 legal value가 존재 하지 않으면 종료를 하는것이다. variable에 value를 assign 하면서 다른 남은 variable들에게 어떤 value가 assign될 수 있는지 항상 체크 하는것이다.


요렇게 푸는 것이다.

3. 위 2번 graph의 B에는 Red 그리고 F 에는 Green이 지정되어 있는 상태에서 forward checking과 arc consistency algorithm을 적용하고자 핚다. 교과서 Figure 5.7의 AC3 algorithm을 이용핛 경우 종료 시까지 총 몇 개의 arc가 처리되고 몇 개의 arc가 다시 queue로 insert되며 또핚 최종 결과는 어떻게 되는가? 단, queue에는 arc들이 다음과 같은 순서로 들어 있다고 가정핚다: AB, BA, AD, DA, AE, EA, BC, CB, BE, EB, CE, EC, CF, FC, DE, ED, EF, FE.

Arc consistency 가 뭔지를 알아야 한다.








'CSE(컴퓨터 공학) > 인공지능' 카테고리의 다른 글

Informed Search and Exploration  (0) 2009.04.18
인공지능 솔루션  (0) 2009.04.17
Solving problem by searching (1)  (0) 2009.04.02
Posted by 태씽
본 포스팅은 부산대학교 정보컴퓨터 공학부 4학년 학생이 인공지능 수업을 들은 내용을 토대로 작성한 것입니다. 본 포스팅의 내용의 신빙성을 책임지지는 않습니다.
--------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
Informed Search Strategies

우리는 이전 내용에서 Searching에 의해서 문제를 해결하는 쉽게 이야기 해서 어떤 문제의 해답을 서치하는 몇가지 방법들을 살펴 보았다. 간단히 Review를 해본다면

먼저 중요한 용어 Fringe라는 용어가 있었다. Fringe는 Expand하기를 원하는Node들의 집합이다. 일반적으로 구현이 될때 queue로 구현이 된다. 그리고 Depth는 solution을 찾기위해 search를 할 때 만들어지는 Searching tree의 깊이, path cost는 한node에서 다른 node로 가는 비용이라 할 수 있다.

Breadth-first Search : 이건 같은 Depth의 fringe상에 있는 node들을 차례대로 expand 한다. Breadth가 먼저 즉 fringe들을 다 expand 하고 다음 Depth로 넘어간다.
Uniform Cost Search : depth의 수치보다 코스트의 수치로 프린지에 있는 노드를 선택해 expand한다.
Depth-first Search : 이건 Depth first, 즉 한쪽의 모든 Depth를 search 한다. 그다음 옆으로 이동한다.
Depth-limited Search : Depth-first에 limit를 준다.
Iterative Deeping Search : Depth-limited의 limit를 증가 시킨다.
Bidirectional Search : Start(initial) 과 Goal에서 동시에 뻐어 나온다. 그래서 제일 먼저 만나는것을 솔루션으로 한다.
이런것들을 알아 보았다. 위의 Searching 방법들의 성능을 비교한 것은 다음과 같다.

위의 전술들은 모두, Time과 space가 어떤 변수에 대해 exponential 하다. 이문제를 해결 하기 위해 이제 부터 우리는 Informed Search를 한번 배워 보자. 인공지능적인 요소는 여기서 부터 나오는 것이다.

먼저 이 Informed search strategies에는
Apply evaluation function to determine the order of the nodes in the queue.
평가 함수가 존재한다. 이평가함수는 큐속에 있는 노드들의 순위를 결정한다.
Evaluation function f(n):
바로 평가 함수 f(n) 파라미터는 어떤 한 노드 n 이다.
f(n) =distance through node n to the goal
노드 n부터 goal 까지의 distance, 즉 거리이지만 평가 값이라고 할 것이다.
Comes from problem-specific knowledge
problem-specific knowledge에서 이값을 도출할 수 있다.
Priority queue maintains the order of the fringe nodes.
프린지노드의 순서를 우선순위 큐로 결정할 수 있다.

Components of evaluation function:
그리고 평가함수의 구성요소를 살펴보자.
h(n):heuristic function
휴리스특 펑션 h(n)이 있다.
h(n) =estimated cost of the cheapest path from node n to the goal
이 h(n)은 노드 n에서 goal 까지 가장 짧은거리를 추측해보는건데 우리가 주로 보는 내용이 길찾기 이런게 많기 떄문에 f(n)은 노드 n에서 골까지의 직선거리로 추측하기도 하고 그런것이다.
g(n):path cost from the start node to n
이건 우리가 앞에서도 봤었던 시작 노드부터 노드 n 까지의 path cost이다.

만약 여기서 f(n) = h(n) 이라면 이건 단지 평가를 휴리스틱 함수로만 한것이다. 그리고 f(n) = g(n) 이라면 이것은 uniform cost search 이다 평가 기준이 path cost 이기 떄문이다.

이제 이 f(n)을 이용한 search 방법들에 대해서 알아보도록 하자.

Greedy best-fit search
일단 먼저 위의 그림은 루마니아의 지도인데. 오른쪽의 직선거리가 각 노드에서 Bucharest까지의 직선거리가 있다. 우리는 이것을 h(n), 휴리스틱 펑션값으로 이용을 할 것이다. Greedy best-fit search란 f(n)을 바로 휴리스틱 펑션만으로 판단하는 것이다.
즉 f(n) = h(n) 이렇게 되는 것이다. 이것을 바탕으로 Arad에서 Bucharest까지의 최단거리를 가지는 Path를 찾아 보자. 상당히 간단하다.

노드를 expansion하는 기준이 h가 가장 작은 노드이다. 즉 h값이 가장 작은 순서대로 queue에 들어 가있다고 생각하면 된다.
depth와 breadth에 전혀 관계가 없다.

Take the biggest bite possible the name “greedy search”
Greedy best-fit search는 가장 가능성이 큰것을 취한다. 이름이 그리디 서치이다.

Evaluation:
Neither optimal nor complete(cf: depth-first search)
이것은 옵티말 하지도 컴플리트하지도 않다.
Time and space complexity
Retains all nodes in memory
메모리안에 모든노드가 있다.
O(b^m), m:maximum depth of the search space
b의m승 오더가 적용이 되는데 m은 가장 깊은 depth 즉, 서치한트리에서 가장 깊은 depth값이다.
Good heuristic function can reduce the space and time complexity.
좋은 휴리스틱 펑션이 space와 time complexity를 줄일 수 있다.

이제 이것보다 약간 발전된 형태인 A* Search에 대해 알아보자.

A*Search

Minimizes the total estimated solution cost
추측된 총 솔루션 코스트를 최소화 시킨다.
Combination of greedy best-first search and uniform-cost search
A* 서치는 쉽게 이야기 해서 greedy best-fit 서치와 uniform-cost 서치의 콤비네이션 즉 합친거다
f(n) = g(n) + h(n)
그래서 평가함수 f(n)은 g(n)과 h(n)을 더한 결과가 된다.
g(n):path cost from the start node to n
h(n):estimated cost of the cheapest path from nto the goal
f(n):estimated cost of the cheapest solution through n
위의 설명은 저 위에서 수차례했으니 패스 바로 위의 지도에서 solution을 찾는 서치트리를 만들어보면

역시 위의 방법은 비슷하나 평가 함수에 g(n)이 들어오게 딘다.

Theorem:
이것에 Theorem에 대해서 보자.
A*using Tree-Search is optimal if h(n)never overestimates the cost to reach the goal. (Such an h(n)is called an admissible heuristic.)
A* 서치는 한가지 조건만 충족이 된다면 옵티말 하다. 바로 h(n)을 측정할때 h(n)이 실제보다 큰값으로만 측정 되지 않으면 된다.(이런 h(n)이 admissible heuristic이다.)

Proof :
Let C*be the cost of the optimal solution.
C*를 옵티말 솔루션의 코스트라고 하자
Suppose a suboptimal goal node G2 appears on the fringe. Then,
서브옵티말(옵티말하지는 않는다는것이다.) 골노드 G2가 프린지 상에 나타나게 된고 가정하자. 그러면
f(G2) = g(G2) + h(G2) = g(G2) > C*
G2에서 골까지 가는 평가 함수값 = 시작노드에서 G2까지의 path cost + G2에서 골까지의 h값  = g(G2) > C*
But, for a fringe node n that is on an optimal solution path
하지만 프린지 노드 n은 옵티말 솔루션 패스이므로
f(n) = g(n) + h(n) <= C*
이렇게 되고
Since f(n) <g(G2), G2 will not be expanded.
결구 f(n)< g(G2) 가 되고 G2가 expand가 되지 않는다. 역시 증명의 길은 어렵다는것을 꺠닫게 되는구나.

A*is optimal and complete.
A*는 옵티말 하고 컴플리트 하다. 단 h가 overestimate 하지않는다면 말이다.

Time and memory complexity:
Exponential time complexity
역시 exponential time complexity를 지니게 된다.
Perfect h->no search (practically impossible)
퍼펙트한 h -> 서치가 없게 되지 이건 불가능하다.
Exponential memory complexity
exponential한 메모리 complexity를 지니게 된다.

A*is optimally efficient for any given heuristics.
A*는 어떤 주어진 휴리스틱에도 옵티말하게 효율적이다.
Search is done efficiently by pruning the subtrees below the nodes with f(n) > C*.
서치는 서브트리를 가지치기 하면서 완료가 되는데 어떤서브티리이냐 하면 f(n) > C*것의 node 밑의 서브트리를 가지치기 한다.
No other optimal algorithm is guaranteed to expand fewer nodes than A*.
A*다 더적게 노드를 expand하는 옵티말 알고리즘은 없다.(이것이 중요하다.) 하지만 아직은 시간과 공간의 complexity가 부담이 된다. 좋은 휴리스틱 펑션을 찾는것이 필요하다. 그것은 유니폼 코스트 서치를 사용하는것보다 훨씬 더 좋게 된다는 말이 된다.
 
당연한 법칙 3가지를 소개 하면
Recall that f(n) = g(n) + h(n)
h= 0, uniform cost search g(n) -> path cost만을 이용해서 판단
g = 1, h= 0 breadth-first search -> 이것은 모든 노드를 차례대로 expand 해야한다. 판단기준이 모두 같기 때문에
g= 0 greedy best-first search -> 이것은 h(n)으로만 판단 하는 greedy best-fit 알고리즘과 같다.

이제 본격적으로 heuristic function에 대해서 알아보도록 하자.
8-puzzle problem을 예를 들어서 알아 보자.


h1= the number of tiles that are in the wrong position
h1 첫번쨰 휴리스틱은 잘못된 위치에 있는 타일의 개수이다.
h2= the sum of the distances of the tiles from their goal positions (Manhattan distance)
두번째 휴리스틱은 그들의 골포지션으로 부터 타일들의 거리의 총합이다. (맨하탄 디스턴스라고 한다.)
* Both are admissible: never overestimates
둘다 절대 overestimate 되지 않았다. h1같은 경우는 그러려니 싶지만 h2는 왜그런지 약간 헷갈릴 수도 있다. 이것은 타일들이 그위치에서 바로된 위치에서 거리보다도 그곳으로 실제로 가기위해서는 다른타일도 움직여야 하는 비용까지 더해지기 때문이다.

The total number of nodes expanded:
expand되는 노드의 총 개수는?
A*with effective branching factor b*(Figure 4.8)
브랜칭 팩터 b*r가 있다.
N= 1 + b* + (b*)^2+ (b*)^3+ … + (b*)^d, d :depth
요런식으로 expand 되는 노딍 총수를 구할수있다.

Dominating heuristic:
We say that h2 dominates h1 if for any node n,
h2가 h1을 어떤 노드 n에서든 dominate한다고 할 수 있는데
h2(n) >=  h1(n).
h2(n) >= h1(n)이기 떄문이 다.
It is always better to use a heuristic function with higher values, as long as it does not overestimates.
그러니까 정리를 하면 h값은 overestimate 되지않는 선에서 높은 값을 선택하는 것이 좋다.
그림에서 보게 되어도 h2가 depth가 커질수록 effective branching factor값이 더 많이 작아진다는 것을 알 수 있다.
그러므로 1 + b* + (b*)^2 + ..... + (b*)^d 인 expanded 노드의 총수 역시 작아진다는것을 알 수가 있다.

이제 좀더 확장된 주제로 넘어자 보자.
Inventing Admissible Heuristic Functions

Consider a relaxed problem:
relaxed problem에 대해서 생각해보자.
A relaxed problem is a problem with fewer restrictions on the action.
relaxed problem은 action에 있어서 제약이 더 없는 문제를 뜻한다.
The cost of an optimal solution to a relaxed problem is an admissible heuristic for the original problem.
relaxed problem에 대한 옵티말 솔루션의 코스트는 오리지널 문제에 대한 admissible 휴리스틱이다.
The optimal solution in the original problem is at least as expensive as the optimal solution in the relaxed problem. 
original problem에 있는 옵티말 솔루션은 적어도 relaxed problem에 있는 옵티말 솔루션과 비슷하게 expensive 할것이다.


8-puzzle의 예를 한번들어보자.
A tile can move from square Ato B if Ais horizontally or vertically adjacent to B and B is blank.
타일은 B가 비어있고 A와 수직또는 수평으로 근접할때 A에서 B로 이동이 가능하다.
 
Relaxed problems:
relaxed problem으로 생각하면
(a)A tile can move from square A to B if A is adjacent to B(h2)
A에 있는 타일은 A가 B에 adjacent할때 A에서 B로 이동이 가능하다 (h2)
(b)A tile can move from square A to B if B is blank.
A에 있는 타일은 B가 blank일떄 A에서 B로 이동이 가능하다.
(c)A tile can move from square A to B. (h1)
A에 있는 타일은 A에서 B로 이동이 가능하다. (h1)

Construction of a relaxed problem:
relaxed problem을 구축해보자.
Can be done automatically if a problem definition is written in a formal language
문제의 정의가 일반적인 언어로 쓸수 있다면 자동적으로 완료가 된다.

Trade off between accuracy and computation time:
정확도와 computation time을 trade off 한다.
It takes more time to derive more accurate heuristic.
좀더 정확한 휴리스틱은 더많은 시간을 소요할 것이다.

Using multiple admissible heuristics:
여러개의 admissible heuristic을 이용해보자
If a set of admissible heuristics h1,…, hm is available, and none of them dominates any of the others, we can use the
admissible 휴리스틱 h1,....의 집합이 있고 hm은 이용가능하며 그들중에 어떤것도 다른것을 dominate 하지 않는다. 
heuristic most accurate on the node in question:
휴리스틱은 어떤 노드에서 가장 정확한 휴리스틱을 선택하면 된다.
h(n) = max{h1(n),…, hm(n)}
그러므로 h(n)은 h1(n),......,hm(n)에서 가장 큰값을 선택하는것이다. 어짜피 집합은 admissible 한 휴리스틱이기 떄문에.

Consider a subproblem:
subproblem에 대해서 생각해보자.
Admissible heuristics can also be derived from the solution cost of a subproblem.
Admissible 휴리스틱들은 또한 subproblem의 솔루션 코스트로 부터 이끌어 낼 수 도 있다.
Can be substantially more accurate than Manhattan distance in some cases
어떤경우에는 맨하탄 디스턴스 모다 훨씬 정확할 수도 있다.


Pattern databases:

패턴 데이터베이스
Store exact solution costs for every possible subproblem instance (every possible configuration of four tiles and
모든 가능한 subproblem instance(4개의 타일과 blank의 모든 가능한 설정)에 대한 모든 가능석에 대한 정확한 소루션 코스트들을 저장한다.
blanks).
The database is constructed by searching backwards from the goal state and recording the cost of each new pattern
데이터베이스는 골스테이트로 부터의 searching backwards와 각각 새로운 pattern encountered의 코스트의 레코딩에의해 구축이 된다.
encountered.
We could construct databases for 5-6-7-8, 2-4-6-8, and so on.
우리는 5-6-7-8, 2-4-6-8 등등으로 데이터 베이스를 만들수가 있다.
These heuristics can be combined by taking the maximum value.
이들 휴리스틱은 최대의 값을 combine 할 수 있다.
The number of nodes generated can be reduced by a factor of 1,000 when solving random 15-puzzles compared with
노드의 갯수는  15-puzzle 문제에서는 1000개의 팩터정도를 제거 할 수 있다. 이것은 맨하탄 디스턴스를 쓸때 비해서 이다. 패턴 데이터 베이스를 쓸때이다.
using Manhattan distance.


Disjoint pattern databases:
패턴 데이터 베이스 분리

Example:
예를 들어서
Construct 1-2-3-4 database and the 5-6-7-8 database.
1-2-3-4 데이터 베이스와 5-6-7-8 데이터베이스를 구축한다.
Record not the total cost of solving the subproblem 1-2-3-4 (5-6-7-8) but just the number of moves involving 1-2-3-4
(5-6-7-8).
subproblem을 solving한 코스트의 총합을 기록하는것이 아니지만 subproblem의 move의 수를 기록한다.
Use the sum of the two costs → still admissible
두개의 코스트의 합을 더해도 아직 admissible 하다.
The number of nodes generated can be reduced by a factor of 10,000when solving random 15-puzzles.
15-puzzle에서 10000개 팩터를 제거, 등 스피드 업이 있다.
A speedup of 1,000,000for 24-puzzles.
==========================================================================================================================
Learning Heuristics from Experience
경험에서 오는 러닝 휴리스틱
Optimal solutions to an 8-puzzle provide examples from which h(n)can be learned.
8-puzzle에 옵티말 솔루션은 h(n)이 배울수 있는데서 오는 예제를 제공한다.

State is described by a set of features
state는 튿징들에 의해서 설명될 수 있는데.
x1(n): # of misplaced tiles
x1(n)은 잘못배치된 타일들이다
x2(n): # of pairs of adjacent tiles also adjacent in the goal state
x2는 adjacent된 타일쌍들의 갯수이고 또한 골스테이트에 근접한것도 된다.
Then, derive a linear combination (find best fitting ci’s)
그러면 선형 조합에서
h(n) = c1x1(n) + c2x2(n)
위와 같은 식을 얻게 되는것이다.
------------------------------------------------------------------------------------------------정말애매하군.

Local search algorithm

In many problems, the path to the goal is irrelevant.
많은 문제들에서 골까지의 path는 irrelevant 하다.
Example: 8-queens problem
예를들어 8-queens problem이 있다.
Order of adding queens is irrelevant
queen을 추가하는 순서는 관계가 없다.

Neighborhood search:
이웃 서치
Local search algorithms operate using a single current state and move only to its neighbors.
local search 알고리은 single current state을 사용하고 오직 자신의 이웃에 이동할 때만 동작하게 되된다.
여기서 state란 바로 어떤 문제를 해결하기 위해서 진행이 될때 그상태 어떻게 진행 되었는지 상태 뭐이런것들이다.
Start with a complete configuration and make modifications to improve its quality
완벽한 설정과함께 시작하고 퀄러티를 향상시키기 위해서 변경을 한다.

Useful for solving optimization problems:
Find the best state according to the objective function.
목표하는 함수를 위한 가장 좋은 state를 찾는다.


Local search algorithm의 예를 보자 이것의 neighborhood configuration의 후보자들을 보면 서로 인접해있는 것들끼리 바꾸는것을 알수있다. 한번에 하나씩! 이제 이런느낌의 알고리즘을 보게 될것이다 그것이 바로 Hill-climbing search이다.

State space landscape
Location: state
기로 : 스테이트 스페이스
Elevation: heuristic cost function or objective function
세로 : 휴리스틱 혹은 오브젝티브 펑션,
어떤 스테이트에서의 휴리스틱펑션값이나 오브젝티브 펑션값이 높으면 높을 수록 좋다.



이런게 노올 수가 있다. 어떤 스테트에서 가장 높은 값을가지는 objective function값을 가지는것을 찾는 것이 궁국적인 목표이다. 하지만 그것은 힘들고 local maximum이라도 잘찾으면 나름 성공적인 서치가 될 것이다.

Hill-climbing Search

Also called as greedy local search:
그리디 로컬 서치라고도 불리는데 그러는걸 보면 로컬 서치 알고리즘이기는 한가 보다.
Continually moves in the direction of increasing value
계속적으로 값이 오르는쪽으로 이동을 하게 된다. 그래서 언덕을 오르는 서치라는 이름이 붙은것이다. 수도코드를 보면

function Hill-Climbing(problem) returnsa state that is a local maximum //로컬 맥시멈인 스테이트를 리턴하게 된다.
inputs: problem, a problem//인풋으로는 문제가 들어가고
local variables: current, a node//local variable로서 현재노드와
neighbor, a node//이웃 노드가 들어가게 된다.
current<-Make-Node(Initial-Sate[problem])//현재노드에 초기 상태의 노드
loop do //루프를 돈다.
neighbor<-a highest-valued successor of current//현재노드의 가장 높은값의 successor(후계자)를 이웃으로
if Value[neighbor] <=Value[current] then returnState[current]
//이웃노드의 값보다 현재 노드의 값이 더 크거나 같다면 현재 상태를 리턴한다.
current<-neighbor 아니면 현재노드에 이웃노드값을 적용시킨다.

이제 hill-climbing search를 8-queens problem에 적용을 한번 시켜보자.

Each state has 8queens on the board, one per column.
각 스테이트는 8개의 queen이 각 열마다 하나씩 배치가 되어있다.
Successor function generates 56states by moving a single queen to another square in the same column.
Successor function은 어떤 single queen을 같은 열안에 다른 square에 배치시키는 7*8=56 가지 방법이다.
h is the # of pairs that are attacking each other.
h값은 서로 공격하는 페어의 수를 뜻한다.
위 그림에서 보면 h=값이 17이고  그옆에 로컬 맥시멈의 상태를 보면 그래도 공격할 수 있는 페어가 보인다.
단순히 hill climbing으로는 완벽한 state를 얻기는 힘들다. 그렇다면 완벽한 상태를 얻기 위해서는 어떤 방법을 써야 할까?

Drawbacks: often gets stuck due to greediness
약점이라면 역시 그리디한 성질때문에
Local maxima
로컬 맥시마
Ridges: a sequence of local maxima (difficult to move along the top of the ridge)
산등성이 : 이건 local maxima가 연속으로 있어서 움직이기가 힘들다.
Plateau: flat evaluation function
높고 평평한 땅 : 요것도 비슷한거 같은데.
To get out of a shoulder, we may allow a limited number of consecutive sideway moves(by replacing <=by <).
shoulder 그림의shoulder를 빠져나가기 위해 우리는 <= 이기호를 <로만 바꾸어도 된다. 같아도 움직이게 하는것이다.

이제 기존의 hill climbing search를 보완(?)한 알고리즘을 살펴보자.

Stochastic hill climbing:
Chooses at random from among the uphill moves with probability proportional to steepness
이것은 Stochastic(확률적인)의 뜻그대로 확률적으로 비례하는 가파름이 있는 오르막 사이에 랜덤으로 배치가 된다.
First-choice hill climbing:
Generates successors randomly until one is found that is better than the current state
successor를 랜덤하게 선택하는데 어떤것이 핸재상태보다 낳아야 한다. 그것을 generate한다.

Random-restart hill climbing:
Conducts a series of hill-climbing searches from randomly generated initial states
이것은 랜덤하게 생성된 이니셜 스테이트들로 부터의 hill-climbing search의 일련을 처리한다.
Very effective for 8-queens
8-queens에 매우 유용하다.
Can find solutions for 3million queens in under a minute
3million queen프라브롬을 1분안에 해결한다. 우와~

The success of hill climbing depends on the shape of the state-space landscape.
hill climbing의 성공은 state-space landscape에 달려 있다.
NP-hard problems typically have an exponential number of local maxima to get stuck on.
A reasonably good local maximum can often be found after a small number of restarts.
위의 내용을 보자면 원래 NP-hard가 exponential 하나 좋은 로컬 맥시마는 아주작은 숫자로 쓰인다.


Simulated Annealing Search
담금질 흉내 서치

Efficiency of hill-climbing + completeness of random walk
hill-climbing의 효용성 + random walk의 완벽함
Analogy with annealing
담금질을 유사한데.

Individual moves in the state space landscape
<->random fluctuations due to thermal noise
state space landscape에서 개별적인 움직임은 <-> 온도 노이즈에 의한 랜덤한 오르내림이다.

Switch our point of view to gradient descent
우리가 포인트를 두고 봐야하는게 기울기가 내려가는 곳인데.
Consider the task of getting a ping-pong ball into the deepest crevice in a bumpy surface.
탁구공이 울퉁불퉁한 표면에 가장 깊은 균열속에 들어갔을 때 꺼내는걸 생각을 해보면
Start by shaking hard (i.e., at a high temperature) and then gradually reduce the intensity of shaking (i.e., lower the
열심히 손을 흔들고(높은 온도) 긔고 점진적으로 흔드는것의 강도가 점점 낮아진다.(온도가낮아진다.)
temperature).

수도 코드를 한번 보자.
역시 hill-climbing과 비슷한데 과정을 한번 보면 local variable로 T(온도변수)가 하나 더생겼다는것을 볼 수 있고 input으로
schedule(온도를 발생시켜주는거)이라는 것이 생겼다. 이것으로 열기 처음에 initial state로 부터 node를 생산하고 t를 1~무한대로 루프를 도는데  T는 schedule[t]에의해서 결정이 된다. 그리고 온도가 가장낮은 0이되면 현재 상태를 리턴하게 된다. 아니면 current의 successor 중 랜덤하게 선택된것을 next로 두게 된다. 델타E는 value[next]-value[current]의값을 집어 넣는다. 변화값이 0보다 크게 되면(next의 value값이 더크면) next값이 current가 되는것이고 아니면 current는 확률 e^델타E/T 에 의해 next가 된다.

A random move is picked instead of the bestmove.
랜덤한 이동이 베스트 무브 대신에 뽑히는데.
If the move improves the situation, it is always accepted.
무브가 상황을 향상시킨다면 그것은 항상 받아들인다 -> value(next)-value(current)>0
Otherwise, the move is accepted with probability e–|델타E|/T.
아니면 확률과 같이 받아들이게 되는데.
|델타E|:the amount by which the evaluation is worsened
델타E는 평가가 나빠진 정도의 총양을 말하는거지.
T:temperature, determined by the annealing schedule (controls the randomness)
T가 schedule에의해 결정이 된다. 이건 랜덤하게.

Bad moves are more likely to be allowed at the start when T is high.
나쁜 움직임은 T가 높을때 더 허락이 된다.
They become more unlikely as T decreases.
그들은 T가 떨어지면서 더 달라진다.
T->0: simple hill-climbing (first-choice hill-climbing)
T가 0이면 simple hill-climbing 이다.

Asymptotically optimal:
점근적으로 옵티말
If the annealing schedule lowers T slowly enough, a global optimum will be found with probability approaching 1.
schedule이 충분하게 천천히 낮춘다면, global optimum은 1의 확률에 근접하게 찾아낼수 있다. 그러니까 온도를 천천히 낮추는게 포인트라는 말이다. 이제 Local Beam search에 대해서 한번 알아보도록 하자.

Local Beam Search
An adaptation of path-based beam search
흠 이건 어떻게 하는 것일까? 알고리즘을 한번 보자.

Algorithm:
Randomly generate k states.
k개의 스테이트가 랜덤하게 발생한다.
Repeat until a goal is found:
골이 찾아질떄까지 계속 반복을 하게 되는데
Generate all the successors of all k states.
k state에 대한 모든 successor들을 모두 generate한다.
Select the k best successors from the complete list.
complete list로 부터 가장 좋은 k개의  successor를 선택한다.

쉽게 말해서 계속 반복해서 k개의 스테이트를 돌리는 건데. 병렬적처리가 된다는 느낌이다.

More than running k random-restarts in parallel:
Information is passed among the kparallel search threads.

Can suffer from a lack of diversity among the k states →stochastic beam search
단점은 k state의 다양함의 부족으로 될 수가 있다 다좋은쪽으로 선택하다보면 -> 이럴경우 stochastic beam search 이용
k successors are probabilistically selected.(analogy to the process of natural selection)
k successor들을 가장좋은걸로 선택하는거 대신에 확률적으로 선택한다. (자연적 선택과 좀 비슷한가)

이것을 바탕으로!
이제 드디어 중요한 Genetic 알고리즘에 대해 알아보자.

Genetic Algorithms
A variant of stochastic beam search:
stochastic beam search 의 변형체? 이런느낌으로 시작해보자
Successor states are generated by combining two parent states, rather than by modifying a single state.
흠 .. Successor state들은 두개의 parent state를 combine 하면서 생성이 된다.
Analogy to natural selection + sexual reproduction
natural selection + sexual reproduction과 유사하다. 이제 한번 과정을 살펴보도록 하자!

일단 Chromosome design(염색체 디자인)이다. 처음 디자인이다.

2)초기화 이디자인들을 나열을 한다. 옆의 파란 숫자는 1의 갯수를 나타내는것이고 이것이 3)Fitness evaluation이다.

4)Selection은 말그대로 선택이다. 위그림에서는 2개의 그림을 선택했다.
6)Mutation 두개의 돌연변이를 만든다. 여기서 두개를 전반으로 잘라서 교환을 시키고 2번째의 6번째 비트를 1로 바꾸었다. 이 하나의 비트를 변형시키는것은 두염색체의 어떤비트든 한비트만 변이한다.

7)Update generation을 한다. 여기서 변이 된 두개의 선택된 염색체들이 앞으로 가고 다른것들이 순서대로 배치가 된다.
8)Go back to 3) 3번으로 가서 fitness evaluation 부터 다시 한다.

이제 이를 토대로 8-queens problem에 대해서 한번 풀어 보도록 하자.
column 수만큼 염색체의 수가 있다 8개가 있고 위치에 따라 수를 배치를 하게 된다. 그리고 fitness evaluation을 하는 기준은 바로 높을 수록 좋은 스테이트가 되어야 하기 때문에 unattacking pair의 수이다. fitness function값의 최대값은 28이다. 이것은 모두가 서로 attack을 하지 않는 값이다. 8C2 = 56/2 = 28값을 얻을 수 있다. 그리고 아래 그림에 빗대어 보면 첫번쨰와 두번째 염색체의 결합이란것을 알 수있고 이것은 evaluation function 값이 가장 높은 두개의 염색체의 변이가 되는것을 알 수 있다.
이런식으로 되어가는것이 바로 GA genetic algorithm이다.


Advantage of GA comes from crossover:
크로스 오버로 부터 오는 GA의 장점은 무엇일까?
Is able to combine large blocks of letters that have evolved independently to perform useful functions
유용한 함수를 수행해서 letter들의 큰 블록을 서서히 independent 하게 콤바인 할 수 있다.
Raises the level of granularity at which the search operates
낱알모양의 레벨이 올라가는데 서치가 수행 되면서 그렇게 된다.

정리를 해보면 GA는 간단하다. 어떤 population(set of individual)에서 어떤 좋은 state(individual)(이평가를 fitness function이 기준이 된다.)2개를 어떤 기준으로 잘라서 섞는다 그래서 변이를 시켜서 다시 새로운 population을 구성한다. 거기서 나온 변이가 더나은 state가 될 수 있고 반복해서 solution을 찾는 그런 형식이다. 



'CSE(컴퓨터 공학) > 인공지능' 카테고리의 다른 글

Constraint satisfaction problems  (0) 2009.04.20
인공지능 솔루션  (0) 2009.04.17
Solving problem by searching (1)  (0) 2009.04.02
Posted by 태씽