더보기

한빛 아카데미 - 쉽게 배우는 운영체제 책 내용 정리입니다

01 운영체제 소개

  • 운영체제는 각각의 응용 프로그램이 활동할 수 있는 환경을 제공하고, 응용 프로그램이 필요로 하는 컴퓨터 자원을 나눠주며, 응용 프로그램으로부터 컴퓨터 자원을 보호하는 강력한 통치자 역할을 한다
  • 운영체제의 정의
    • 사용자에게 편리한 인터페이스 환경을 제공하고 컴퓨터 시스템의 자원을 효율적으로 관리하는 소프트웨어
  • 운영체제의 역할
    • 자원관리(효율성), 자원보호(안정성), 하드웨어 인터페이스 제공(확장성), 사용자 인터페이스 제공(편리성)

02 운영체제의 역사

  • 일괄작업 시스템(천공카드, 라인프린터) → 대화형 시스템 → 시분할 시스템(반대개념 real time system) → 분산시스템 → 클라이언트/서버 시스템 → P2P → Grid Computing, Cloud, IOT

03 운영체제의 구조

  • Kernel(시스템호출, 드라이버) : 프로세스 관리, 메모리 관리, 저장장치 관리 같은 운영체제의 핵심적인 기능을 모아놓은것
  • System call : 커널이 자신을 보호하기 위해 만든 인터페이스
    • 커널은 사용자나 응용프로그램으로부터 컴퓨터 자원을 보호하기 위해 직접 접근하는 것을 차단, 따라서 자원을 이용하려면 시스템호출이라는 인터페이스를 통해 접근해야함
    • 커널이 제공하는 시스템 관련 서비스를 모아놓은것
    • 커널이 제공하는 시스템 자원의 사용과 연관된 함수
    • 응용 프로그램이 하드웨어 자원에 접근하거나 운영체제가 제공하는 서비스를 이용하려 할때는 시스템 호출을 사용해야함
  • Driver : 커널과 하드웨어의 인터페이스를 담당
  • 커널의 구성
    • 프로세스 관리 : 프로세스에 CPU를 배분하고 작업에 필요한 제반 환경을 제공
    • 메모리 관리 : 프로세스에 작업 공간을 배치하고 실제 메모리보다 큰 가상공간을 제공
    • 파일 시스템 관리 : 데이터를 저장하고 접근할 수 있는 인터페이스 제공
    • 입출력 관리 : 필요한 입력과 출력 서비스를 제공
    • 프로세스간 통신 관리 : 공동 작업을 위한 각 프로세스 간 통신 환경을 지원
  • 단일형 구조 커널(Monolithic)
    • 모든 서브시스템이 커널과 같은 메모리 공간에 적재, 실행되는 커널의 구조로 이루어져 있다
    • 커널의 핵심 기능을 구현하는 모듈들이 구분 없이 하나로 구성
    • 장점
      • 모듈이 거의 분리되지 않았기 떄문에 모듈 간의 통신비용이 줄어들어 효율적인 운영이 가능
    • 단점
      • 모든 모듈이 하나로 묶여있기 때문에 버그나 오류를 처리하기 힘듬
      • 운영체제의 여러 기능이 서로 연결되어있어 상호 의존성이 높아 기능상의 작은 결함이 시스템 전체로 확산될수있음
      • 다양한 환경의 시스템에 적용하기 어렵다
      • 현대의 크고 복잡한 운영체제에 구현하기 어렵다
    • 커널내의 모든 서브시스템이 ring 0레벨에서 동작
  • 계층형 구조 커널(Layered)
    • 단일형 구조 커널이 발전된 형태
    • 비슷한 기능을 가진 모듈을 묶어서 하나의 계층으로 만들고 계층간의 통신을 통해 운영체제를 구현
    • 비슷한 기능을 모아 모듈화했기 때문에 단일현 구조보다 버그나 오류를 쉽게처리
    • 오류 발생시 해당 계층만 수정하기때문에 디버깅하기 쉬움
  • 마이크로 구조 커널(micro architecture)
    • 메모리 관리, 프로세스 관리, 장치 관리, 파일시스템, 네트워크 스택 등 각 서브시스템을 커널과 분리하여 별도의 메모리공간에 적재, 실행
    • 프로세스관리, 메모리관리, 프로세스간 통신관리 등 가장 기본적인 기능만 제공
    • 운영체제의 많은 부분이 사용자 영역에 구현, 따라서 각 프로세스마다 보호 영역을 갖게됨
      • 디바이스 드라이버 하나가 다운되더라도 다른 서브시스템은 영향을 받지 않게됨
    • 커널은 메모리 관리와 프로세스 간의 동기화 서비스를 제공, 메모리 관리자와 동기화 모듈은 프로세스간 통신 모듈로 연결되어있음
    • 각 모듈은 세분화되어 존재하고 모듈 간의 정보교환은 프로세스간 통신을 이용하여 이루어짐
    • 메모리 관리, 프로세스 관리, 장치 관리, 파일시스템, 네트워크 스택 등 각 서브시스템을 커널과 분리하여 별도의 메모리공간에 적재, 실행
    • 커널을 제외한 나머지 서브시스템은 ring 3레벨에서 동작
  • 가상머신 : 운영체제 위에 가상머신을 만들고 그 위에서 응용프로그램이 작동하게함

'CS Study > OS' 카테고리의 다른 글

정리정리  (0) 2022.01.26
2. Chapter 3. Processes  (0) 2021.10.22
1. Chapter 1-2. Introduction & O/S Structures  (0) 2021.10.09

