- 국민경제의 활동수준을 종합적으로 판단한기 위해 국민소득이라는 경제지표를 만들어 사용하고 있다.
- 국내총생산, GDP(Gross Domestic Product) : 1년동안 한 나라의 영토 안에서 생산된 재화와 서비스의 가치를 합산한 것.
- 국민총소득, GNI(Gross National Income) : 1년동안 벌어들인 소득을 합산한 것.

- 국민소득 3면 등가의 법칙 : 국민소득의 생산, 분배, 지출은 그 크기가 같다.

- 명목국민소득은 생산물수량과 가격이 오를경우 커진다. 하지만 실질국민소득은 특정년도의 가격으로 고정하여 평가하므로 생산량이 늘어나는 경우에만 커진다.
- 국민총처분가능소득 : 한 나라 국민이 소비나 저축으로 자유롭게 사용 할 수 있는 소득.
- 국민총처분가능소득 가운데 저축의 비중을 저축률, 투자를 국민총처분가능소득으로 나누어 백분율로 나타낸 것을 투자율이라 한다.
- 경제구조란 경제의 각 부문이 만들어 낸 부가가치가 국내총생산(GDP)에서 어느 정도의 비중을 차지하고 있는지를 말한다.

- 각 나라의 국민의 생활수준을 비교하는 데에는 1인당 국민소득이 더 적합하다.
- 1인당 국민소득이라고 해도 복지수준을 정확히 나타내는 척도가 될 수는 없다. 시장에서 거래되는 서비스의 부가가치만을 계산하고 거래되지 않는 서비스의 가치는 전혀 포함되지 않기 때문이다. 시장이 발달한 나라에서는 국민소득이 늘어나게 된다.
- 비관측경제 : 국민소득을 계산할때 포착하기가 어려워 빠진 것들. 밀수, 마약거래, 사채거래 같은 지하경제들.
- 녹색 GDP : 국내총생산 중에서 이를 생산하는 데 발생한 환경손실분을 제거한 후의 GDP

- 로렌츠곡선 : 한 나라 국민의 소득분배 상태를 파악하기 위해 인구의 누적비율과 소득의 누적점유율과의 관계를 나타낸 곡선.
- 지니계수 : 로렌츠곡선과 소득 완전 균등분배 대각선 사이의 면적의 비율. 0에 가까울수록 소득격차가 적은 것이고, 1에 가까울수록 큰 것이다.

- 경제성장률 : 물가요인을 제외한 실질 국내총생산이 전년에 비해 얼마나 변동하였는지를 백분율로 나타낸 것.
- 총수요 : 가계의 소비지출, 기업의 투자지출, 정부의 공공지출, 순수출(수출 - 수입)을 합친 것. Y = C + I + G + NX





'학부 전공 > 경제이야기' 카테고리의 다른 글

1. 생활과 경제  (0) 2011.03.29

내맘대로 요약정리. 귀찮은 부분은 스킵. 재밌는 부분은 폭풍타자. 잇힝~



* 결정성 : 병행으로 실행되는 프로세스들은 그 순차적 실행의 흐름이 매번 다르지만 
   같은 조건과 입력이 주어질 때, 같은 결과를 산출해야 한다.

* 프로세스 시스템프로세스의 집합과 이들의 선행 제약의 두 가지 요소로 정의된다.
즉, 프로세스의 목록과 이들간의 순서가 정의되어야 한다.

- 선행 그래프 : 프로세스 시스템 내의 프로세스간 선행관계를 Directed Graph로 표현한 것. 물론 사이클이 없어야한다.

- 한 프로세스 시스템에 있어서, 비간섭 관계는 그 시스템이 결정적인가에 대한 필요충분조건이다.
즉, 프로세스들이 비간섭이면 그 시스템은 결정성이 있는 것이고,
결정성이 있는 시스템에서는 프로세스들이 비간섭 관계에 있는 것이다.

* 생산자/소비자 문제 : 유한한 크기의 버퍼에 생산자 프로세스와 소비자 프로세스가 병행으로 자료를 삽입/인출할 때 발생하는 문제.

- 상호 배제의 문제 : 공유 자료에 동시에 접근하여 발생하는 자료의 일관성 문제
- 동기화의 문제 : 버퍼가 full이면 인출하는 소비자가 대기하는 생산자를 깨워주고,
                                 empty이면 삽입하는 생산자가 대기하는 소비자를 깨워주어야 하는 문제.

- 임계구역 : 각 프로세스가 공유변수, 자료구조, 파일등을 베타적으로 읽고 쓸 수 있도록 설정한 코드 세그먼트
 상호간에 영향을 미치는 임계 구역은 서로에 대해 원소적 실행이 보장되어야 한다. 즉, 한 프로세스가 임계 구역을 실행하고 있는 동안에 문맥 교환이 발생하여 다른 프로세스가 실행되더라도 선점 당한 임계구역에는 진입하지 못하도록 해야 한다.

- 상호 배제의 요구조건 : 한 프로세스가 임계 구역을 실행 중일 때, 다른 어떤 프로세스도 임계 구역을 실행할 수 없다. 
  임계 구역을 실행하는 프로세스가 없는 상황에서 여러 개의 프로세스들이 임계 구역이 들어오고자 하는 상황에서는 반드시 하나의 프로세스를 선택하여 진입시키는 올바른 결정 기법이 있어야 한다.
- 제한된 대기 : 한 프로세스가 임계 구역 진입 요청을 보낸 후 수락을 받을때까지의 기간 내에, 다른 프로세스가 임계 구역을 실행할 수 있는 횟수에는 제한이 있어야 한다. 이게 뭔소리야 도대체..
 한 프로세스가 결론적으로 '수락을 받는다'는건 지금 임계구역을 사용중인 프로세스가 없단 얘기잖아. 그러니까 수락을 응답 받는거 아냐. 근데 "다른 프로세스"가 임계 구역을 실행하는 횟수가 존재한다고?! 이....이게 무슨 소리요 저자양반....

* 상호 배제의 S/W적 구현
- lock test 함수를 만들어서 하는 경우, 그 안에서 문맥 교환이 일어날 수 있으므로 상호배제가 성립되지 않는다.
- 올바른 방법은 한번 양보를 하고 대기하는 것이다. 대기에서 벗어나는 조건은 상대의 플래그가 0이 되거나 턴이 나에게 있을 때이다. 그렇게 해 놓으면 어느 상황에서 문맥 교환이 일어나더라도 상호배제가 성립된다.
- Bakery 알고리즘 : 여러개의 프로세스를 위한 상호배제 알고리즘
  대기하는 각 프로세스는 우선 번호표를 하나씩 뽑는다. 각 프로세스는 자신의 번호가 가장 작은 번호가 될 때까지 기다린다.

