1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
 
//정올 2364 사냥꾼
//백준 8983 사냥
//2019-03-05
 
public class Main_8983{
    public static void main(String[] args) throws Exception {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(bf.readLine(), " ");
        int M = Integer.parseInt(st.nextToken()); // 사대 수
        int N = Integer.parseInt(st.nextToken()); // 동물 수
        long L = Integer.parseInt(st.nextToken()); // 사정거리
        int ans = 0;
        long yy = Long.MIN_VALUE;
        long xx = Long.MIN_VALUE;
        long[] gun = new long[M+1];
        pair[] animal = new pair[N];
        st = new StringTokenizer(bf.readLine(), " ");
        for (int i = 0; i < M; i++) {
            int token = Integer.parseInt(st.nextToken());
 
            gun[i] = token;
        }
        gun[M] = 1000000001;
        Arrays.sort(gun);
 
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(bf.readLine(), " ");
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());
             
 
            animal[i] = new pair(x, y);
        }
        Arrays.sort(animal);
 
        /*
         * gun과 animal의 좌표를 x를 기준으로 정렬한다. 
         * animal을 기준으로 두고, gun을 순회한다. 
         * gun의 처음부터 순회하다가 사정거리 안에 포함되는 사대를 발견했을 때, 카운트 해주고 사대의 시작 위치를 바꿔준다. 
         * 다음 동물은 현재 사대부터 보면 된다 .
         */
 
        int cur = 0;
        for (int i = 0; i < N; i++) {
            pair p = animal[i];
            int ax = p.x;
            int ay = p.y;
            if (ay > L || ax < gun[0- L ) continue;
            
            //animal의 x좌표가 gun의 최대  최대 범위보다 커지는 경우 그 이후의 좌표는 탐색하지 않아도 된다.
            if (ax > gun[M - 1+ L) break;
 
            for (int j = cur; j < M; j++) { // 사대 검사
                long dist = getDist(gun[j],ax,ay);
                if(dist<=L) {
                    ans++;
                    cur = j;
                    break;
                }
                //사정거리안에 없으면서 gun의 x값이 크면 break
                if(ax<gun[j]) break;
 
            }
 
        }
 
        System.out.println(ans);
    }
 
    public static long getDist(long x, int a, int b) {
        return Math.abs(x - a) + b;
    }
 
    static class pair implements Comparable<pair> {
        int x;
        int y;
 
        public pair(int x, int y) {
            super();
            this.x = x;
            this.y = y;
        }
 
        @Override
        public int compareTo(pair o) {
            // TODO Auto-generated method stub
            return this.x-o.x;//오름차순 
        }
    }
}
 
cs


CPU_Scheduler

CPU 스케줄링

CPU란?

프로그램의 기계어 명령을 실제로 수행하는 컴퓨터 내의 중앙처리장치.

일반적으로 시스템 내에 하나밖에 없으므로 여러 프로그램이 동시에 수행되는 시분할 환경에서의 CPU는 매우 효율적으로 관리되어야 하는 자원이다.

  • 처리순서

    1. 프로그램이 시작되어 메모리에 올라간다.
    2. 프로그램 카운터라는 이름의 레지스터가 현재 CPU에서 수행할 코드의 메모리 주소값을 가지고 있다.
    3. CPU는 프로그램 카운터가 가르키는 주소의 기계어 명령을 수행한다.

 

CPU 스케줄러

CPU를 사용하는 패턴이 상이한 여러 프로그램이 동일한 시스템 내부에서 함께 실행되기 때문에 필요하다.

준비 상태에 있는 프로세스들 중에 어떠한 프로세스에게 CPU를 할당할지 결정하는 운영체제의 코드.

 

CPU스케줄링이 발생하는 상황

  1. 실행 상태에 있던 프로세스가 I/O 요청 등에 의해 봉쇄상태로 바뀌는 경우
  2. 실행 상태에 있던 프로세스가 타이머 인터럽트 발생에 의해 준비 상태로 바뀌는 경우
  3. I/O 요청으로 봉쇄 상태에 있던 프로세스의 I/O 작업이 완료되어 인터럽트가 발생하고 그 결과 이 프로세스의 상태가 준비 상태로 바뀌는 경우
  4. CPU에서 실행 상태에 있는 프로세스가 종료되는 경우

 

