알고리즘 - Greedy (dead-line Scheduling Problem)

2022. 4. 29. 23:36· Skils/Algorithm
목차
  1. Scheduling problem은 운영체제에서 다루는 개념이다.
  2. 👀정리

Scheduling problem은 운영체제에서 다루는 개념이다.

  • 최대한 적은 시간을 사용하면서 많은 작업을 해야 효율적이다

어떻게 하면 효율적으로 배치할 수 있을까?

●FCFS(First-come , First served)

  • 들어온 순서대로 일을 시작한다.
  • 도착 순서는 P1->P2->P3이라고 가정하자.

  • FCFS의 방식은 p1이 먼저 도착했으니까 p1의 일을 다 끝내기 전까지 p2, p3는 일을 시작하지 못한다.
  • P1, P2, P3의 모든 작업이 끝나는데 소요되는 시간은 30이지만, P1, P2, P3가 기다리는 시간은 24+27 = 51이다.
  • p2, p3는 p1에 비해 굉장히 적은 시간을 사용하는 작업임에도 불구하고 p1이 끝날 때까지 기다려야 한다.
  • 이러한 알고리즘은 굉장히 효율적이지 못하다.

●SJF(Shortest-Job-First)

  • 사용하는 시간이 적은 작업부터 시작한다.
  • 도착 순서는 P1->P2->P3로 가정하자. (단 같은 시간을 사용할 경우에는 먼저 도착한 사람부터 작업을 시작)

  • SJF방식은 도착 순서와 무관하게 적은 시간을 사용하는 작업부터 일을 시작한다. 
  • P1이 P2, P3보다 먼저 도착했지만, 많은 시간을 필요로 하는 작업이기에 후순위로 밀리고 시간이 적은 순서대로 P2->P3->P1으로 작업순서가 정해진다.
  • 이렇게 된다면 소요되는 시간은 FCFS와 동일하다. 하지만 기다리는 시간 측면에서 엄청난 차이를 보인다.
  • P2= 0, P3=3, P1=6으로 FCFS에서의 51 --> SJF에서의 6으로 엄청나게 줄어든 것을 알 수 있다.
  • 굉장히 효율적인 알고리즘이라고 볼 수 있다.

●Scheduling with deadline

  • 만약 각각의 job이 deadline을 가지고 있다고 가정하자.
  •  job은 deadline안에 처리해야 한다.
  • 각 job의 deadline과 profit을 고려해서 효율적으로 스케줄링해보자.

 

무식하게 모든 경우의 수를 고려하면 결과는 도출할 수 있을 것이다.

그렇게 한다면 factorial time의 시간 복잡도를 가진다.

-->굉장히 비효율적인 알고리즘이다.

 

효율적인 접근법은 Greedy 하게 푸는 것이다.

  1. Profit이 큰 순서대로Sort 한다.
  2. 이 작업을 추가하는 게 possible 한 지 impossible 한 지 검사해준다. ->(deadline을 고려)

※sequence와 set의 의미를 명확하게 구분할 줄 알아야 한다.

  • 위 그림에서 [2,3]은 possible Scheduling이다. 하지만 [3,2]인 경우에는 impossible Scheduling이다.
  • 이러한 경우에 [2,3]은 feasible sequence라고 하고 [3,2]은 feasible set이라고 한다

feasible 한 지 어떻게 검사해야 할까?

  • job을 선택하고 job을 feasible set에 넣는다.
  • feasible set에 있는 job을 deadline이 작은 것부터 정렬한다.
  • 만약 job에 순서가 deadline보다 크다면 그것은 not feasible 하다고 할 수 있다.

궁극적으로 우리는 feasible sequence 중에서 total profit이 maximum 한 것을 찾는 것이다.

 