* 상호 배제의 H/W적 구현
- Test-and-Set : Lock에 대한 test와 copy를 CPU의 명령어로 제공 ( atomic instruction )
   타겟의 값을 1로 만들고, 이전의 타겟 값을 리턴하는 함수.
- Swap : 두 변수의 교체를 CPU의 명령어로 제공.( atomic instruction ) 
  누군가 lock을 0으로 리셋하면 다음 스왑에서 키 값이 0이 되고, 임계구역에 진입한다. 이 때 그 '누군가'는 이미 임계구역에서의 작업을 전부 마친것.
- interrupt-disable/enable : 임계 구역 내의 문맥교환 자체를 방지. 특권 명령어이기 때문에 커널 모드에서만 사용가능.

* 세마포어
- 일종의 객체.
- 정수 변수 1개와 프로세스 대기 큐, 정수에 대한 3가지 연산을 제공한다.
- 프로세스가 임계구역 진입 불가능시에는 대기 상태로 전환한다. 임계구역에서 작업을 마친 프로세스가 대기중인 프로세스를 준비 상태로 깨운다.
- 세마포어의 정수 변수는 양수일 때, 남은 자원의 갯수를 의미하고, 
                        음수일 때, 대기 중인 프로세스 갯수를 의미한다.
- 자원이 여러 개 있을 경우, 자원과 대기자를 동시에 관리할 수 있다. 
- 정수 변수의 초기값 n이 1인 경우, 공유변수에 대해 임계구역(mutex)이고,
                                    0인 경우, event에 의한 다중 쓰레드 간의 동기화에 사용된다.

- SW나 HW적인 방법들은 전부 "busy waiting" 알고리즘이다. 임계구역앞에서 대기하는 프로세스마다 busy waiting loop를 실행하는 것은 타임 슬라이스 낭비이다. 세마포어는 wait와 signal을 수행하는 짧은 기간에만 busy waiting loop를 실행한다.

* 병행 읽기/쓰기의 문제
- 공유 변수나 파일에 대해 쓰기 연산을 하는 프로세스는 모든 프로세스에 대해 상호 배제를 필요로 한다.
                                     읽기 연산을 하는 프로세스는 읽기 프로세스들과는 임계구역을 공유하고,
                                                                             쓰기 프로세스에 대해서는 상호 배제를 필요로 한다.

- 기아 : 무기한 연기 라고도 한다. 읽기 프로세스가 계속 되면 쓰기 프로세스는 계속 기다리기만 한다.
 기아의 해결책으로 aging 기법을 사용한다. 대기 시간이 길어지면 우선순위를 높이는 것이다.
 
- 모니터 : 세마포어를 클래스로 만든 형태. 데이터멤버와 멤버함수들로 구성된다.
















'학부 전공 > 운영체제' 카테고리의 다른 글

2. 컴퓨터 구조  (0) 2011.03.15
1. 운영체제 소개  (0) 2011.03.09


1. 왜 경제상식이 중요한가?

- 경제상식은 일상사에서 합리적인 의사결정을 할 수 있도록 도와주어 장기적으로 개개인의 행복을 크게 해주는 역할을 한다.
- 나라의 경제운영 성과는 국민의 경제상식 수준에 비례한다.

2. 생활은 선택의 연속

- 일상생활은 경제활동의 연속이다.
* 경제활동 : 사람에게 필요한 재화와 서비스를 생산/분배/소비하는 모든 활동
* 희소성 : 한 사회가 가지고 있는 자원의 유한성
* 경제재 : 돈이나 노력을 지급해야 얻을 수 있는 유형의 물건.
- 경제문제는 이용 가능한 자원이 희소성을 가지고 있기 때문에 생긴다. 그래서 합리적인 선택을 해야한다.
- 선택과 포기는 항상 함께 일어난다.

* 기회비용 : 선택하지 못한 것 중에서 제일 아쉬운 것의 가치.
명시적/회계적 비용뿐만 아니라 암묵적 비용도 포함하여야 한다.

3. 기본개념을 알자.

* 매몰비용 : 지불되고 난 뒤 회수할 수 없는 비용
- 경제적 사고방식에 의한 의사결정은 선택에 따르는 추가적인 행복과 추가적인 희생을 비교하여 선택하는 것이다.

* 유인(인센티브 : incentive) : 의사결정에 영향을 미치는 주변 여건의 변화.

* 수요 : 소비자가 어떤 상품을 일정한 가격을 치르고 사려고 하는 의도
* 공급 : 생산자가 어떤 가겨에 판매하고자 하는 의도
- 수요는 행복을 최대화하려는 소비자의 합리적 의사결정 결과이다.
- 공급은 이윤을 최대화하려는 생산자의 합리적 의사결정 결과이다.

* 균형가격,거래량 : 수요와 공급을 일치시키는 가격과 이때의 수요량/공급량.

* 시장경제 : 수많은 기업과 가계가 시장에서 상호작용하면서 분산된 의사결정에 의해 자원배분이 이루어 지는 경제체제
- 시장은 자유로운 의사에 따라 교환에 참여하는 당사자 모두에게 이익을 준다.
- 시장에서 결정되는 가격은 생산자와 소비자 사이에서 정보를 전달하는 신호의 역할을 하여 자원배분이 효율적으로 이루어지게 한다. (자원이 정해져있을땐 최대의 효과, 목적을 달성하기 위해 최소의 자원.)

* 계획경제 : 나라의 경제운영이 국가의 통일된 의사 밑에서 계획적으로 시행되는 경제체제.
- 계획경제는 인센티브가 없어서 기술적 진보나 생산성 향상을 기대하기 힘들고, 자원이 적재적소에 배분되기 힘들다.
- 시장경제는 소득분배의 차이를 줄이지 못하는 단점을 가지고 있다.
* 혼합경제 : 시장경제를 기본으로 하고 정부가 공적개입을 통해 계획경제의 요소를 일부 혼합한 경제체제




'학부 전공 > 경제이야기' 카테고리의 다른 글

7. 국민소득과 경제성장  (0) 2011.06.20



 1.  입출력 시스템의 구성


1) 개요
- 입출력은 메모리와 입출력장치 사이의 자료 이전이다.
- 입출력장치는 논리 회로와 입출력장치 자체로 구성된다.
- 입출력시스템의 최상위에는 응용프로그램이 있고, 운영 체제 커널에는 장치 구동기들이 있는데, 응용 프로그램과 장치 구동기 사이의 인터페이스로서 API가 존재한다.
- 장치 구동기는 하드웨어 인터페이스를 통해서 제어기에 연결되고 제어기에 입출력 장치가 연결된다.
- 각 구성요소 사이의 인터페이스가 결정되어야 한다.

2) 제어기 ( Device Controller )
- 주변장치는 제어기에 연결된다.
- 인터페이스 3종세트; API(응용프로그램과 커널의 장치구동기 사이)
                               HW 인터페이스(장치구동기와 제어기 사이); 장치생산업체에서 제공
                               장치구동기 - 커널 인터페이스