Virtual Reality Sickness: A Review of Causes and Measurements Causes of VR Sickness(https://doi.org/10.1080/10447318.2020.1778351)

  1. Hardware
    1. Display type and mode
    2. Hardware FOV
    3. Latency
    4. Flicker
  2. Content
    1. Optical flow
    2. Graphic Realism
    3. Reference Frame
      • rendered fixed visual stimuli regradless of moving VR content ex. clouds or trees
      • grid patterns(https://dl.acm.org/doi/10.1145/365024.365051) “independent visual background(IVB)”
      • virtual nose
      • 위에서 언급한 다양한 유형의 고정된 시각적 자극은 사용자가 VR에서 자신의 위치를 정확하게 인지하는 데 도움을 주는 기준 프레임이 될 수 있다
      • 기준 프레임은 인간의 관성 자기 운동 시스템과 일치하고 감각 충돌을 줄이는 시각적 자극을 제공할 수 있다
  3. Content FOV
  4. Duration
  5. Controllability
  • Rest Frame Hypothesis(https://www.proquest.com/docview/304457571?pq-origsite=gscholar&fromopenview=true)
    • 감각적 충돌보다는 인지적 충돌에서 발생하는 것
    • 신경계가 언제든지 사건을 추적할 수 있는 "기준 프레임"을 설정할 수 있다고 지적. 여러 개의 기준 프레임이 있는 작업 중, 뇌는 "정지 프레임" 즉, "정지된" 기준 프레임으로 하나를 선택한다.
    • Before any decisions or recognitions, our brains first regard ground as stationary reference, all further spatial judgements are based on it.
    • Once humans predict what is or is not stationary, they will combine the information received by the visual and inertial system to support their next perceptions or actions
    • To judge space, positions and orientations around them, a person uses a coordinate system that is called a reference frame
    • 하지만 가상환경에서는 ground 같은 stationary한 reference가 없어서 혼란스럽고 이는 멀미를 야기한다
    • Virtual nose의경우 Rest Frame의 일종이지만 신체의 일부라 vr환경 내에서 사용자가 느끼기에 이질감이 덜하다(https://doi.org/10.1109/VS-Games.2018.8493408)
    • Rest Frame의 크기가 너무 작을경우엔 의미가 없으며 너무 클경우엔 화면을 가려서 몰입을 방해한다(https://doi.org/10.1145/3451255)

 

💡 Virtual nose : https://doi.org/10.1109/VS-Games.2018.8493408

 

A Virtual Nose as a Rest-Frame - The Impact on Simulator Sickness and Game Experience

This paper presents an experiment measuring the impact of a virtual nose on simulator sickness and game experience in a virtual reality game presented on an Oculus Rift DK 2. Furthermore, the presented study investigated in the significance of the rest-fra

ieeexplore.ieee.org

Optical Correction Reduces Simulator Sickness in a Driving Environment : https://doi.org/10.1177%2F0018720814533992

 

논문 : https://www.tandfonline.com/doi/abs/10.1207/s15327108ijap0303_3

 

RELATED WORK

 

MSQ(Pensacola Motion Sickness Questionnaire,  1965) to study motion sickness(MS)

실제 토할때까지의 정도 degree of MS severity

MS 발병과 관련된 (보통) 25~30가지 증상들의 목록으로 구성

아무증상없음(0점) ~ 토함(emesis, highest score)

증상의 수, 유형 및 심각도에 따라 중간 점수가 할당


THE NEED FOR A SIMULATOR SICKNESS QUESTIONNAIRE (SSQ)

 

SS의 증상은 MS와 비슷하지만 노출된 인구의 적은 비율에 영향을 미치며 일반적으로 훨씬 덜 심각

왜냐하면 SS는 pseudo-coriolis, visual distortion, visual/motion transport delay을 생성하기 때문

(The pseudo-Coriolis illusion is the experience of an anomalous angle of head tilt and tilting of the visual stimulus that occurs when an observer moves his head across the plane of rotation of an optokinetic stimulus that would otherwise produce vection)

SS 자체도 시뮬레이터 간 차이로 인해 다른 증상 클러스터를 생성할 수 있음

또한 고정 기반 비행 시뮬레이터는 해상 선박과 중요한 측면에서 다르다. 즉, 시뮬레이터에서 눈을 감으면 자극이 멈춘다.

 

또한 MSQ를 SS의 이상적인 지표보다 낮은 지표로 만드는 MS와 시뮬레이터에 의한 질병 사이에는 몇 가지 다른 차이점이 있다.

현재 설문지의 증상 중 일부는 시뮬레이터 노출 하에서 보고되지 않거나, 명시된 경우 기준 수준을 초과하지 않는 수준으로 표시된다.

MS 점수를 매기는 데 유효한 증상 중 일부는 SS 평가에 반드시 적합하지 않음

예를들어 Drowsiness 졸림 은 MS에서는 key indicator지만 다른 실험에서는 의미가 없다고 하였음

(그러나 강력한 운동 자극에 대한 부교감 반응을 암시하는 다른 증상들이 뒤따를 때 그것의 의미는 상당히 다를 수 있다)

 

3가지 목적을 가지고 논문을 작성

(a) 멀미와 구별되는 전반적인 시뮬레이터 멀미 심각도에 대한 보다 효과적인 지표를 제공한다.

(b) 전반적인 심각도가 문제로 나타난 특정 시뮬레이터에서 시뮬레이터 멀미 위치를 보다 진단하는 서브스케일 점수를 제공

(c) 모니터링 및 누적 추적을 비교적 쉽게 하기 위한 점수 매기기 접근 방식을 제공


DEVELOPMENT OF THE SSQ SCORING SYSTEMS

 

Method

사용된 dataset은 1,119pairs(pre and posetexposure)개의 MSQs

이때 사용된 MSQ version은 28 symptoms

우리의 목적은 어떤 증상이 노출 전에서 노출 후로 체계적인 변화를 보이는지를 결정하는 것이었기 때문에, 너무 드물게 선택된 증상은 통계 지표로서 가치가 없다(i.e., with less than 1% frequency)

예를 들어 구토는 MS와 SS의 중요한 신호이지만 약 1,200개의 시뮬레이터 결과에서 두 번밖에 발생하지 않았다. 상관 관계 및 기타 통계 데이터가 안정되기에는 너무 낮은 비율이다.

 

잘못된 징후를 줄 수 있는 증상도 후속 분석에서 제거되었다

이러한 증상(예: 지루함)은 다른 징후가 거의 없거나 전혀 없는 시뮬레이터에서 가장 높은 발생 빈도를 보였으며, 대부분의 다른 증상에 대해 높은 빈도 또는 심각도를 가진 시뮬레이터에서는 거의 볼 수 없었다.

총 28개의 증상 중 12개가 제거되었음(Table 1)

 

MSQ와 관련된 대부분의 연구는 problem severity의 주요 지표로 post and pre scores 간의 차이를 사용한다. 그러나 차이점수는 신뢰성이 떨어진다.

MSQ 관리의 일환으로, 노출 전 체크리스트를 사용하여 응답자에게 "아프다"거나 "평소의 건강 상태"가 아닌 다른 상태인지 물었다.

이 두 가지 질문 중 하나에 긍정적인 답변을 한 응답자를 제외하였을때, pre-exposure data에 미치는 영향이 거의 없었음

자신을 "건강하지 않은 사람"이라고 보고한 피실험자의 기록은 분석에서 제외되었다.

여기에 보고된 SSQ 점수 시스템은 노출 후 증상에만 적용되며, "건강하지 않은" 피험자에 대한 선별이 필요하다는 추가 전제 조건이 있다.

 

 

Factor Analyses

평가의 근거를 제공하기 위해 설문지 내 증상 하위 그룹의 요인 분석 모델을 연구

시뮬레이터 멀미는 0.2Hz에서의 선형 진동, vection, 시각 왜곡, flicker, conflict among oculomotor systems(안구 운동 시스템 간의 충돌), cue asynchrony(신호 비동기) 등 다양한 자극에 의해 발생할 수 있다

요인 분석을 통해 coincidence(우연의 일치) 또는 clusters of symptoms(증상 군집)을 식별할 수 있음

두 가지 형태의 요인 분석이 사용되었다.(principal-factors analysis, hierarchical factor analysis)

principal-factors analysis : normalized varimax rotation

(1) 직교 회전 (orthogonal ratation) : 회전된 인자들이 서로 상관되지 않도록 제약
배리맥스(VARIMAX)
가장 대중적인 기준이며, 관습적으로 가장 많이 쓰이고 있다. 이 회전법은 "분산이 극대화된다"(Variance is maximized)의 약자이다. 여기서는 요인의 분산을 극대화하는 논리를 따르는데, 요인행렬을 변환할 때 행렬의 열(요인)을 기준으로 하여 큰 값은 더 크게, 작은 값은 더 작게 회전하는 길을 찾는다. 배리맥스의 도입 이후, 학계에서 다요인 구조 속의 모든 요인들의 의미가 비로소 뚜렷하게 해석될 수 있게 되었다는 역사적 공로가 있다고 한다. 아무튼 요인의 수가 꽤 많다 싶을 때 쓰기 좋은 방법이다

 

Results

principal-factors analysis/varimax :

16가지 증상변수에서 3, 4, 5, 6가지 요인 솔루션을 추출하여 분석하였다. 3요인 solution은 가장 쉽게 해석할 수 있었다.

three distinct symptom clusters(Oculomotor, Disorientation, Nausea)

3요인 솔루션은 3개의 (부분적으로) 독립적인 증상 클러스터가 존재하며, 각각은 인간 내 다른 "목표 시스템"에 대한 시뮬레이터 노출의 영향을 반영한다.

주어진 시뮬레이터는 인간이 영향을 받는 메커니즘이나 메커니즘에 따라 이러한 클러스터 중 하나 또는 그 이상으로 분류되는 증상을 일으킬 수 있다.(A given simulator may cause symptoms that fall into none, one or more, or all of these clusters, depending on the mechanism or mechanisms by which the human is affected)

이러한 증상의 대상 시스템 조직은 이론적 및 실제적 중요성을 모두 가지고 있다. 보고된 증상의 생리학적 근거를 연구하는 데에도 유용할 수 있다.

또한 시뮬레이터가 사용자에게 문제를 일으킬 수 있는 방법을 결정하는 과정을 단순화

4요소, 5요소 및 6요인 솔루션은 채점에는 유용하지 않지만, 응답자가 시뮬레이터 노출에 따른 감정 사이에 더 세밀한 구분을 할 수 있는 능력을 제안했다는 점에서 일부 관심사가 되었다.

The 10 simulators on which data were collected divide themselves conveniently into two distinct groups(five simulators with little or no reported symptomatology and five with a markedly higher level of reported symptoms)

낮은 발생률 그룹의 약 500개의 관측치는 변수 간의 공분산에 약간만 기여했고, 따라서 증상 간의 상관 관계의 절대 수준을 줄이는 데 작용

 

Hierarchical :

표 2의 변수 최대 요인 행렬을 검사하면 각 요인에 대해 중간에서 큰 적재(.50 - 0.75)를 가지며 적재 범위가 .15 - .35인 동일한 수의 변수가 있음을 알 수 있습니다. 또한 적어도 두 개 또는 때로는 세 개 모두에 상당한 하중을 가하는 여러 변수가 있습니다.

이러한 행렬에 대한 이상적인 패턴은 모든 인자가 몇 개의 매우 큰 하중을 가지고 다른 대부분의 하중은 0에 가깝고 모든 변수는 한 인자에 대해서만 큰 하중을 가지고 다른 인자에 대한 하중은 0에 가까운 것이다.

the number of "insignificant" loadings (absolute value < .10)

 

Hierarchical 모델에 기반한 SSQ 측정은 적어도 이론적으로 varimax 모델에 기반한 측정보다 우수해야 한다.

그러나, 해석적으로 덜 명확하지만, varimax 인자는 SSQ에 포함된 제한된 증상 집합에 대해 수학적 의미에서 더 잘 정의됨

 

Deriving the SSQ Measures

SSQ 점수 체계는 표본에서 파생된 매개변수 값의 정밀도에 가장 덜 의존하기 때문에 선택되었다.

가중치 시스템과 관련 상수는 두 가지 중요한 속성을 가진 점수 분포를 생성한다.


USING AND SCORING THE SSQ

 

Administration

이후 약술된 채점 절차는 평상시 건강 상태가 아닌 모든 개인이 표본에서 제거되고 노출 후 데이터만 채점된다고 가정

Scoring

variable score(0,1,2,3) / conversion formulas given at the bottom of the table

 

Interpreting the SSQ Scores

변환 공식의 값에 대한 특별한 해석적 의미는 없다.

그들의 기능은 값이 더 쉽게 비교될 수 있는 유사한 가변성을 가진 척도를 생성하는 것 뿐이다.

 

table 5,6 비교를 통해 새로운 샘플에서 SS 문제의 상대적 심각성과 특성에 대한 표시를 얻을 수 있다.

새로운 수단이 주어진 척도에서 상위 3~4개 시뮬레이터의 범위 내에 있는 경우, 데이터와 시뮬레이터 자체에 대한 면밀한 검토가 보장될 수 있다.(If the new means fall within the range of the upper three to four simulators on a given scale, closer examination of the data and of the simulator itself is probably warranted)

조사된 10개의 시뮬레이터는 훈련 시뮬레이터 커뮤니티의 시뮬레이터를 대표할 수 있기 때문에 표 5의 정보를 통해 해당 값보다 다소 극단적인 모집단의 관측치 수를 결정할 수 있다

 

표에서 모든 척도에 대해 0-값(영점)이 관측치의 최소 40%와 최대 75%를 포함한다는 것을 유의해야 합니다. 이는 일반적으로 시뮬레이터 전반의 SS에 대한 모달 위치가 지시된 증상학이 전혀 아니며, 척도의 민감도는 증상학 범위의 상위 극단에 있다는 것을 지적한다.

이는 일반적으로 시뮬레이터 전반의 SS에 대한 모달 위치가 지시된 증상학이 전혀 아니며, 척도의 민감도는 증상학 범위의 상위 극단에 있다는 것을 지적한다.

따라서 척도는 문제가 없는 시뮬레이터를 구별하지 않고 문제 시뮬레이터와 표시된 어려움이 없는 시뮬레이터를 구별하기 위한 것이다.


AN ILLUSTRATIVE EXAMPLE: FIELD TESTING A SEMIAUTOMATICALLY SCORED SSQ

 

Method

20-month program of data acuisition

TH-57 trainers(helicopter)

3,691hops

자체 채점 소프트웨어는 즉각적인 피드백을 제공하여 조종사의 증상 및 그에 따른 제한 사항에 대한 인식을 높여 후속 활동에서 위험을 줄이기 위해 필요한 예방 조치를 취할 수 있습니다.

둘째, 시간에 걸쳐 모니터링될 때, 특정 유형의 증상뿐만 아니라 전체 발병률은 후속 증상 데이터를 비교할 수 있는 기준선이 될 수 있다.

마지막으로, 시뮬레이터 유도 증상학의 자동화된 모니터링을 사용하여 교육 강의 계획 변경뿐만 아니라 엔지니어링 기능 수정의 영향을 평가할 수 있다.

 

Results

 

그림 2의 데이터는 정상 비행 스케줄이 재개되었을 때 4가 급등한 것과 일치하며, 질병의 발생률도 감소했습니다.

그림 3은 SS 스트레스에 대한 적응에 대한 반복 홉의 영향을 보여준다. Hop 1에서 75번째 백분위수 사람은 15의 점수를 보여주는데, 이는 해군의 가장 질병을 유발하는 시뮬레이터의 평균 점수와 비슷하다(표 6 참조).

그림 4는 각 조종사의 두 번째 노출에서 얻은 점수를 노출 간 분리의 함수로 나타낸다.

질병률은 홉이 같은 날 또는 하루 간격으로 있을 때 가장 높다는 것을 유의

마찬가지로 홉이 5일 이상 간격을 두면 적응이 거의 없다.

이 시뮬레이터에서 SS의 발생률을 제어하는 측면에서 최적의 간격은 홉 사이의 2일에서 5일로 보입니다.

아마도 이 간격은 한 노출에서 다음 노출로 증상이 전달되지 않도록 충분히 길고 시뮬레이터에 대한 적응을 유지할 정도로 짧다.

 

Discussion

 

흥미로운 결과 중 하나는 75백분위수 메트릭이 시뮬레이터에서 매우 안정적인 활동 지표가 될 수 있으며, 사용 중인 엔지니어링 동안 장비의 유지 보수를 모니터링하는 데 어느 정도 유용하다는 것이다.

시뮬레이터 구성에 엔지니어링을 변경한 후 기준 점수를 얻은 다음 사건 및 증상 혼합과 비교할 것을 권장


CONCLUSIONS

 

SS와 관련된 증상 유무 및 심각도의 패턴은 멀미 패턴과 충분히 다르므로 이러한 특정 패턴의 정량화에 맞춘 별도의 측정 시스템의 사용을 정당화할 수 있다

현재 분석 및 관련 분석 모두에서 MS와 SS의 기초에는 적어도 세 가지 개별 차원이 있는 것으로 보인다

이러한 각 차원은 인간 유기체의 다른 표적 시스템을 통해 작동하여 바람직하지 않은 증상을 생성한다

 

VARIMAX 회전으로 식별된 변수에 단위 가중치를 사용하는 것)은 대부분의 애플리케이션에 적합

 

 

'Papers' 카테고리의 다른 글

Digging Into Self-Supervised Monocular Depth Estimation(monodepth2)  (0) 2022.03.04

https://arxiv.org/abs/1806.01260

 

Digging Into Self-Supervised Monocular Depth Estimation

Per-pixel ground-truth depth data is challenging to acquire at scale. To overcome this limitation, self-supervised learning has emerged as a promising alternative for training models to perform monocular depth estimation. In this paper, we propose a set of

arxiv.org

Abstract

  1. a minimum reprojection loss, designed to robustly handle occlusions
  2. full-resolution multi-scale sampling method that reduces visual artifacts
  3. auto-masking loss to ignore training pixels that violate camera motion assumptions

1. Introduction

  • 단순 이미지 하나에서 depth 추출하는것은 어렵다(with out second image to enable triangulation)
  • Generating high quality depth-from-color는 LIDAR를 대체하기 좋음(저렴함)
  • 이렇게 이미지에서 depth를 추출할수 있으면 use large unlabeled image datasets for the pretraining of deep networks for downstream discriminative tasks하기 쉬움
  • but 감독 학습을 위한 정확한 실측 depth data로 크고 다양한 훈련 데이터 세트를 수집하는 것 자체가 힘들다
  • 이에 대한 대응으로 최근 몇몇 self-supervised approaches들은 대신 동기화된 스테레오 쌍이나 단안 비디오만을 사용하여 단안 깊이 추정 모델을 훈련하는 것이 가능(but challenges가 존재)
  • propose three architectural and loss innovations that lead to large improvements in monocular depth estimation when training with monocular video, stereo pairs, or both
    1. monocular supervision을 사용할 때 발생하는 occluded pixels 문제를 해결하기 위한 appearance matching loss
    2. auto masking : monocular training에서 상대적인 카메라 움직임이 관찰되지 않는 픽셀을 무시하는 접근법
    3. 입력 해상도에서 모든 영상 샘플링을 수행하여 depth artifacts를 줄이는 multi-scale appearance matching loss

2. Related Work

2.1 Supervised Depth Estimation

  • combining local predictions
  • non-parametric scene sampling(DepthTransfer: Depth Extraction from Video Using Non-parametric Sampling)
  • end-to-end supervised learning
더보기

(Depth Map Prediction from a Single Image using a Multi-Scale Deep Network)

(Deeper Depth Prediction with Fully Convolutional Residual Networks)

(Deep Ordinal Regression Network for Monocular Depth Estimation)

  • 위와같이 다양한 방법들은 학습시 ground truth가 필요한 fully supervised 방식인데 이러한 방식은 실제 환경에서 획득하기 어려운 단점이 존재함
  • weakly supervised training data, Synthetic training data 등등

2.2 Self-supervised Depth Estimation

ground truth가 없기에 image reconstruction 즉 supervisory signal을 만들어서 대안으로 사용해보자

Self-supervised Stereo Training

- synchronized stereo pairs를 사용, pair간의 pixel disparities를 통해 monocular depth estimation(GT로 사용)

Self-supervised Monocular Training

- monocular videos에서 frame사이의 camera pose를 추정해 depth estimation

 

3. Method

3.1 Self-Supervised Training

  • pixel하나당 depth를 찾아내는것은 ill-posed problem임 
  • 이 애매함을 좀 해결하기위해 Classical binocular and multi-view stereo methods를 사용 depth maps을 강제로 smoothness하게 만듬
  • 다른 시점의 이미지에서 target image로 view-synthesis를 예측하는 network training

 

- minimization of a photomaetric reprojection error at training time 

  • $I_{t}$ : single color input
  • $D_{t}$ : depth map
  • $I_t'$  : relative pose for each source view
  • $T_{t->t'}$ : respect to target image $I_t$'s pose
  • $L_p$ : photo metric reprojection error

 

  • pe : photometric reconstruction error
  • proj() : resulting 2D coordinates of the projected depths $D_t$ in $I_t'$(depth와 $I_t$에서 $I_t'$로의 pose $T_{t->t}'$를 이용하여 projection된 위치)
  • $\left< \right>$ : sampling operator

 

보통 error는 bilineara sampling된 pixel값의 L1 distance를 사용하지만 이 논문에선 L1 distance에 SSIM을 추가

 

  • $\alpha$ = 0.85, use edge-aware smoothness

 

  • 여기서 $d_{t}^{*} = d_{t} / \bar{d_t}$이며 mean-normalized inverse depth를 의미
  • 학습에서는 target 이미지 앞뒤의 2개 이미지를 source이미지로 하여 pose와 depth를 estimation 하도록 학습
  • stereo방식에선 stereo pair의 다른 이미지를 source이미지로 사용

3.2 Improved Self-Supervised Depth Estimation

Per-Pixel Minimum Reprojection Loss

  • multiple source images에서 reprojection error를 계산할때 여러 source images로 부터 계산된 error을 평균내서 사용
  • pixel이 target image에서 보이지만 source image에서 안보일때 문제가 발생
  • 만약 network가 pixel에대한 정확한 depth값을 예측했음에도 source image에서 corresponing color가 가려졌을때 pixel값의 차이는 error로 계산되고 penalty가 되어버림
  • 이 논문에선 이러한 문제를 해결하기위해 평균대신 minimum을 사용함

 

minimum reprojection loss

Auto-Masking Stationary Pixels

  • Self-supervised monocular training 주로 카메라는 움직이고 scene은 static한 상황으로 가정
  • 위의 가정이 깨질경우 성능이 떨어지며 이는 depth map에서 무한대로 멀리 있는 hole로 나타나게 된다
  • 여기에 착안하여 새로운 auto-masking 방법을 제안. 만약 target 이미지와 source 이미지 사이에 appearance 변화가 없으면 이를 계산에서 제외
  • 이는카메라가 움직이지 않는 상황이나 카메라와 동일한 속도로 물체가 움직이는 부분을 무시할 수 있게 해준다
  • 이전의 방법들처럼 픽셀 마다 mask $\mu$를 할당하여 loss로 사용하되, 이전에는 mask를 네트워크가 estimation하도록 하거나, 혹은 객체 움직임에서 추정해 냈지만 여기에서는 더 간단한 방법을 사용하였다
  •  warp된 source image와의 reprojection error가 warp하지 않은 source image보다 작은 경우, 이러한 상황으로 판단하여 mask를 0으로, 그렇지 않으면 1로 할당

 

mask $\mu$

Multi-scale Estimation

  • Bilinear sampler에 의한 local minimum에 빠지는 것을 막기 위해 multi-scale depth prediction을 사용
  • 이전 방법들은 decoder에서 각 scale에 대해 별도로 loss들을 계산하여 이를 합하는 방법을 사용
  • 이는 low resolution에서 low-texture regions 영역으로 인해 holes들이 생기는것을 확인
  • 논문에서는 photometric error를 저해상도의 이미지에서 계산하는 대신 저해상도 depth map을 원래의 해상도로 업샘플한 뒤, 높은 해상도에서 error(pe)를 계산(Fig. 3(d))
  • 이는 matching patches와 비슷한 과정인데, 저 해상도의 한 depth는 고해상도로 warping 될 경우 patch에 해당되기 때문

 

Final Training Loss

combine our per-pixel smoothness and masked photometric losses

 $$L = \mu L_p + \lambda L_s$$

 

3.3 Additional Considerations

network based on the general U-Net architecture

ResNet18 as encoder

start with weights pretrained on ImageNet

Machine Learning : 데이터를 이용하여 컴퓨터를 학습시키는 방법론


머신러닝 알고리즘

  1. 지도학습(Supervised learning)
  2. 비지도학습(Unsupervised learning)
  3. 강화학습(Reinforcement learning)

지도학습(Supervised learning)

  • 데이터에 대한 명시적인 정답 즉 레이블(label)이 주어진 상태에서 컴퓨터가 학습하는 방식
  • 정답이 있는 데이터를 활용하여 데이터를 학습, 입력 값(X data)이 주어지면 입력값에 대한 Label(Y data)을 주어 학습
  • 지도학습은 [데이터, 레이블]의 형태를 컴퓨터에게 제공하여 학습을 진행

1) 분류(Classification) - discrete value

주어진 데이터를 정해진 카테고리(레이블)에 따라 분류하는 문제

맞다 아니다의 이진 분류 문제, 2가지 이상으로 분류하는 다중 분류 문제

 - kNN, Naive Bayes, Support vector, Machine decision

 

2) 회귀(Regression) - continuous value

어떤 데이터들의 Feature를 기준으로 연속된 값(그래프)을 예측하는 문제

 - Linear regression, Locally weighted linear, Ridge, Lasso


비지도학습(Unsupervised learning)

  • 정답 레이블이 없는 데이터를 비슷한 특징끼리 군집화하여 새로운 데이터에 대한 결과를 예측하는 방식
  • 라벨링 되어있지 않은 데이터로부터 패턴이나 형태를 찾아야 하기때문에 지도학습보다 난이도가있음
  • 데이터의 숨겨진 feature나 구조를 발견하는데 사용
  • Clustering, K Means, Density estimation, Exception maximization, DBSCAN

1) 클러스터링(Clustering)

[데이터] 형태의 데이터를 컴퓨터에 학습시켜 데이터의 결과값을 예측하는 것이 아닌 비슷한 특성을 가지는 데이터들끼리 묶음(군집화)


자가지도 학습(Self-Supervised learning)

  • 레이블이 없는 Untagged data를 기반으로 한 학습
  • 우선 Unlabeled 데이터들을 이용하여 사용자가 새로운 문제를 정의하며 정답도 사용자가 직접 정해줌
  • 이 때, 사용자가 정의한 새로운 문제를 논문 들에서는 pretext task라고함
  • Network로 하여금 만든 pretext task를 학습하게 하여 데이터 자체에 대한 이해를 높일 수 있게 하고, 이렇게 network를 pretraining 시킨 뒤 downstream task로 transfer learning을 하는 접근 방법

강화학습(Reinforcement learning)

  • 데이터가 주어진 정적인 환경에서 학습하는 지도, 비지도 학습과 달리 강화학습은 에이전트가 주어진 환경에서 어떤 행동을 취하고 그에대한 보상을 얻으면서 학습
  • 이때 에이전트는 보상을 최대한 많이 얻는 쪽으로 행동함, 강화학습은 동적인 상태에서 데이터를 수집
  • DQN, A3C

자가지도 학습

 

cpu

산술논리 연산장치ALU

제어장치(CU) - 작업지시

레지스터 - cpu내에 데이터를 임시로 보관

 

버퍼 - 일정량의 데이터를 모아 옮김으로 속도의 차이를 완화

캐시 - 메모리와 cpu간의 속도 차이를 완화히기 위해 메모리의 데이터를 미리 가져와 저장해두는 임시장소

 

저장장치 계층구조

레지스터 - 캐시 - 메모리 - 저장장치

 

인터럽트

- cpu의 작업과 저장장치의 데이터 이동을 독립적으로 운영하여 효율을 높임

 1) cpu가 입출력 관리자에게 입출력 명령을 보냄

 2) 입출력 관리자는 명령받은 데이터를 메모리에 가져다놓거나 메모리에있는 데이터를 저장장치로 옮김

 3) 데이터 전송이 완료되면 입출력 관리자는 완료신호를 cpu에 보냄(인터럽트)