/*
deadline 스케쥴링 문제
시간을 최대한 적게쓰면서 이익을 최대로 해야한다.
어떤식으로 배치해야 적은 시간을 쓰면서 최대한의 효율을 낼 수있을까?
각각의 job에는 deadline이 존재한다. deadline안에 해야 그 job은 유효하다.
deadline을 넘어선 시간대에 job을 선택하면 그것은 impossible하다.
*/
#include <iostream>
#include <vector>
using namespace std;
vector<int> j, k;
typedef struct Schedule
{
int deadline;
int profit;
};
void schedule(int n, Schedule* s, vector<int>& j, vector<int>& k);
bool is_feasible(vector<int>& k, Schedule* s);
int main()
{
int n;
cin >> n;
Schedule* s = new Schedule[n + 1];
vector<int> deadline;
vector<int> profit;
for (int i = 1; i <= n; i++)
{
cin >> s[i].deadline;
}
for (int i = 1; i <= n; i++)
{
cin >> s[i].profit;
}
for (int i = 1; i <= n; i++) //profit이 큰 순서대로 정렬한다.
{
for (int j = i + 1; j <= n; j++)
{
if (s[i].profit < s[j].profit)
{
swap(s[i], s[j]);
}
}
}
schedule(n, s, j, k); //n은 회의 갯수,s는 구조체,j
int sum = 0;
//j가 feasible set이다.
for (int i = 1; i < j.size(); i++)
{
sum = sum + s[j[i]].profit; //j배열에 순서대로 넣어줌.
}
cout << sum << "\n";
for (int i = 1; i < j.size(); i++) //j배열에 순서가 job의 순서임.
{
if (i < j.size() - 1)
cout << s[j[i]].profit << " ";
else
cout << s[j[i]].profit;
}
}
void schedule(int n, Schedule* s, vector<int>& j, vector<int>& k)
{
j.clear();
j.push_back(0);
j.push_back(1);
for (int i = 2; i <= n; i++)
{
k.resize(j.size()); //만약 적절하지않다면 k를 원래대로 돌려놓음.
copy(j.begin(), j.end(), k.begin());
int cnt = 1;
//i가 내가 넣어줄려는 job cnt만큼 증가시켜주고 그 자리에 넣어줌.
//그 자리가 들어가야할 위치임 k에 들어가는 job은 데드라인이 작은순서대로 정렬되어있음. deadline이 같더라더 그 이익이 더 작기때문에 후순위에 배치됨.
//s[i]의 deadline보다 k배열에 deadline이 커질때 그 자리에 넣어줌. 같으면 넣어주면 안됨. 후순위로 배치해야함.
while (cnt < k.size() && s[k[cnt]].deadline <= s[i].deadline)
cnt++;
k.insert(k.begin() + cnt, i); //해당위치에 job을 넣어줌.
if (is_feasible(k, s)) //지금 넣어준 job의 집합이 적절한지 체크함.
{
j.resize(k.size()); //적절하면 j에 k를 복사.
copy(k.begin(), k.end(), j.begin());
}
}
}
bool is_feasible(vector<int>& k, Schedule* s)
{
for (int i = 1; i < k.size(); i++)
{
if (i > s[k[i]].deadline) //job이 위치한 i와 job에 deadline을 비교해서 만약 i가 크다면 그 작업은 유효하지않다.
return false;
}
return true;
}

시간 복잡도는 n^2를 가진다.


👀정리

  • job의 이익을 내림차순 정렬한다.
  • 일단 무조건 이익이 큰 job을 넣는다.
  • 그다음에 내가 이미 넣은 deadline보다 작거나 같은 애들 중에서 자리를 찾아서 넣어줌.
    • deadline별로 k에 정렬되는데 내가 넣어주려는 작업의 deadline [s [i]. deadline]이 s [k [cnt]]의 deadline보다 커질 때 그 자리에 넣어줘야 함. 
      • 왜냐하면 이미 이익이 크고 작은 순서대로 정렬되어있기 때문에 늦게 들어온 job은 deadline이 같더라도 앞에 job보다 우선순위가 낮음.
  • 그리고 그 작업이 적절한지체크함
    • 그 적절한지의 체크는 k배열은 job에 배정순위이다.
    • 작업의 배정순위와 작업에 deadine 중에서 작업의 배정순위가 deadline보다 당연히 작아야 한다.
    • 만약 크다면 deadline안에 못했다는 뜻이므로 적절하지 않다.
  • 모든 작업이 끝나면 feasible 배열의 순서가 job의 순서이다.

'Skils > Algorithm' 카테고리의 다른 글

[C++]-백트래킹(Backtracking)이란? + n-Queens문제  (0) 2022.05.06
알고리즘[C++] - 허프만 코드(Huffman Code )  (0) 2022.05.01
분할가능 배낭 문제(Fractional Knapsack Problem)-C++  (0) 2022.04.30
알고리즘- 시간복잡도 분석(Time complexity Analysis)  (0) 2022.04.19
알고리즘(C++) - 피보나치 수열  (0) 2022.04.19
  1. Scheduling problem은 운영체제에서 다루는 개념이다.
  2. 👀정리
'Skils/Algorithm' 카테고리의 다른 글
  • 알고리즘[C++] - 허프만 코드(Huffman Code )
  • 분할가능 배낭 문제(Fractional Knapsack Problem)-C++
  • 알고리즘- 시간복잡도 분석(Time complexity Analysis)
  • 알고리즘(C++) - 피보나치 수열
재한
재한
안녕하세요 💻
재한
짜이한
전체
오늘
어제
  • 분류 전체보기 (504)
    • Skils (118)
      • Android (52)
      • C++ (5)
      • Kotlin (36)
      • Algorithm (24)
      • Server (1)
    • CodingTest (228)
      • Programmers (45)
      • Baekjoon (183)
    • Experience (8)
      • 후기(코딩테스트,프로그램,프로젝트) (8)
    • Computer Science (70)
      • Design Pattern (2)
      • OOP (2)
      • Computer Architecture (14)
      • OS (2)
      • Software Engineering (3)
      • DataBase (8)
      • Network (39)
    • 학교 (75)
      • R프로그래밍 (26)
      • 회계와 사회생활 (17)
      • 컴퓨터학개론 (20)
      • it기술경영개론 (12)

블로그 메뉴

  • 홈
  • 태그
  • 카테고리
  • 글쓰기
  • 설정

인기 글

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
재한
알고리즘 - Greedy (dead-line Scheduling Problem)
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.