- 제어기와 주변장치 사이의 인터페이스는 운영체제에 속하지 않고 장치를 생산하는 업체에서 제공한다.
- 제어기와 운영체제 사이의 인터페이스는 장치 구동기( Device Driver )이다.
- 입출력을 수행하기 위해서 필요한 것은 입출력을 수행하는 장치 구동기와 제어기 사이의 상호작용이다.
- 제어기에는 busy와 done의 상태와 오류를 나타내는 상태레지스터, 장치에 대한 명령을 적재할 수 있는 명령레지스터, 그리고 자료레지스터(버퍼)가 있다.

 * 응용 프로그램에서 입력요구 발생시
1. 장치구동기가 제어기의 상태레지스터를 확인한다.
2. busy/done 모두 clear 상태이면 입력 명령을 명령레지스터에 적재하고
   제어기를 가동시키고 busy 플래그를 set한다.
3. 제어기가 장치에서 버퍼로 자료 이전을 완료하면 busy 플래그를 clear, done플래그를 set한다.
4. 인터럽트를 발생시켜 CPU에게 통보한다.
5. CPU가 장치구동기를 가동하여 버퍼에서 메모리로 데이터를 읽어온다. 그리고 done 플래그를 clear로 바꾼다.


 * 응용 프로그램에서 출력요구 발생시
1. 장치구동기가 제어기의 상태레지스터를 확인한다.
2. busy/done 모두 clear이면 busy플래그를 set한다.
3. 장치구동기가 메모리에서 버퍼로 데이터를 이동시킨다.
4. 출력 명령을 명령레지스터에 적재하여 제어기를 가동시킨다.
5. 출력이 완료되면 busy플래그를 clear, done플래그를 set한다.
6. 인터럽트를 발생시켜 CPU에게 통보한다. 그리고 done플래그를 clear로 바꾼다.

- 입력과 출력은 거의 비슷하다. done플래그를 set하는것은 입력에서는 '입력을 받아서 지금 버퍼에 받아놨다.'라는 의미이고, 출력에서는 '출력을 완료했다."라는 의미이다. 입력에서는 인터럽트가 발생되고 done플래그가 set되고 난 후 CPU가 버퍼에서 메모리로 읽어오는 작업을 하지만, 출력에서는 인터럽트가 발생되고 done플래그가 set되면 그걸로 끝이다.


3) 장치구동기 ( Device Driver )
- 운영체제에서 해당되는 제어기를 통제하여 입출력을 수행하는 부분이 장치 구동기이다.
- 장치 구동기는 두가지의 인터페이스를 제공해야한다. 응용프로그래머를 위한 API와 커널과 장치구동기 사이의 인터페이스가 그것이다.
- API는 표준API를 사용하여 추상화 된 명령을 제공한다
( open/close, read/write, seek )
- 장치구동기-커널 인터페이스는 디바이스드라이버가 바뀔때마다 커널을 다시 컴파일할 수는 없으니 표준화한것.
( plug & play 기능)

 2. 인터럽트 시스템
- CPU가 제어기에게 입출력 명령을 내리고 그 응답을 기다리는 것은 CPU를 낭비하는 것이므로, 인터럽트를 사용하여 제어기가 CPU에게 작업완료를 통보하고, 그때까지 CPU는 다른 작업을 처리하는 방법을 사용한다.
- 다수준 인터럽트 : 인터럽트가 들어오면 그 인터럽트보다 낮은 수준의 인터럽트의 처리를 중지한다.
 (인터럽트마다 우선순위를 결정하는 것)
 * 인터럽트가 발생하면
1. 현재 진행중인 프로세스 또는 하위의 ISR(Interrupt Service Routine) 수행을 중단한다.
2. 프로그램 카운터 및 레지스터 값들을 보존한다.
3. 인터럽트에 해당하는 마스크를 설정한다.
4. ISR로 제어를 넘긴다. ( 프로그램 카운터를 ISR의 첫주소로 세팅 )

 * 인터럽트 처리가 끝나면 -> 보존된 레지스터의 내용을 복구한다.


 3. 장치 경영 접근방식

1) 격리형 입출력 방식과 메모리-사상형 입출력 방식
- 격리형 입출력 방식에서는 제어기의 명령레지스터에 해당하는 명령을 적재하며, CPU와 제어기의 버퍼사이에 자료를 교환한다. 따라서 주변장치를 위해서 개별적으로 레지스터를 확보해야한다. (일종의 주소 공간)
- 메모리-사상형 입출력방식에서는 메모리의 논리적 주소 공간을 그대로 사용하여 제어기의 레지스터를 메모리에 사상시킨다. 이 방식은 명령의 개수를 줄이고 사용하기에 용이해서 많이 사용되고 있다.
(즉, 이 방식에서는 제어기에 실제 레지스터가 존재하지 않고, 메모리의 일부를 할당해서 사용하는 것이다.)

2) 폴링과 인터럽트 입출력
- 폴링은 바쁜 대기 방식으로서, 입출력 명령을 내리고 난 후, 입출력이 완료될 때까지 기다린다.
 이 때, 계속해서 상태를 조사하는 방법과 일정 시간마다 상태를 조사하는 방법이 있는데 주로 후자가 쓰인다.
- 인터럽트방식은 바쁜 대기를 해소하고 입출력이 완료될때까지 CPU가 다른 작업을 할 수 있게 한다.
- 입출력 명령을 내린 프로세스는 입출력이 끝나는 것을 기다리거나 프로세스에게 그대로 제어를 넘기도록 할 수 있다. 전자를 동기 방식, 후자를 비동기 방식이라 한다.
- 동기방식의 경우 CPU는 다른 프로세스를 처리할 수 있다.

3) 직접 입출력과 DMA 입출력
- 직접 입출력은 CPU가 메모리와 제어기의 자료 레지스터 사이의 자료 이전을 직접 관장하는 것이다.
- CPU와 입출력을 동시에 사용할 수 있지만, 매 입출력을 위해 인터럽트를 처리해야하는 단점이 있다.
 이것은 문자장치의 경우에는 문제가 되지 않으나, 디스크와 같은 블록장치의 경우에는 문제가 된다.
- 이러한 문제를 해결하기 위해 CPU의 도움 없이 독자적으로 메모리에 접근하여 한 입출력 명령으로 많은 자료(블록)를 입출력 및 전송하고, 한 블록의 처리가 끝날때마다 한번의 인터럽트를 발생시키는 방법을 쓴다.
 이 방식이 직접 메모리 접근(DMA) 방식이다.
- 즉, DMA입출력에서는 매 바이트마다 인터럽트가 발생하지 않고 한 블록에 한 인터럽트가 발생한다.

- 디스크에서 사용하는 시스템 버퍼는 블록 단위로 시스템 버퍼 풀에서 배정된다.
- 디스크 입출력 요구가 많아질 경우 작업의 큐로 형성되고 인터럽트 처리기에 의해 스케쥴되어 실행된다.
 디스크의 seek time 최적화를 위한 것이다.

- cycle stealing : CPU와 DMA가 동시에 메모리 접근을 요구하게 되면 DMA에게 우선권을 주고 CPU는 한 사이클을 쉰다.


 4. Buffering과 Spooling

1) 버퍼링 (Buffering)
- 서로 속도가 다른 하드웨어 사이에 자료 레지스터를 추가하여 속도를 개선하는 방법을 버퍼링이라 한다.
- 프로세스가 제어기의 자료레지스터A에 있는 자료를 읽는 동안, 제어기는 자료레지스터B에 다음 자료를 적재하는 것 같은 방법을 이중 버퍼링이라 한다.

2) 스풀링 (Spooling)
- 출력 명령이 주어지면 먼저 그 데이터를 디스크의 일정 장소에 저장하고, 별도의 출력 프로그램이 저장된 데이터를 순차적으로 프린터에 내보내는 방식을 스풀링이라 한다.
- 출력을 전담하는 프로그램을 스풀러라고 한다. 스풀러는 스풀 영역의 큐 정보를 감시하다가 생성되면 파일을 출력하는 기능을 한다.


 5. 입출력 프로세스의 처리

1) 비동기 VS 동기 입출력
- 비동기/동기 입출력은 응용 프로그램쪽에서 장치를 사용하는 관점에서의 차이가 있다.
- 동기식은 입출력을 시작시키고 그 작업이 끝날때까지 프로세스가 대기한다. CPU가 다른 프로세스에 사용된다.
- 비동기식은 입출력을 시작시키고 바로 다음 연산을 수행한다. 입출력과 상관없이 그 프로세스가 계속 CPU를 사용할 수 있다.
 입출력 종료를 알려주는 방법이 필요하다. ex)이벤트.
- 따라서 비동기식에서는 Call-back function을 구현해야 하며, Kernel thread를 사용할 수 있어야 한다.

2) 입출력장치 큐
- 입출력 장치는 빈번하고, 입출력장치의 속도는 느리기 때문에 입출력 프로세스들은 큐를 사용해서 작업을 대기시킨다.
- 키보드나 마우스처럼 언제 입력이 들어올지 모르는 장치들은 요구가 없는 상태에서도 인터럽트 처리기를 통해 버퍼링해 놓는다.

 6. 하드웨어에 의한 보호

- 운영 체제가 하는 일이 많아지고 입출력과 관계하여 할 일이 많아지게 되자, 시스템의 효율성을 높이기 위해서 시스템내의 많은 자원을 여러 프로그램이 동시에 공유하도록 하였다. 한 프로그램이 CPU를 사용하는 동안 다른 프로그램들이 입출력을 수행할 수 있게 되었고(다중 프로그래밍과 인터럽트), 여러 프로그램이 동시에 메모리를 사용할 수도 있게 되었다.
- 이런 자원의 공유는 시스템의 활용도를 높이는 반면에, 사용하는 자원을 보호해야하는 문제가 생겼다.
- 운영체제가 처리할 수 있는 오류(계산상의 오버플로우 등) 같은 경우는 기계가 멈추지 않지만, 프로그램이 운영체제의 영역을 침범하여 손상시키거나 입출력 프로그램에서 인터럽트를 잘못다루는 경우가 생기면 기계가 멈출 수 있다.


1) 이중 모드
- CPU의 상태레지스터 중 1비트를 모드 비트로 사용한다. 0이면 커널모드이고 1이면 사용자모드이다.
- 사용자 프로세스의 코드영역에 있는 명령어를 실행하는 경우, 사용자 모드로 실행한다. 인터럽트나 시스템/입출력 제어와 관련된 특권 명령을 수행할 수 없다. 메모리 참조 영역도 메모리 보호 하드웨어에 의해서 제한된다.
- 운영체제 코드영역에 있는 명령어를 실행하는 경우, 커널 모드로 실행한다. 하드웨어적인 제한이나 보호를 수행하지 않는다.
 사용자 프로그램에서 시스템 호출(트랩), 인터럽트 처리, 감지된 사용자 오류(트랩) 발생 시에 커널 모드가 된다.
- 사용자모드에서 커널모드로의 전환은 프로그램에서 독자적으로 할 수 없다.

2) 입출력 보호
- 불법 IO명령을 막기 위해 모든 IO명령을 특권 명령으로 구성하는 방법이 있다.
- 프로세스가 IO명령을 하기 위해서는 커널 모드로의 전환(특권 획득)이 필요한 것이다.

3) 메모리 보호
- 일반적으로 사용자는 사용자 모드에서 운영체제 영역 안의 인터럽트 테이블 및 처리기를 포함한 모든 영역에 접근하거나 수정할 수 없다. 또한 사른 사용자의 영역에도 마찬가지이며 자신의 코드 영역에 쓰는 것도 불가능하다.
- Base와 Limit레지스터를 사용하여 프로그램 공간을 정의해 놓음으로서 보호한다.
- 사용자 모드에서 주소를 생성했을 때에 확인하여 만약 범위(Base~Limit)를 벗어난 주소가 나오면 커널로 트랩한다.
- 리눅스나 유닉스커널에서는 segmentation fault가 발생한다.

4) CPU 보호
- 사용자 프로그램이 무한 루프에 들어가서 운영체제에게 제어를 넘기지 않으면 문제가 되므로, 제어권을 가져올 방법이 필요하다.
- 타이머 또는 클럭이라고 부르는 장치로 정해진 시간마다 인터럽트를 발생시킨다. 이 인터럽트는 정전이나 하드웨어 결함을 제외하고 가장 높은 우선순위의 인터럽트이다.
- 타이머가 있기 때문에 프로그램의 실행 시간이 제한되고 무한루프로 인한 CPU 독점을 방지할 수 있다.


 7. 기억장치 구조

- 하드웨어는 CPU, 메모리 그리고 주변장치로 구성된다.

- 메모리와 프로세서 안에 있는 레지스터들은 CPU가 접근할 수 있는 유일한 장치들이다.
- 메모리 접근 속도가 레지스터에 비해 상대적으로 느리기 때문에, CPU의 속도를 좌우하는 것은 메모리의 속도이다.
- CPU의 연산속도와 메모리 접근시간의 격차를 줄이기 위한 하드웨어적 기법으로 캐시 메모리를 사용한다.

- 디스크의 접근시간은 seek time, rotational delay, 입출력시간 및 전송시간으로 이루어진다.
- 디스크의 seek time은 CPU에 비해 매우 느리기 때문에 시스템의 성능을 저하시킨다.
- 디스크의 seek time을 줄이기 위해 버퍼링 기법이나 디스크 스케줄링을 사용한다.


 8. 기억장치 계층