- 하던 작업을 중단하고 처리해야하는 신호(인터럽트)

 

 

프로그램 - 저장장치에 저장되어있는 정적인 상태

프로세스 - 실행을 위해 메모리에 올라온 동적인 상태

 

프로세스 제어 블록(PCB) : 프로세스를 처리하는데 필요한 다양한 정보를 가지고있음

- 프로세스 구분자(PID)

- 메모리 위치정보

- 중간값(프로그램 카운터, 레지스터 등)

 

프로세스 = 프로그램 + 프로세스 제어블록

 

프로세스 구조

- 코드영역(프로그램의 본문이 기술된곳, 프로그래머가 작성한 프로그램이 코드영역에 탑재)

- 데이터 영역(코드가 실행되면서 사용하는 변수나 파일등의 각종 데이터를 모아놓은곳)

- 스택 영역(운영체제가 프로세스를 실행하기 위해 부수적으로 필요한 데이터를 모아놓은곳)

 

운영체제 작업 단위 = 프로세스

CPU 작업단위 = 스레드

 

/// 프로그램 실행 -> 운영체제가 코드와 데이터를 메모리에 가져옴 -> 프로세스 제어블록 생성 -> 작업에 필요한 메모리 영역 확보 -> 준비된 프로세스를 준비큐에 삽입 -> 프로세스가 생성된후 CPU 스케줄러는 프로세스가 해야할일을 CPU에 전달(이때 스케줄러가 CPU에 전달하는 일 하나가 스레드임)

 

스레드 : 프로세스의 코드에 정의된 절차에 따라 CPU에 작업 요청을 하는 실행 단위

 

 

메모리 관리

Segmentation(가변분할방식)

- 프로세스 크기에 따라 메모리를 나눔

Paging(고정분할방식)

- 프로세스 크기와 상관없이 메모리를 같은크기로 나눔

 

컴파일과정

소스코드 -> (컴파일러) -> 목적코드(기계어) -> (링커(라이브러리)) -> 실행(동적라이브러리)

- 컴파일-> 목적 코드와 라이브러리 연결 -> 동적 라이브러리를 포함하여 최종 실행

'CS Study > OS' 카테고리의 다른 글

01 운영체제의 개요  (0) 2022.09.28
2. Chapter 3. Processes  (0) 2021.10.22
1. Chapter 1-2. Introduction & O/S Structures  (0) 2021.10.09

 

  • 배열(array) 리스트(list)의 차이점
  • 배열은 인덱스를 가진 데이터의 집합이고, 리스트는 인덱스 없이 순차적으로 저장된 데이터의 집합이다.
  • 배열은 메모리에 연속적으로 저장되고 리스트는 메모리에 분산 되어 저장된다. 

6.1 배열(array)로 구현된 리스트

- 배열을 이용하여 리스트를 구현하면 순차적인 메모리 공간이 할당됨(리스트의 순차적 표현)