CPU 스케줄링 방식

  • 비선점형 방식

    CPU를 획득한 프로세스가 스스로 CPU를 반납하기 전까지는 CPU를 빼앗기지 않는 방법

    일반적으로 선점형보다 스케줄러의 호출 빈도가 낮고 Context Switching 오버헤드가 작다.

    (1), (4)가 대표적인 예.

     

  • 선점형 방식

    프로세스가 CPU를 계속 사용하기 원하더라도 강제로 빼앗을 수 있는 방법

    "선점"이라는 말은 OS가 프로세스 자원을 선점하고 있다가 각 프로세스의 요청이 있을 때 특정 요건들을 기준으로 자원을 배분하는 방식 => 한 프로세스가 자원을 독점 할 수 없다.

    (2), (3)이 대표적인 예

 

디스패처 dispatcher

CPU스케줄러가 어떤 프로세스에게 할당할지 결정하고 나면, 새롭게 선택된 프로세스가 CPU를 할당받고 작업을 수행할 수 있도록 환경설정하는 커널 모듈.

PCB에 저장, 복원 등등.. 소요 시간은 Context Switching 오버헤드에 해당.

 

 

스케줄링 알고리즘

FCFS

FCFS(First-Come First-Served)는 프로세스가 준비 큐에 도착한 시간 순서대로 CPU 할당

프로세스가 자발적으로 CPU를 반납할 때까지 CPU를 선점하지 않는다. => 비선점형 방식

단점 : Convoy(콘보이) 현상

CPU버스트가 짧은 프로세스가 CPU버스트가 긴 프로세스보다 나중에 도착해 오랜 시간을 기다려야 하는 상황.

(CPU를 짧게 사용해야 하는 프로세스가 길게 사용해야하는 프로세스보다 나중에 도착해서 무한 대기)

 

SJF

SJF(Shortest-Job First)는 CPU 버스트가 가장 짧은 프로세스에게 먼저 CPU를 할당하는 방식.

프로세스들이 준비큐에서 대기하는 전체적인 시간이 줄어든다.

  • 비선점형

    일단 CPU를 획득하면 자진 반납할때까지 선점 당하지 않는 방식.

  • 선점형

    준비 큐에서 CPU버스트가 가장 짧은 프로세스에게 CPU를 할당했다 하더라도 더 짧은 프로세스가 도착할 경우 CPU를 빼앗아 부여한다. ==> SRTF(Shortest Remaining Time First)

    일반적 시분할 환경에서는 평균 대기 시간을 가장 많이 줄일 수 있는 방식.

단점 : CPU 버스트 시간을 미리 알수 없다.

그렇기 때문에 예측치가 가장 짧은 프로세스에게 할당한다.

기아 현상(Starvation)

계속 CPU버스트가 짧은 프로세스에게만 할당할 경우 CPU 버스트가 긴 프로세스는 준비 큐에서

무한 대기

 

우선순위 스케줄링

준비큐에서 기다리는 프로세스들 중에 우선순위가 가장 높은 프로세스에게 CPU할당

숫자가 낮을수록 우선순위가 높다.

  • 비선점형

    비록 우선순위가 더 높은 프로세스가 도착하더라도 CPU를 자진 반납하기 전까지 선점 불가.

  • 선점형

    현재 CPU에서 수행중인 프로세스보다 우선순위가 높은 프로세스가 도착할 경우 CPU를 새롭게 도착한 프로세스에 할당.

단점: 기아 현상(Starvation) 우선순위가 낮은 프로세스는 무한대기.

=> 에이징 기법

에이징 기법이란 기다리는 시간이 길어지면 우선순위를 조금씩 높여 언젠가 가장 높은 우선순이가 되어 CPU를 할당받을 수 있게 해주는 방법.

 

HRN 스케줄링

HRN(Highest Response-ratio next)는 SJF의 단점을 보안하기 위해 등장.

우선순위 계산식을 이용하여 자원 할당. 숫자가 높을수록 우선순위가 높다. ==> 비선점형

우선순위 = (대기시간+실행시간)/실행시간

 

라운드 로빈 스케줄링

시분할 시스템의 성질을 가장 잘 활용한 새로운 의미의 스케줄링 방식.

CPU 사용 시간이 특정 시간으로 제한되며, 이 시간이 경과되면 CPU를 회수해 다음 프로세스에게 할당하고, 이 프로세스는 준비 큐의 맨 뒤로 가서 차례를 기다린다. ==> 선점형

라운드 로빈 스케줄링은 SJF방식보다 평균대기시간은 길지만 응답시간은 더 짧다.

할당시간 : 각 프로세스가 CPU를 연속적으로 사용할 수 있는 최대 시간.

할당시간이 너무 길면 FCFS와 같은 결과를 초래할 수 있으며, 너무 작으면 빈번하게 교체로 인한 context switching 오버헤드가 커지게 된다.

CPU를 회수하는 방법으로는 타이머 인터럽트 사용. 만약, CPU 버스트 시간이 할당시간보다 짧으면 자신의 버스트 시간만큼 스스로 사용후 반납.

 

 

 

 


회랑 청하 조합 햄복해..

'Diary' 카테고리의 다른 글

역삼 상도  (5) 2019.05.30
선릉 착한고기  (4) 2019.01.31
역삼 민들레떡볶이  (3) 2019.01.30
역삼 호타루  (2) 2019.01.25
역삼 전봇대  (2) 2019.01.23
scheduler

스케줄러

프로세스를 스케줄링하기 위한 Queue에는 세 가지 종류가 존재한다.

  • Job Queue : 현재 시스템 내에 있는 모든 프로세스의 집합
  • Ready Queue : 현재 메모리 내에 있으면서 CPU를 잡아서 실행되기를 기다리는 프로세스의 집합
  • Device Queue : Device I/O 작업을 대기하고 있는 프로세스의 집합

각각의 Queue에 프로세스들을 넣고 빼주는 스케줄러에도 크게 세 가지 종류가 존재한다.

 

장기스케줄러 Long-term scheduler / job scheduler

메모리는 한정되어 있는데 많은 프로세스들이 한꺼번에 메모리에 올라올 경우, 대용량 메모리(일반적으로 디스크)에 임시로 저장된다. 이 pool에 저장되어 있는 프로세스 중 어떤 프로세스에 메모리를 할당하여 ready queue로 보낼지 결정하는 역할을 한다.

  • 메모리와 디스크 사이의 스케줄링을 담당.

  • 프로세스에 memory(및 각종 리소스)를 할당(admit)

  • degree of Multiprogramming 제어

    메모리에 여러 프로그램이 올라가는 것 -> 몇 개의 프로그램이 올라갈 것인지를 제어

  • 프로세스의 상태 new - > ready (in memory_)

 

cf) 메모리에 프로그램이 너무 많이 올라가도, 너무 적게 올라가도 성능이 좋지 않은 것이다. 참고로 time sharing system에서는 장기 스케줄러가 없다. 곧바로 메모리에 올라가 ready 상태가 된다.

 

단기스케줄러 Short-term scheduler / CPU scheduler

  • CPU와 메모리 사이의 스케줄링을 담당.
  • Ready Queue에 존재하는 프로세스 중 어떤 프로세스를 running 시킬지 결정.
  • 프로세스에 CPU를 할당(scheduler dispatch)
  • 프로세스의 상태 ready -> running -> waiting -> ready

 

중기 스케줄러 Medium-term scheduler / Swapper

  • 여유 공간 마련을 위해 프로세스를 통째로 메모리에서 디스크로 쫓아냄 (swapping)
  • 프로세스에게서 memory를 deallocate
  • degree of Multiprogramming 제어
  • 현 시스템에서 메모리에 너무 많은 프로그램이 동시에 올라가는 것을 조절하는 스케줄러.
  • 프로세스의 상태 ready -> suspended

Process state - suspended(stopped)

외부적인 이유로 프로세스의 수행이 정지된 상태에로 메모리에서 내련 상태를 의미한다. 프로세스 전부 디스크로 swap out 된다. Blocked 상태는 다른 I/O 작업을 기다리는 상태이기 때문에 스스로 ready state로 돌아갈 수 있지만 이 상태는 외부적인 이유로 suspending 되었기 때문에 스스로 돌아갈 수 없다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package Z_Project;
 
import java.util.Arrays;
 
/**
 * Dijkstra: 하나의 선택한 정점에서 각 정점까지 갈 수 있는 최단거리를 구하는 알고리즘
 *  Greedy 방식, 음이 아닌 가중치 일 경우만 사용가능
 *                음의 가중치가 있는 경우는 => 벨만포드 알고리즘을 통해서 구해야한다
 *    시간복잡도 O(n^2)
 */