- 다양한 기억장치는 속도와 가격에 따라서 계층 구조를 갖도록 조직할 수 있다.
- 계층구조는 속도, 용량, 가격의 비교 뿐만이 아니라, 하드웨어나 운영체제에 의한 버퍼링의 개념이 추가되어야 완성된다고 할 수 있다.
- 계층구조의 궁극적인 목적은 용량은 최하위 기억장치의 크기처럼, 접근 속도는 최상위 기억장치의 속도처럼 사용하는데에 있다.

1) 캐시
- 두 기억장치 사이에 접근시간이나 이동속도의 격차가 있을 때, 이를 완화하기 위해서 사용한다.
- CPU에서 메모리에 접근하는 경우 그 자료를 메모리보다 속도가 빠른 캐시에 복사하는 용도로도 사용한다.
- 알고리즘에 따라서는 90%이상의 확률로 캐시가 필요한 데이터를 가지고 있을 수 있다.




'학부 전공 > 운영체제' 카테고리의 다른 글

6. 병행 프로세스  (0) 2011.06.17
1. 운영체제 소개  (0) 2011.03.09

 운영체제는 컴퓨터 사용자와 컴퓨터 하드웨어간의 중개자로서 동작하는 프로그램이다.

 

 1. 운영체제란
 - 컴퓨터 시스템은 하드웨어, 운영체제, 응용프로그램, 사용자 부분으로 나눌 수 있다.
 - 운영체제는 일종의 정부이다. 시스템을 운영하여 자원을 적절하게 사용할 수 있게 한다.
 - 운영체제의 목적은 사용자에게 편의를 제공하는 것과 시스템을 효율적으로 운영하는데에 있다.
 
 2. 초기 시스템
 - 운영체제가 만들어지기 이전에는 컴퓨터가 굉장히 느렸기때문에, 사용자는 사용할 시간을 예약해서 그 시간 동안에만 사용해야했다.
 - 프로그램은 빨리 끝날수도, 늦게 끝날 수도 있기 때문에, 이런 방법은 컴퓨터를 효율적으로 사용할 수 없다.

 3. 초기 일괄처리 시스템
- 초기 시스템이 너무나 비효율적이라 운영자를 고용하여 사용자의 작업을 대신 실행하였다. 
그러나 작업의 준비시간이 너무 길고 여러 단계가 너무 복잡하여 운영자의 기능을 프로그램으로 대치하게 되었는데 
이것이 초기의 운영체제이다.
  
 1) 배치
- 요구수준이 비슷한 작업들을 함께 묶어서 실행함으로써 준비 시간을 줄일 수 있다. 
- 입력과 결과가 별도의 오프라인 카드리더나 테이프에 기록된다.

 2) 입출력 표준화 
- 테이프에 대한 입출력이 빈번해짐에 따라서 시스템에서는 표준 프로그램을 제공하여 편의를 제공하고 오류를 방지하였다.

 4. 일괄처리 시스템
 1) 하드웨어
채널 : 제한된 기능을 가지는 컴퓨터. 입출력장치의 제어를 위해서 설계되었다.
 명령 구조, 약간의 레지스터, 입출력장치와 통신하기 위한 하드웨어를 가진다. 메모리를 CPU와 공유하여, 메모리로부터 명령을 가져오고 명령에 의해 자료를 메모리와 주변장치 사이로 이동시킨다. 
 채녈은 CPU에서 입출력 정보를 받아 명령을 실행하기 시작하면, CPU와 독립적으로 작동한다.
(단 메모리 사이클에 대한 경쟁은 제외)

- CPU와 채널 입출력을 동시에 활용하기 위해 버퍼를 둔다. 연산하는 동안 읽거나 쓸 수 있게하여 입출력 대기시간을 없앤다.
인터럽트의 등장으로 대기루프 없이 CPU연산과 입출력 버퍼링을 병렬로 수행가능하게 되었다.
- 인터럽트는 하드웨어에 의하여 자동으로 호출되며, 메모리의 특정부분에 위치한 함수를 호출하는 것이다.

 2) 상주 모니터
- 입출력 관리자 또는 인터럽트 처리기를 메모리에 영구적으로 상주시켜야 할 필요성이 생겼다.
- 작업 제어 명령어, 적재기, 작업 순서 제어기를 상주시키에 되어 이 프로그램의 집합을 상주 모니터라 부르게 되었다.
- 상주 모니터의 설치로 처리율이 급격히 증가하였으나, 사용자가 늘어남에 따라 하드웨어와 소프트웨어의 표준을 어기는 일이 빈번해졌다. 상관없는 다른 프로그램을 지워버린다거나 입출력 오류로 비정상적 신호를 보낸다거나 하는 일이다.

3) 보호
- 잘못된 사용자 프로그램에서 상주 모니터가 있는 부분에 접근하여 자료를 덮어쓰는 일이 발생하자 상주 모니터를 보호할 방안이 필요하게 되었다.
- 모든 프로그램에서 입출력을 위해 상주 모니터의 루틴을 사용하게 하고, 시스템에서 요청된 연산을 미리 작성된 허용치를 참조하여 검사하게 함으로써 위험한 동작을 미연에 방지할 수 있게되었다.
- 사용자가 출력 상한선과 상한 시간을 제시하게 함으로써 프로그램의 오동작을 막기도 하였다.

 4) 작업 제어 명령어
- 규격카드나 제어 카드를 사용하여 필요한 조작을 기술하는 방법이 등장하였다. 
- 이 기법을 위해 시스템에 제어 명령어를 추가하게되었다.
- 각각의 작업은 해당하는 제어 카드를 가지고 있어서 작업순서가 이미 정의되어 있다. 그 작업이 모두 끝난 후에야 결과를 볼 수가 있다.

5. 다중 프로그래밍

- 다중 프로그래밍의 기본적인 개념은, 운영체제가 여러 개의 작업을 메모리에 적재하고, 적재된 작업중 하나를 선택하여 CPU를 할당하고 실행시키기 시작한다. 그 작업은 키보드 입력을 기다리거나 출력을 기다리거나 하는 상태가 될 수 있다. 그 때 다른 작업에 CPU를 할당하여 실행시키는 것이다.

 1) 스풀링
- 시스템이 작업을 실행하는 동안 별도로 카드 판독기의 작업을 테이프나 디스크에 일괄 저장하고, 시스템이 다음 작업들을 테이프나 디스크에 적재하는 방식을 사용하기 시작하였는데 이를 입력 스풀링이라 한다.

 6. 시분할 시스템
- 시분할 시스템은 사용자와 시스템 간에 온라인 통신을 마련하여 사용자가 운영체제나 프로그램에 직접 명령을 주고 즉시 응답을 받을 수 있도록 한다. 
-  여러 프로그램이 동시에 메모리에 존재할 뿐만 아니라 여러 사용자에게 빠른 응답시간을 제공하기 위해 CPU시간을 나누어서 각 작업에 번갈아 가며 할당하는데, 한번에 할당되는 CPU시간을 타임 슬라이스( time slice )라 한다.

 7. 개인용 컴퓨터
 8. 병렬 시스템
 9. 분산 시스템
 10. 실시간 시스템
 11. 내장형 시스템