#include<stdio.h>
#include<stdlib.h>
#define MAX_LIST_SIZE 100


typedef int element;
typedef struct {
	element array[MAX_LIST_SIZE]; // 배열의 정의
	int size; // 현재 리스트에 저장된 항목들의 개수
} ArrayListType;

// 오류 처리 함수
void init(ArrayListType* L)
{
	L->size = 0;
}

// 리스트가 비어 있으면 1을 반환
// 그렇지 않으면 0을 반환
int is_empty(ArrayListType* L)
{
	return L->size == 0;
}

// 리스트가 가득 차 있으면 1을 반환
// 그렇지 않으면 1을 반환
int is_full(ArrayListType* L)
{
	return L->size == MAX_LIST_SIZE;
}
element get_entry(ArrayListType* L, int pos)
{
	if (pos < 0 || pos >= L->size)
		printf("위치 오류");
	return L->array[pos];
}

// 리스트 출력
void print_list(ArrayListType* L)
{
	int i;
	for (i = 0; i < L->size; i++)
		printf("%d->", L->array[i]);
	printf("\n");
}

void insert_last(ArrayListType* L, element item)
{
	if (L->size >= MAX_LIST_SIZE)
	{
		printf("리스트 오버플로우");
	}
	L->array[L->size++] = item;
}

void insert(ArrayListType* L, int pos, element item)
{
	if (!is_full(L) && (pos >= 0) && (pos <= L->size)) {
		for (int i = (L->size - 1); i >= pos; i--)
			L->array[i + 1] = L->array[i];
		L->array[pos] = item;
		L->size++;
	}
}

element delect(ArrayListType* L, int pos)
{
	element item;

	if (pos < 0 || pos >= L->size)
		printf("위치 오류");
	item = L->array[pos];
	for (int i = pos; i < (L->size - 1); i++)
		L->array[i] = L->array[i + 1];
	L->size--;
	return item;
}

int main(void)
{
	// ArrayListType를 정적으로 생성하고 ArrayListType를 가리키는 포인터를 함수의 매개변수로 전달
	ArrayListType list;

	init(&list);
	insert(&list, 0, 10); print_list(&list); // 0번째 위치에 10 추가
	insert(&list, 0, 20); print_list(&list); // 0번째 위치에 20 추가
	insert(&list, 0, 30); print_list(&list); // 0번째 위치에 30 추가
	insert_last(&list, 40); print_list(&list); // 맨끝에 40 추가
	delect(&list, 0); print_list(&list); // 0번째 항목 삭제
	return 0;
}

6.2 연결 리스트(Linked List)

- 동적으로 크기가 변할 수 있고 삭제나 삽입 시에 데이터를 이동할 필요가 없는 연결된 표현

- 이 연결된 표현은 포인터를 사용하여 데이터들을 연결함

  • 연결 리스트의 구조

- 연결리스트는 노드(node)들의 집합, 다른 노드로 가기 위해서는 현재 노드가 가지고 있는 포인터를 이용

Data field에는 우리가 저장하고 싶은 데이터가 들어감, Link field에는 다른 노드를 가리키는 포인터가 저장됨

- 연결 리스트에서는 연결 리스트의 첫번째 노드를 알아야 만이 전체의 노드에 접근할수 있음

- 따라서 연결 리스트마다 첫번째 노드를 가리키고 있는 변수가 필요한데 이것을 헤드포인터(head pointer)라고 한다

연결 리스트의 종류

6.3 단순 연결 리스트(Single Linked List)

- 노드 들이 하나의 링크 필드를 가지며 이 링크 필드를 이용하여 모든 노드들이 연결. 마지막 노드의 링크 필드값 NULL

  • 노드의 정의

- 노드는 자기 참조 구조체(자기 자신을 참조하는 포인터를 포함하는 구조체)를 이용하여 정의됨

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

typedef int element;

typedef struct ListNode { // 노드 타입을 구조체로 정의
	element data;
	struct ListNode* link;
} ListNode;

// 공백 리스트 생성
// 구조체 변수 선언
ListNode* head = NULL;
  • 노드의 생성

노드의 크기만큼 동적메모리를 할당 받음, 이 동적 메모리가 하나의 노드가됨. 동적메모리의 주소를 헤드 포인터인 head에 저장

head = (ListNode*)malloc(sizeof(ListNode));
  • 노드의 연결
// 두번째 노드 생성
ListNode* p;
p = (ListNode*)malloc(sizeof(ListNode));
p->data = 20;
p->link = NULL;