public class Z38_Dijkstra {
    public static void main(String[] args) {
        final int M = Integer.MAX_VALUE;
        int[][] G = {
                {0,3,5,M,M,M},
                {M,0,2,6,M,M},
                {M,1,0,4,6,M},
                {M,M,M,0,2,3},
                {3,M,M,M,0,6},
                {M,M,M,M,M,0}
        };
        
        int s = 0//시작정점
        int[] D = G[s].clone(); // 가중치 배열, 시작정점의 진출차수로 가중치배열을 초기화
        boolean[] used = new boolean[G.length]; //사용한 정점들을 저장할 배열
        
        for (int n = 0; n < used.length; n++) { //정점 하나씩 선택하기
            //사용하지 않은 정점중에서, 가중치가 최소인 정점을 찾아서 used배열에 정점 추가
            int minIndex = -1//최소 가중치가 저장된 D배열의 인덱스
            int minVal = M; //최소가중치
            for(int i=0;i<D.length;i++) {
                if(!used[i] && minVal>D[i]) {
                    minIndex=i;
                    minVal=D[i];
                }
            } //가중치 최소인 장점을 찾음. 
            used[minIndex] = true;
            
            //선택한 정점을 통해서 갈수 있는(인접한) 정점의 가중치를 갱신
            for(int i=0;i<D.length;i++) {
                //사용하지 않은 정점, 인접한 정점, 가중치가 지금보다 더 작으면 =>갱신
                if(!used[i] && G[minIndex][i] != M && D[i]>D[minIndex]+G[minIndex][i] ) {
                    D[i] = D[minIndex]+G[minIndex][i];
                }
            }
        }
        
        System.out.println(Arrays.toString(D));
    } //end of main
}//end of class
 
 
cs


1. 재귀함수.


stirng 넘겨줄때 함수 호출 파라미터로 바로 넘어줘야한다.

s+="a"

dfs(s);


이런식으로 넘겨주면 함수가 종료된후 돌아왔을때 s는 여전히 "a"된 값이 저장되있다



2. substring

substring(0,len)

이면.. 0~4까지 cut

'Computer Science > Languages' 카테고리의 다른 글

[javascript] Hoisting 호이스팅이란  (1) 2019.07.11
[java 예외처리]Try-with-resources  (2) 2019.07.11
[java] 쓰레드(Thread)  (0) 2019.01.24
[java] 예외처리  (2) 2019.01.24
[java] Collection 활용  (0) 2019.01.17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package Z_Project;
 
import java.util.Arrays;
import java.util.Scanner;
 
/**
 * MST 알고리즘 중 KRUSKAL이 더 직관적이고 간단(많이 사용됨) DisjointSets
 */
 
/*
 * 
input
6 11
5 3 18
1 2 21
2 6 25
0 2 31
0 1 32
3 4 34
5 4 40
2 4 46
0 6 51
4 6 51
0 5 60
output
5-3 18
1-2 21
2-6 25
0-2 31
3-4 34
2-4 46
 * 
 * */
public class Z37_KRUSKAL {
    public static int[] p; //부모를 저장할 배열
    public static int[] rank;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int V = sc.nextInt();
        int E = sc.nextInt();
        p = new int[V+1];
        rank = new int[V+1];
        
        Edge[] ed = new Edge[E];
        
        for(int i=0;i<E;i++) {
            ed[i] = new Edge(sc.nextInt(),sc.nextInt(),sc.nextInt());
        }
        Arrays.sort(ed); //정렬하기 위해서 compareTo()를 작성해야한다.
        
        for(int i=0;i<p.length;i++) {
            makeSet(i);
        }
        