'학부 전공 > 운영체제' 카테고리의 다른 글

6. 병행 프로세스  (0) 2011.06.17
2. 컴퓨터 구조  (0) 2011.03.15


1. 블록킹 자바 IO

- 자바에서 파일 읽기를 시도하면, 먼저 커널에 명령이 전달되고,
 커널은 시스템 콜을 사용해서 디스크 컨트롤러가 읽어온 데이터를 커널의 버퍼에 저장한다.
 그 후 모든 파일 데이터가 커널의 버퍼에 복사되면, JVM의 버퍼로 복사한다.

- 첫번째 문제점은, 커널의 버퍼에 저장된 데이터를 프로세스 영역의 버퍼로 복사하는 것이다.
 만약 커널의 버퍼를 직접 사용할 수 있다면, 복사하는 시간이 필요없다.
 
- 두번째 문제점은, 디스크 컨트롤러에서 커널의 버퍼로 데이터를 복사하는 동안, 프로세스 영역이 블로킹 된다는 것이다.


2. IO 속도 향상을 위한 OS수준의 기술들

1) 버퍼
 - 효율적으로 데이터를 전달하기 위한 객체.
 - 버퍼의 크기가 크면 클수록 성능 향상이 이루어진다.

2) Scatter/Gather
 - 사용하는 버퍼가 여러개 일때, Scatter/Gather를 사용하면 시스템 콜을 한번만 호출하고,
 사용할 버퍼의 주소 목록을 넘겨줌으로서, 운영체제에서 버퍼들에게서 순차적으로 데이터를 읽거나 쓰게 된다.

3) 가상 메모리
 - 프로그램이 사용할 수 있는 주소 공간을 늘이기 위해 운영체제에서 지원하는 기술.
 - 가상 메모리를 사용함으로써 실제 물리적 메모리보다 더 큰 공간을 사용할 수 있고,
   여러 개의 가상 주소가 하나의 물리적 메모리 주소를 참조함으로써 메모리를 효율적으로 사용할 수 있게 해준다.
- 프로그래밍에서 가상 메모리를 사용하게 되면, 프로세스의 버퍼와 커널의 버퍼를 매핑시킴으로써
   커널의 버퍼에서 프로세스의 버퍼로 복사할 필요가 없게 된다.

4) 메모리 맵 파일
 - Memory-mapped IO는 파일시스템의 페이지들과 유저 영역의 버퍼를 가상 메모리로 매핑시킨다.
 - 메모리 맵 파일을 사용하면, 프로세스가 파일 데이터를 메모리로서 바라보기 때문에 시스템 콜을 할 필요가 없다.
   따라서 프로세스가 파일 데이터를 변경하면 별도의 입출력을 할 필요가 없이 물리적 디스크에 자동으로 반영하게 된다.
 - 또한, 매우 큰 파일을 복사하기 위해 많은 양의 메모리를 소비하지 않아도 된다.
   그때그때 필요한 부분만을 실제 메모리에 올려놓고 사용하면 된다.

5) 파일 락
 - 스레드의 동기화와 거의 비슷한 개념이다. 한 프로세스가 어떤 파일에 락을 획득하면, 다른 프로세스가 그 파일에 접근하는 것을
  막거나, 접근 방식에 제한을 두는 것이다.
 - 파일의 일부분만을 잠궈서 사용하기 때문에, 락이 설정되지 않은 부분은 다른 프로세스가 작업할 수 있다.
 - 일반적으로 공유 락은 읽기 작업에 사용되고, 배타 락은 쓰기 작업에 사용된다.
 - 공유 락이 걸려있는 부분은 읽기 작업은 얼마든지 더 할수 있지만, 쓰기 작업을 할 수 없다.
   배타 락이 걸려있는 부분은 어떤 다른 작업도 할 수 없다.


3. 자바의 변화

1) 포인터 버퍼 도입
 - NIO에서는 커널이 관리하는 시스템 메모리를 직접 사용할 수 있는 Buffer 클래스가 도입되었다.
 - 내부적으로는 C로 만들어져 있지만 우리는 추상화되어 제공되는 자바 클래스인 Buffer만을 사용하게 된다.

2) 네이티브 IO서비스를 제공해주는 채널 도입
 - 채널은 단방향 뿐만이 아니라 양방향 통신도 가능하다.
 - 채널을 이용해서 시스템 메모리인 버퍼에 직접 읽거나 쓸 수 있다. 또한 Scatter/Gather를 구현하였다.

3) 셀렉터 도입
 - 기존에는 클라이언트 하나당 스레드 하나를 생성해서 처리해야 했다.
 - 셀렉터를 이용함으로써 단 한개의 스레드만으로 수천, 수만명의 동시 사용자를 처리할 수 있다.




문제의 특성상 그림이 설명에 중요한 역할을 하나,
포스트에 그리기가 번거로우므로 생략하고, 노트에 있는 그림을 참고한다.


문제 정의 : 평면 상의 n개의 점들 중 가장 가까운 한 쌍을 찾아라.
- 이 문제의 입력은 그래프가 아니라 x좌표, y좌표가 주어진 점들의 집합이다.

Alg.
1. 입력을 x축 기준으로 정렬해서 반으로 나눈다.
2. 재귀적으로 호출한다.
3. (merge sort를 사용하여) y축 기준으로 정렬하며 합친다.


* 반으로 나뉠때 가운데에 잘린 것들은 어떻게 비교할 것인가? ( 하나는 왼쪽에, 다른 하나는 오른쪽에 있는 경우 )

- 왼쪽에서 찾은 제일 짧은 선과 오른쪽에서 찾은 제일 짧은 선, 둘 중에 더 짧은 선을 d라 하자.
- x축의 중심에서 왼쪽으로 d, 오른쪽으로 d만큼의 영역을 "밴드"라 하자.

- 밴드 안의 특정한 점에 대해서 y축 방향으로 d만큼 차이나는 점과의 거리만 보면 된다.
- 그리고 그 점들은 무조건 10개 이하이다.
  -> 거리가 d인 정사각형 안에 d보다 긴 거리를 가지는 점들은 최대 3개까지 밖에 넣지 못한다.

- 밴드 안에 있는 점들을 y축 기준으로 정렬해야 한다.
- 한 레벨에서 nlogn 만큼의 시간을 쓰기 때문에, 전체 알고리즘의 수행시간은 n(logn)^2 이 된다.

* 밴드 안에 있는 점들만 보면 되지만, 모든 점들을 sort하는 것이 더 좋다.

왜냐하면 밴드 안에 있는 점들만 sort하려면 각 레벨마다 "그 레벨의 밴드 안에 있는 점들"을 y축을 기준으로 새로 정렬해야 하지만,
애초에 모든 점들을 sort하겠다고 한다면, 합치면서 merge sort를 사용할 수 있기 때문이다.
또한, 모든 점을 sort 해도, 실제 스캔은 밴드 안에 있는 점만을 찾아서 계산하기 때문에
작업이 크게 늘어나지 않는다. ( 밴드 밖에 있는 점을 건너뛰는 시간이 더해질 뿐이다.)
- 합치면서 merge sort를 하게 된다면, 한 레벨에서 n만큼의 시간을 쓰게 되고,
 전체 알고리즘의 수행시간이 nlogn이 된다.
- 기존의 작업은 아래 레벨에서의 결과물이 현재 레벨에서 아무 도움이 되지 않는다.
 ( 밴드의 위치는 레벨마다 다르기 때문에 현재 레벨에서 다시 정렬을 수행해야 한다.)
 merge sort를 사용하면 아래 레벨에서의 결과물이 현재 레벨에서 도움이 된다.
 ( 양쪽 배열이 이미 정렬되어 있으므로, merge기법을 통해 간단히 합칠 수 있게 되는것.)


'학부 전공 > 알고리즘' 카테고리의 다른 글

Selection  (0) 2010.10.29
Tape에 데이터 담기  (0) 2010.10.11
Job Scheduling  (0) 2010.10.08
Dijkstra 알고리즘  (0) 2010.10.08
Kruskal 알고리즘  (0) 2010.10.08

문제 정의 : k등을 찾아라!

- Sorting 보다 빨라야 도움이 된다. ( 퀵소트에서 중간값을 찾는 경우 등)

- 토너먼트 식으로 한다면? 
1등을 찾는데에는 n, 2등을 찾는데에는 n + logn, 3등을 찾는데에는 n + 2logn,
k등을 찾는데에는 n + klogn이 걸리게 된다.

- Selection Sort를 k번째 까지 수행한다면?
kn 시간이 걸림 -> k가 n/2이면 O(n^2)이 걸리게 된다.

- Quick Sort를 k등 근처에서 수행한다면?
최선의 경우 O(n)에 끝나지만,
최악의 경우 O(n^2)이 걸리고 평균적으로 O(n)이 된다.

-> Selection 문제를 "최악의 경우에도" n^2이 안 걸리게 풀 수 있는 알고리즘이 있을까?
-> 있지만, 슬프게도, 실용적이지는 않다.


* Approximate Median

정의 : rn등부터 (1-r)n등 사이의 원소. (단, 0 < r < 1)

- 매우 약한 정의이기는 하지만 이렇게 주어져도 문제 없다는 것이 증명되어 있음. ( = 그냥 믿으세요! )
- r = 0.3으로 고정한다.

Alg.
  1. 배열을 5개씩 분할
  2. 각 분할의 중간값을 찾는다.
  3. 중간값들 중 실제 중간값을 찾는다.

결론 : 3번에서 찾은 '실제 중간값'은 반드시 rn등과 (1-r)n등 사이에 존재한다.


* 정확성 증명

입력이 ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ 이라고 한다면

1번에서
ㅇㅇㅇㅇㅇ | ㅇㅇㅇㅇㅇ | ㅇㅇㅇㅇㅇ | ㅇㅇㅇㅇㅇ | ㅇㅇㅇㅇㅇ 
- 단, 실제로 나누는 것이 아니고 그렇게 생각하는 것.


2번을 이해하기 쉽게 배열을 세로로 나타내면

ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 
ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 
ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 
ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 
ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 

- 위에 있을수록 큰 값, 아래에 있을수록 작은 값.

- 3번째 줄, 즉 가운데 값이 각 분할된 배열의 중간값이다.


가운데 값을 기준으로 각 분할된 배열을 정렬한다.
(여기서는 증명 과정을 알아보기 쉽도록 정렬을 하지만, 실제 구현에서는 모든 분할 배열을 정렬할 필요없이,
 3번째 줄의 진짜 중간값만 찾으면 된다.)

ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 
ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 
ㅇ | ㅇ | ㅇ | ㅇ | ㅇ |  <- 정렬되어 있음.
ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 
ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 

1,2, 4,5번째 줄은 좌우로는 크기비교를 할수 없지만, 위의 것보다는 작고, 아래의 것보다는 크다.


3번에 의해 찾은 실제 중간값을 ☆ 이라 하자.

ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 
ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 
ㅇ | ㅇ | ☆ | ㅇ | ㅇ | 
ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 
ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 

- 위에서 빨간색으로 표시된 것들은 무조건 ☆보다 큰 값이다.
- ☆의 위에 있는 값들은 분할된 배열이 정렬되어 있기때문이고, ☆의 오른쪽에 있는 값들은 3번째줄을 기준으로 정렬했기 때문이고,
☆의 오른쪽 위에 있는 값들은 
 ☆ < (☆의 오른쪽) < (☆의 오른쪽)의 위
이기 때문이다.

- 따라서, 예제의 입력된 배열에는 ☆보다 큰 값이 최소한 8개 존재하며,
 입력된 배열이 n개 일때, ☆보다 큰 값이 최소한 (대략) 3n/10개 존재한다.
 -> 즉, ☆이 아무리 커도 상위 30%이내에는 들어갈 수 없다.


위와 같은 식으로,

ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 
ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 
ㅇ | ㅇ |  | ㅇ | ㅇ | 
ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 
ㅇ | ㅇ | ㅇ | ㅇ | ㅇ | 

- 위에서 빨간색으로 표시된 것들은 무조건 ☆보다 작은 값이다.
- ☆의 아래에 있는 값들은 분할된 배열이 정렬되어 있기때문이고, ☆의 왼쪽에 있는 값들은 3번째줄을 기준으로 정렬했기 때문이고,
☆의 왼쪽 아래에 있는 값들은 
 ☆ > (☆의 왼쪽) > (☆의 왼쪽)의 아래
이기 때문이다.

- 따라서, 예제의 입력된 배열에는 ☆보다 작은 값이 최소한 8개 존재하며,
 입력된 배열이 n개 일때, ☆보다 작은 값이 최소한 (대략) 3n/10개 존재한다.
 -> 즉, ☆이 아무리 작아도 하위 30%이내에는 들어갈 수 없다.


=> 따라서 ☆이 전체 입력의 30% ~ 70% 사이에 존재한다.
=> Approximate Median이 성립함.


 * 3번에서 "실제 중간값"을 찾기 위해서 Quick sort를 호출한다.
그리고 그 Quick sort는 pivot을 찾기 위해 Approximate Median을 호출한다.
=>Quick sort ( 이하 QS )와 Approximate Median ( 이하 AM )이 상호재귀함수로서 작동한다.