// 첫번째 노드의 링크가 두번째 노드를 가리킴
head->link = p;
#include<stdio.h>
#include<stdlib.h>

typedef int element;
typedef struct ListNode { // 노드 타입을 구조체로 정의
	element data;
	struct ListNode* link;
} ListNode;

// 오류 처리 함수
void error(char* message)
{
	fprintf(stderr, "%s\n", message);
	exit(1);
}

ListNode* insert_first(ListNode* head, int value)
{
	ListNode* p = (ListNode*)malloc(sizeof(ListNode));
	p->data = value;
	p->link = head; // 헤드 포인터의 값을 복사
	head = p; // 헤드 포인터 변경
	return head;
}

// 노드 pre 뒤에 새로운 노드 삽입
ListNode* insert(ListNode* head, ListNode* pre, element value)
{
	ListNode* p = (ListNode*)malloc(sizeof(ListNode));
	p->data = value;
	p->link = pre->link;
	pre->link = p;
	return head;
}

ListNode* delete_first(ListNode* head)
{
	ListNode* removed;
	if (head == NULL) return NULL;
	removed = head;
	head = removed->link;
	free(removed);
	return head;
}

// pre가 가리키는 노드의 다음 노드를 삭제
ListNode* delete(ListNode* head, ListNode* pre)
{
	ListNode* removed;
	removed = pre->link;
	pre->link = removed->link;
	free(removed);
	return head;
}

void print_list(ListNode* head)
{
	for (ListNode* p = head; p != NULL; p = p->link)
		printf("%d->", p->data);
	printf("NULL \n");
}

int main(void)
{
	ListNode* head = NULL;

	for (int i = 0; i < 5; i++)
	{
		head = insert_first(head, i); // insert_first()가 반환된 헤드 포인터를 head에 대입
		print_list(head);
	}

	for (int i = 0; i < 5; i++)
	{
		head = delete_first(head);
		print_list(head);
	}
	return 0;
}

'CS Study > DataStructure' 카테고리의 다른 글

05 큐  (0) 2022.01.20
04 스택  (0) 2022.01.20
03 배열, 구조체, 포인터  (0) 2022.01.18
02 순환  (0) 2022.01.18
01 자료구조와 알고리즘  (0) 2022.01.18

5.1 queue

- FIFO

 

5.2 선형큐(linear queue)

- 구현이 간단하나 선형큐의 경우 앞으로 이동이 필요함(안그러면 배열의 앞부분이 비어있어도 사용못함)

#include<stdio.h>
#include<stdlib.h>
#define MAX_QUEUE_SIZE 5

typedef int element;
typedef struct {
	int front;
	int rear;
	element data[MAX_QUEUE_SIZE];
} QueueType;

// 오류 함수
void error(char* message)
{
	fprintf(stderr, "%s\n", message);
	exit(1);
}

void init_queue(QueueType* q)
{
	q->rear = -1;
	q->front = -1;
}

void queue_print(QueueType* q)
{
	for (int i = 0; i < MAX_QUEUE_SIZE; i++)
	{
		if (i <= q->front || i > q->rear)
			printf(" | ");
		else
			printf("%d | ", q->data[i]);
	}
	printf("\n");
}

int is_full(QueueType* q)
{
	if (q->rear == MAX_QUEUE_SIZE - 1)
		return 1;
	else
		return 0;
}

int is_empty(QueueType* q)
{
	if (q->front == q->rear)
		return 1;
	else
		return 0;
}

void enqueue(QueueType* q, int item)
{
	if (is_full(q))
	{
		printf("queue is full");
		return;
	}
	q->data[++(q->rear)] = item;
}

int dequeue(QueueType* q)
{
	if (is_empty(q))
	{
		printf("queue is empty");
		return -1;
	}
	int item = q->data[++(q->front)];
	return item;
}

int main(void)
{
	int item = 0;
	QueueType q;

	init_queue(&q);

	enqueue(&q, 10); queue_print(&q);
	enqueue(&q, 20); queue_print(&q);
	enqueue(&q, 30); queue_print(&q);
	enqueue(&q, 40); queue_print(&q);

	item = dequeue(&q); queue_print(&q);
	item = dequeue(&q); queue_print(&q);
	item = dequeue(&q); queue_print(&q);
	return 0;
}

5.3 원형큐

- front와 rear의 값이 배열의 끝에 도달하면 다음에 증가되는 값은 0이 되도록 설계

- 한칸은 늘 공백을유지(포화상태와 공백상태 구별을 위해)

init_queue(), is_empty(), is_full(), enqueue(), dequeue()

#include<stdio.h>
#include<stdlib.h>
#define MAX_QUEUE_SIZE 5

typedef int element;
typedef struct {
	int front;
	int rear;
	element data[MAX_QUEUE_SIZE];
} QueueType;

// 오류 함수
void error(char* message)
{
	fprintf(stderr, "%s\n", message);
	exit(1);
}

// queue 초기화
void init_queue(QueueType* q)
{
	q->rear = q->front = 0;
}

// 공백상태 검출함수
int is_empty(QueueType* q)
{
	return (q->front == q->rear);
}

// 포화상태 검출함수
int is_full(QueueType* q)
{
	return ((q->rear + 1) % MAX_QUEUE_SIZE == q->front);
}

// 원형큐 출력 함수
void queue_print(QueueType* q)
{
	printf("QUEUE(front=%d rear =%d) = ", q->front, q->rear);
	if (!is_empty(q)) {
		int i = q->front;
		do {
			i = (i + 1) % (MAX_QUEUE_SIZE);
			printf("%d | ", q->data[i]);
			if (i == q->rear)
				break;
		} while (i != q->front);
	}
	printf("\n");
}

// 삽입 함수
void enqueue(QueueType* q, int item)
{
	if (is_full(q))
		printf("queue is full");
	q->rear = (q->rear + 1) % MAX_QUEUE_SIZE;
	q->data[q->rear] = item;
}

// 삭제 함수
int dequeue(QueueType* q)
{
	if (is_empty(q))
		printf("queue is empty");
	q->front = (q->front + 1) % MAX_QUEUE_SIZE;
	return q->data[q->front];
}

int main(void)
{
	QueueType queue;
	int element;

	init_queue(&queue);

	enqueue(&queue, 1);
	enqueue(&queue, 2);
	enqueue(&queue, 3);
	enqueue(&queue, 3);
	queue_print(&queue);

	dequeue(&queue);
	dequeue(&queue);
	dequeue(&queue);
	queue_print(&queue);
	return 0;
}

5.4  큐의 응용(버퍼)

- 서로 다른 속도로 실행되는 두 프로세스 간의 상호작용을 조화시키는 버퍼역할에 사용

 

5.5 덱(deque)

- double-ended queue : 큐의 front와 rear에서 모두 삽입과 삭제가 가능한 큐

init_deque(), is_empty(), is_full(), add_rear(), delect_front(), delect_rear() 

'CS Study > DataStructure' 카테고리의 다른 글