        for(int i=0;i<ed.length;i++) { //가중치가 낮은 간선부터 선택하기
            Edge e = ed[i];
            if(findSet(e.a) != findSet(e.b)) { //서로 다른 집합일 경우만 합치기
                union(e.a,e.b);
                System.out.println(e.a+"-"+e.b+" "+e.val);
            }
        }
    }//end of main
    
    public static void printSet() {
        System.out.print("index : ");
        for(int i=0;i<p.length;i++) {
            System.out.printf("%2d ", i);
        }
        System.out.print("\nparent: ");
        for(int i=0;i<p.length;i++) {
            System.out.printf("%2d ", p[i]);
        }        
        
        System.out.println("\n");
    }
    
    
    /*멤버 x를 포함하는 새로운 집합을 생성*/
    public static void makeSet(int x) {
        p[x]=x; //부모 : 자신의 index로 표시 or -1
        //rank[x] = 0;//초기값 0임, 생략가능
    }
    
    /*멤버 x를 포함하는 집합의 대표자를 리턴*/
    public static int findSet(int x) {
        if(x==p[x]) return x;
        else {
            p[x]=findSet(p[x]); // Path Compression
            //rank[x]=1;//할 필요 없다. 대표자의 깊이(rank)만 알면된다.
            return p[x];
        }
    }
    
    public static void union(int x,int y) {
        int px = findSet(x);
        int py= findSet(y);
        
        // 서로 다른 집합일 경우만 합친다.
 
        if(px!=py) {
        //    p[py]=px; //대표자 합치기    
            link(px,py);
        }
    }
    
    /*x의 대표자의 집합과 y의 대표자의 집합을 합침, rank도 맞춤*/
    public static void link(int px, int py) {
        if(rank[px]>rank[py]) {
            p[py]=px; //작은쪽에 큰쪽을 붙인다.
        } else {
            p[px]=py;
            
            if(rank[px]==rank[py]) { //같은 경우는 rank 값이 증가
                rank[py]++;//집합의 대표자 랭크가 증가됨.
            }
        }
    }
    
    public static class Edge implements Comparable<Edge>{
        int a; //정점1
        int b; //정점2
        int val; //가중치
        public Edge(int a, int b, int val) {
            this.a = a;
            this.b = b;
            this.val = val;
        }
        @Override
        public int compareTo(Edge o) { //비교기준
            return this.val-o.val;
        }
        
        
    }
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package Z_Project;
 
import java.util.Arrays;
 
/*
 * 상호배타 집합 => MST(크루스칼 알고리즘에 활용)
 * 
 * makeSet(int x) 멤버 x를 포함하는 새로운 집합을 생성
 * findSet(int x) 멤버 x를 포함하는 집합의 대표자를 리턴
 * union(int x, int y) 멤버 x,y의 대표자를 구해서 두 집합을 통합
 * link(int px, int py) x의 대표자의 집합과 y의 대표자의 집합을 합침
 * 
 */
public class Z36_DisjointSets2 {
    public static int[] p = new int[10]; //부모를 저장할 배열
    public static int[] rank=new int[10];
    public static void main(String[] args) {
        
        for(int i = 0;i<p.length;i++) {
            makeSet(i);
        }
        
        printSet();
        union(0,1);printSet();
        union(2,3);printSet();
        union(0,3);printSet();
        
    }//end of main
    
    public static void printSet() {
        System.out.print("index : ");
        for(int i=0;i<p.length;i++) {
            System.out.printf("%2d ", i);
        }
        System.out.print("\nparent: ");
        for(int i=0;i<p.length;i++) {
            System.out.printf("%2d ", p[i]);
        }        
        
        System.out.println("\n");
    }
    
    
    /*멤버 x를 포함하는 새로운 집합을 생성*/
    public static void makeSet(int x) {
        p[x]=x; //부모 : 자신의 index로 표시 or -1
        //rank[x] = 0;//초기값 0임, 생략가능
    }
    
    /*멤버 x를 포함하는 집합의 대표자를 리턴*/
    public static int findSet(int x) {
        if(x==p[x]) return x;
        else {
            p[x]=findSet(p[x]); // Path Compression
            //rank[x]=1;//할 필요 없다. 대표자의 깊이(rank)만 알면된다.
            return p[x];
        }
    }
    
    public static void union(int x,int y) {
        int px = findSet(x);
        int py= findSet(y);
        
        // 서로 다른 집합일 경우만 합친다.
 
        if(px!=py) {
        //    p[py]=px; //대표자 합치기    
            link(px,py);
        }
    }
    
    /*x의 대표자의 집합과 y의 대표자의 집합을 합침, rank도 맞춤*/
    public static void link(int px, int py) {
        if(rank[px]>rank[py]) {
            p[py]=px; //작은쪽에 큰쪽을 붙인다.
        } else {
            p[px]=py;
            
            if(rank[px]==rank[py]) { //같은 경우는 rank 값이 증가
                rank[py]++;//집합의 대표자 랭크가 증가됨.
            }
        }
    }
}
 
cs

'Computer Science > Algorithms' 카테고리의 다른 글

[java] Dijkstra 다익스트라 알고리즘  (0) 2019.02.19
Kruskal 크루스칼 알고리즘  (0) 2019.02.18
[java] Insertion Sort 삽입정렬  (0) 2019.01.28
Permutation 순열  (0) 2019.01.17
Dijkstra 최단경로 알고리즘  (2) 2019.01.08

+ Recent posts