- QS(n)은 AM(n)과 QS(0.7n)을 호출한다.
   -> 입력된 것을 그대로 AM으로 보내 pivot을 찾고, 그 pivot은 최악의 경우에도 70%안쪽이므로 0.7n으로 다시 QS를 호출할 수 있다.

- AM(n)은 QS(0.2n)을 호출한다.
   -> 입력을 5개씩 분할하고 각 분할된 배열의 중간값만을 QS로 보내 실제 중간값을 찾는다. 


* Selection 문제를 푸는 시간을 t(n)이라 하면

t(n) = n + t(2n/10) + t(7n/10)

t(n) <= Cn이라고 가정하면

t(n) = n + 2Cn/10 + 7Cn/10 
      = 9Cn/10 + n
      = (9C+10)*n/10 

C가 커질수록 (9C+10)/10 의 값이 작아진다.
( C가 10일때 10, 20일때 19, 30일때 28 .........)

즉 t(n) <= 10n

따라서 t(n) = O(n)



'학부 전공 > 알고리즘' 카테고리의 다른 글

Closest Pair  (0) 2010.10.29
Tape에 데이터 담기  (0) 2010.10.11
Job Scheduling  (0) 2010.10.08
Dijkstra 알고리즘  (0) 2010.10.08
Kruskal 알고리즘  (0) 2010.10.08


- 입력 D에는 단위 데이터들이 저장되어 있고, 데이터마다 길이(L)와 사용빈도(F)가 저장되어 있다.
- 매번 read한 후에 full rewind 한다고 가정한다.

- 문제의 목표는 read시간의 기대값을 최소화 하는 것.

 * 알고리즘
- 길이가 짧을수록, 빈도가 높을수록 앞부분에 둔다.
- F(i)/L(i) 값이 큰 것부터 앞에 둔다.
 -> F(i) - L(i) , F(i)^2 / L(i) , 등등의 값 또한 사용할 수 있는데 왜 F(i)/L(i) 값을 쓰는것이 가장 좋은가?

 * 증명
- d1,d2,d3,d4,d5,..... dn 순서가 정답이고, F(i)/L(i)가 감소하는 순서가 아니라고 가정하자
 -> 즉, 정답 중에 F(k)/L(k) < F(k+1)/L(k+1)인 k가 적어도 1개 존재한다.

- S' = d1,d2,d3,,,,,,,d(k+1), d(k),,,,,,,,dn 이라고 하자. ( d(k)와 d(k+1)의 순서를 바꾼 것 )
- S의 기대값 t = F(1)*L(1) + F(2)*( L(1)+L(2) ) + F(3)*( L(1)+L(2)+L(3) + ............
.....+ F(k)*( L(1)+L(2)+...+L(k) ) + F(k+1)*( L(1)+L(2)+...+L(k+1) ) + ... + F(n)*( L(1)+L(2)+...+L(n) )

- S'의 기대값 t' =  F(1)*L(1) + F(2)*( L(1)+L(2) ) + F(3)*( L(1)+L(2)+L(3) + ............
.....+ F(k+1)*( L(1)+L(2)+...+L(k-1)+L(k+1) ) + F(k)*( L(1)+L(2)+...+L(k+1) ) + ... + F(n)*( L(1)+L(2)+...+L(n) )
- t - t' = F(k+1)*L(k) - F(k)*L(k+1)
          = L(k)*L(k+1)*( F(k+1)/L(k+1) - F(k)/L(k) ) > 0

- t > t' 이다. 정답의 기대값인 t보다 작은 t' 존재하는 것은 모순이다.
따라서 가정은 거짓이다.


 * F(i)/L(i)값을 쓰는 이유는 기대값을 계산하고 비교하는데에서 F(i)/L(i)값이 등장하기 때문이다.

'학부 전공 > 알고리즘' 카테고리의 다른 글

Closest Pair  (0) 2010.10.29
Selection  (0) 2010.10.29
Job Scheduling  (0) 2010.10.08
Dijkstra 알고리즘  (0) 2010.10.08
Kruskal 알고리즘  (0) 2010.10.08


- unit time에 실행가능한 job들이 존재.
- 시간 d(i) 이전에 job i를 수행하면 이익 P(i)
- job은 이익으로 내림차순 정렬되어 있다.

- S(k) = i 는 job i가 k시간에 끝나도록 schedule했다는 의미.
- deadline이 n보다 큰 job은 없다고 가정

 * 구조
- 첫번째 job부터 시작하여 d(i)보다 작고 S(k)=0 인 가장 큰 k에 대해 S(k) = i

 " 알고리즘이 최적의 solution을 얻는다. "
- feasible : deadline을 위반한 job이 없는 schedule
- promising : feasible하면서 최적 solution으로 "확장"될 수 있는 schedule
- 확장 : job i+1, job i+2, ........ job n 들 중에서만 job을 추가함

 " 알고리즘의 모든 단계에서 S는 promising 하다 "
base) 최초에 S는 promising하다. 모든 k에 대해서 S(k) = 0이기 때문이다.
step) 알고리즘이 i-1번째 job을 추가했을때 promising 하다면, i번째 job을 추가했을때 promising 한가?
- 최적 solution 중 하나를 Sopt라 하자.
- 알고리즘은 job i를 가지고 두가지 동작을 할 수 있다. job i를 버리거나, job i를 k에 추가하는 것이다.
1) 알고리즘이 job i를 버렸다는 것은, deadline 앞에 빈 칸이 없을 때이다. 이런 경우의 Sopt에는 i가 없다.
따라서 여전히 promising하다.
2) 알고리즘이 job i를 k번째에 추가했다고 하자. 이 때에도 두 가지 경우가 생긴다.
- i를 추가한 S를 S'라 하자. 즉, S'(k) = i
 2-1) job i가 Sopt에서 k'에 schedule되어 있음. 즉, Sopt(k') = i
k' = k 일 경우, S'는 promising하다.
k' < k 일 경우, Sopt(k)와 Sopt(k')를 교환한다. 조건에 위배되는것이 없으므로, 여전히 promising하다.
k' > k 일 경우는 불가능하다. 알고리즘에서 deadline과 k 사이에는 빈칸이 없기 때문이다.
 2-2) job i가 Sopt에 없을 경우
- 최소한 Sopt(k)는 0이 아니라는 것을 알 수 있다. Sopt(k)를 x라 하자.
- x는 i 보다 더 나중에 나오는 job이다. 따라서 이익이 더 작거나 같다. 따라서 S'opt(k)를 i로 교체한다.
- 그래서 S'는 promising 하다.


'학부 전공 > 알고리즘' 카테고리의 다른 글

Selection  (0) 2010.10.29
Tape에 데이터 담기  (0) 2010.10.11
Dijkstra 알고리즘  (0) 2010.10.08
Kruskal 알고리즘  (0) 2010.10.08
Prim 알고리즘  (0) 2010.10.07

+ Recent posts