06 연결리스트1  (0) 2022.01.20
04 스택  (0) 2022.01.20
03 배열, 구조체, 포인터  (0) 2022.01.18
02 순환  (0) 2022.01.18
01 자료구조와 알고리즘  (0) 2022.01.18

4.1 Stack

- LIFO

- 복귀할 주소를 기억하는데 사용됨

- push : 스택의 맨 위에 item을 추가

- pop : 스택의 맨 위의 원소를 제거해서 반환

 

4.2 스택의 구현

- 정수배열 스택

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

#define MAX_STACK_SIZE 100 // 스택의 최대 크기
typedef int element; // 데이터의 자료형
element stack[MAX_STACK_SIZE]; // 1차원 배열
int top = -1;

// 공백상태 검출함수
int is_empty()
{
	return (top == -1);
}

// 포화상태 검출함수
int is_full()
{
	return (top == MAX_STACK_SIZE - 1);
}

// 삽입(push)함수
void push(element item)
{
	if (is_full())
	{
		fprintf(stderr, "스택 포화 에러\n");
		return;
	}
	else
		stack[++top] = item;
}

// 삭제(pop)함수
element pop()
{
	if (is_empty())
	{
		fprintf(stderr, "스택 공백 에러\n");
		exit(1);
	}
	else
		return stack[top--];
}

// 피크(peek)함수
element peek()
{
	if (is_empty())
	{
		fprintf(stderr, "스택 공백 에러\n");
		exit(1);
	}
	else
		return stack[top];
}

- top과 stack배열을 하나의 구조체로 결합시키고 이 구조체의 포인터를 함수로 전달

StackType이라는 새로운 구조체 타입을 만들고 여기에 stack 배열과 top을 넣음

#include<stdio.h>
#include<stdlib.h>
#define MAX_STACK_SIZE 100

// 스택이 구조체로 정의됨
typedef int element;
typedef struct {
	element data[MAX_STACK_SIZE];
	int top;
} StackType;

// 스택 초기화 함수
void init_stack(StackType* s)
{
	s->top = -1;
}

// 공백상태 검출함수<모든 연산은 구조체의 포인터를 받는다>
int is_empty(StackType *s)
{
	return (s->top == -1);
}

// 포화상태 검출함수
int is_full(StackType* s)
{
	return (s->top == MAX_STACK_SIZE - 1);
}

// 삽입(push)함수
void push(StackType *s, element item)
{
	if (is_full(s))
	{
		fprintf(stderr, "스택 포화 에러\n");
		return;
	}
	else
		s->data[++(s->top)] = item;
}

// 삭제(pop)함수
element pop(StackType* s)
{
	if (is_empty(s))
	{
		fprintf(stderr, "스택 공백 에러\n");
		exit(1);
	}
	else
		return s->data[s->top--];
}

// 피크(peek)함수
element peek(StackType* s)
{
	if (is_empty(s))
	{
		fprintf(stderr, "스택 공백 에러\n");
		exit(1);
	}
	else
		return s->data[s->top];
}

int main(void)
{
	StackType s; // 스택을 정적으로 생성

	init_stack(&s);
	push(&s, 1);
	push(&s, 2);
	push(&s, 3); // 함수를 호출할 때 스택의 주소를 전달
	printf("%d\n", pop(&s));
	printf("%d\n", pop(&s));
	printf("%d\n", pop(&s));
	return 0;
}

4.3 동적 배열 스택

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

// 스택이 구조체로 정의됨
typedef int element;
typedef struct {
	element *data; // data는 포인터로 정의됨
	int capacity; // 현재 크기
	int top;
} StackType;

// 스택 생성 함수
void init_stack(StackType* s)
{
	s->top = -1;
	s->capacity = 1;
	s->data = (element*)malloc(s->capacity * sizeof(element));
}

// 공백상태 검출함수<모든 연산은 구조체의 포인터를 받는다>
int is_empty(StackType* s)
{
	return (s->top == -1);
}

// 포화상태 검출함수
int is_full(StackType* s)
{
	return (s->top == s->capacity - 1);
}

// 삽입(push)함수
void push(StackType* s, element item)
{
	if (is_full(s))
	{
		s->capacity *= 2;
		s->data =
			(element *)realloc(s->data, s->capacity * sizeof(element));
	}
	s->data[++(s->top)] = item;
}

// 삭제(pop)함수
element pop(StackType* s)
{
	if (is_empty(s))
	{
		fprintf(stderr, "스택 공백 에러\n");
		exit(1);
	}
	else
		return s->data[s->top--];
}

int main(void)
{
	StackType s; // 스택을 정적으로 생성

	init_stack(&s);
	push(&s, 1);
	push(&s, 2);
	push(&s, 3); // 함수를 호출할 때 스택의 주소를 전달
	printf("%d\n", pop(&s));
	printf("%d\n", pop(&s));
	printf("%d\n", pop(&s));
	free(s.data);
	return 0;
}

 

'CS Study > DataStructure' 카테고리의 다른 글

06 연결리스트1  (0) 2022.01.20
05 큐  (0) 2022.01.20
03 배열, 구조체, 포인터  (0) 2022.01.18
02 순환  (0) 2022.01.18
01 자료구조와 알고리즘  (0) 2022.01.18

3.1 배열

배열 : 동일한 타입의 데이터를 한 번에 여러 개 만들 때 사용됨, 연속적인 메모리 공간이 할당되고 인덱스 번호를 사용하여 쉽게 접근이 가능

int list[i]
int list[3][4] // 3개행 5개열

3.2 구조체

타입이 다른 데이터를 묶는 방법

struct 구조체이름 {
	항목1;
	항목2;
	...
};
typedef struct studentTag{
    char name[10] // 문자 배열로 된 이름
    int age;
    double gpa;
} student;

int main(void){
    student a = { "kim", 20, 4.3 };
    student b = { "park", 21, 4.1 };
    return 0;
}

3.3 포인터

포인터 : 다른 변수의 주소를 가지고 있는 변수

#include<stdio.h>
int main(void) {
    int a = 100; // 정수형 변수
    int* p;
    p = &a; // 변수의 주소를 포인터에 저장
    printf("%d\n", a); // a에 저장된 값 (100)
    printf("%d\n", &a); // a의 주소 (4061816)
    printf("%d\n", p); // 포인터 p가 가르키는 주소 (4061816)
    printf("%d\n", *p); // 포인터 p가 가르키는 주소에 저장된 값 (100)
    return 0;
}

3.4 동적 메모리 할당

- 동적 메모리 할당(dynamic memory allocation) : 필요한 만큼의 메모리를 os로부터 할당받아 사용하고 사용이 끝나면 메모리 반납

- heap : 동적 메모리가 할당되는 공간

'CS Study > DataStructure' 카테고리의 다른 글

06 연결리스트1  (0) 2022.01.20
05 큐  (0) 2022.01.20
04 스택  (0) 2022.01.20
02 순환  (0) 2022.01.18
01 자료구조와 알고리즘  (0) 2022.01.18

+ Recent posts