プログラマディスクコントローラ
6629 ワード
🔗 質問リンク
https://programmers.co.kr/learn/courses/30/lessons/4262
🤔 質問する
HDDは一度に1台しか処理できません.ディスクコントローラを実装する方法はいくつかあります.最も一般的な方法は、リクエストの受信順序に従って処理することである.
例:
一度に1つのリクエストしか実行できないため、各タスクをリクエストの順序で処理する場合:
でもA→C→B順に処理すると
各タスクについて、「要求タスクの時点、タスク所要時間」を含む2 Dタイルジョブをパラメータとして指定した場合は、要求から終了までのタスクの平均値を最小限に抑えるためのソルバを作成します.(ただし小数点以下)
📌 せいげんじょうけん
😮 トラブルシューティング方法
ディスクコントローラの問題は、オペレーティングシステムのスケジューリング方法の1つであるSJF(Shortest Job First)方法の非線形プリエンプト方法と同じです.
したがって、ディスクが作業中に他の短いタスクに遭遇した場合でも、処理を先に行い、次の短いタスクを実行します.
したがって、ディスクコントローラのトラブルシューティングのポイントは、ジョブの並べ替えの開始時間と優先キューを比較するときに、経過した時間順にキューに挿入することです.
static class Disk implements Comparable<Disk> {
private int start; //시작 시간
private int elapsed; //경과 시간
public Disk(int start, int elapsed) {
this.start = start;
this.elapsed = elapsed;
}
public int getStart() {
return start;
}
public int getElapsed() {
return elapsed;
}
// 경과 시간이 짧은 순서로 힙에 넣어줌
@Override
public int compareTo(Disk o) {
if (this.elapsed < o.elapsed) return -1;
else if (this.elapsed > o.elapsed) return 1;
return 0;
}
}
開始時間と経過時間を変数とするディスククラスを作成します.ディスククラスの実装は、競合インタフェースを短い時間の順序でキューに入れることです.{{4, 9},{5, 6},{1, 1}}
要素を有するジョブ配列を例示する.まず、この配列の開始時間である4、5、1を並べ替えます.(開始時間が短い)
{{1, 1},{4, 9},{5, 6}}
でソートを終了した後、優先順位キューに最初に開始したジョブを入れる.タスクが完了した後に注意しなければならないのは、現在のタスクが完了したときにまだ開始していないタスクが1つもない場合、最初に要求されたタスクが実行されます.
したがって、クエリー条件にキューがない場合、またはジョブに残りのジョブがある場合は、繰り返しを続行する条件を指定します.1秒開始のタスクは1秒後の2秒で終了しますが、次のタスクは4秒で開始します.まだタスクがあるので、キューが空であってもwhile文にアクセスし続けます.
//큐가 empty가 아니거나 아직 작업이 큐에 다 들어가지 않은 경우
while (!pq.isEmpty() || list.size() > 0) {
最初のタスクが開始された時点を現在の時間(時間変数)に入れ、タスクが完了するたびに経過した時間を加算すると、進行中のタスクが終了する現在の時間となります.その後、受信したタスクがキューに残っている場合は、すべてのタスクをキューに入れます.また,タスクを繰り返し実行するとスケジューリングに必要なすべての時間が得られ,タスクの数に応じて割り当てられると平均作業時間が得られ,返されると問題が解決される.
次はJavaで実装されたコードです.
🚩 JAVAコード
package com.algorithm.Programmers.Lv3;
import java.util.*;
public class Solution_42627 {
static class Disk implements Comparable<Disk> {
private int start; //시작 시간
private int elapsed; //경과 시간
public Disk(int start, int elapsed) {
this.start = start;
this.elapsed = elapsed;
}
public int getStart() {
return start;
}
public int getElapsed() {
return elapsed;
}
// 경과 시간이 짧은 순서로 힙에 넣어줌
@Override
public int compareTo(Disk o) {
if (this.elapsed < o.elapsed) return -1;
else if (this.elapsed > o.elapsed) return 1;
return 0;
}
}
public static void main(String[] args) {
int[][] jobs = {{1, 1}, {4, 9}, {5, 6}};
System.out.println(solution(jobs));
}
public static int solution(int[][] jobs) {
int answer = 0;
PriorityQueue<Disk> pq = new PriorityQueue<>();
//Jobs 배열을 시작시간이 빠른 순서로 먼저 정렬
//시작시간이 동일한 경우 경과 시간이 짧은 순으로 정렬
Arrays.sort(jobs, (o1, o2) -> {
if (o1[0] == o2[0])
return Integer.compare(o1[1], o2[1]);
else
return Integer.compare(o1[0], o2[0]);
});
LinkedList<Disk> list = new LinkedList<>();
for (int[] job : jobs)
list.add(new Disk(job[0], job[1]));
pq.offer(list.poll()); //가장 빠른 작업 제일 먼저 넣어주기
int time = pq.peek().getStart(); //가장 빠른 작업 시작시간이 모든 스케줄링 시작 시간
//time >= start 인 값 큐에 넣기
//time += elapsed;
//answer += time - disk.start;
//큐가 empty가 아니거나 아직 작업이 큐에 다 들어가지 않은 경우
while (!pq.isEmpty() || list.size() > 0) {
/*큐가 비었지만 list size가 남은 경우는 (1,1) (4,1)의 경우
*1초에 시작 2초에 완료, 이후 2초부터 다음 작업 시작시간인 4초까지 작업이 없기 때문에
*먼저 요청하는 작업 큐에 넣어주기
*/
if(list.size() > 0 && pq.isEmpty()){
time = list.peek().getStart();
pq.offer(list.poll());
continue;
}
Disk disk = pq.poll();
time += disk.getElapsed(); //경과 시간을 더해주면 작업이 끝난 현재 시간
while (list.size() > 0 && time >= list.peek().getStart()) {
pq.offer(list.poll()); //현재 시간보다 전에 요청 받은 작업 큐에 넣어주기
}
answer += time - disk.getStart(); //현재 시간부터 요청 시작 시간을 빼주면 요청부터 작업 완료까지의 시간
}
return answer / jobs.length;
}
}
📄 整理する
これは、
Reference
この問題について(プログラマディスクコントローラ), 我々は、より多くの情報をここで見つけました https://velog.io/@zayson/프로그래머스-Java-디스크-컨트롤러テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol