[programmers]ディスクコントローラ(Python)


質問する📚


HDDは一度に1台しか処理できません.ディスクコントローラを実装する方法はいくつかあります.最も一般的な方法は、リクエストの受信順序に従って処理することである.
例:
  • 0ミリ秒時3ミリ秒のA要求
  • Bジョブ要求
  • ミリ秒(
  • ミリ秒)
  • msの時点で6ミリ秒のCタスクを要求
    受け取った要求は同じです.下図のように.
  • 一度に1つのリクエストしか実行できないため、各タスクをリクエストの順序で処理する場合:
  • A:3ミリ秒(リクエストから終了まで:3ミリ秒)
  • B:1 ms待機開始、3 ms動作開始、12 ms完了(リクエストから終了:11 ms)
  • C:2ミリ秒~2ミリ秒、12ミリ秒~18ミリ秒(リクエストから終了まで:16ミリ秒)
    各タスクの要求から終了までの平均時間は10ミリ秒(=(3+11+16)/3)である.
  • でもA→C→B順に処理すると
  • A:3ミリ秒(リクエストから終了まで:3ミリ秒)
  • C:2ミリ秒~2ミリ秒、3ミリ秒~9ミリ秒、7ミリ秒~
  • B:1 msで始まり、9 msで始まり、18 msで終了(リクエストから終了まで:17ミリ秒)
    A→C→Bの順に処理すると,各タスクの要求から終了までの平均時間は9 ms(=(3+7+17)/3)となる.
  • 各タスクについて、「要求タスクの時点、タスク所要時間」を含む2 Dタイルジョブをパラメータとして指定した場合は、要求から終了までのタスクの平均値を最小限に抑えるためのソルバを作成します.(ただし小数点以下)

    せいげんじょうけん


    jobsの長さは1または500以下です.
    ジョブの各行は、タスクの[タスクを要求する時間、タスクに要する時間]です.
    各タスクについて、タスクを要求する時間は1000を超えません.
    各タスクに要する時間は1000時間を超えない.
    ハードディスク(HDD)が動作していない場合は、リクエストのタスクを先に処理します.

    I/O例


    jobsreturn[[0, 3], [1, 9], [2, 6]]9
    質問リンク

    のり

  • 0 0から入る作業をチェックします.
  • 現在、
  • が時間基準で進んでいる作業をheapq를 이용한 우선순위 큐に組み入れる.
  • 優先度はジョブサイズで比較される(ジョブ[1]、ジョブ[0]).
  • heapqの最小値をポップアップして処理するか、キューにジョブがない場合は、現在の時間に1を追加します.
  • コード(Python)

    import heapq
    from collections import deque
    
    def solution(jobs):
        answer, count, currenttime = 0, 0, 0
        lasttime = -1
        jobheap = []
    
        while count < len(jobs):
            for job in jobs: #이전 job을 처리하는 동안 발생한 Job을 Heap에 삽입
                if lasttime < job[0] <= currenttime:
                    heapq.heappush(jobheap, (job[1], job[0]))
            if jobheap:
                work, start = heapq.heappop(jobheap)
                lasttime = currenttime
                currenttime += work
                count += 1
                answer += (currenttime - start)
            else: #heap에 job이 없는 경우
                currenttime += 1
    
        return answer // len(jobs)

    別の答え

  • 他の人の解答を参考にして、deque를 함께 사용仕事がなければ、もう1時間追加するわけではありません.현재 기준 가장 빠르게 들어올 job을 처리を実現し、時間を短縮しました.
  • def solution2(jobs):
        #deque를 사용해서 pop 시간복잡도를 낮춤
        tasks = deque(sorted([(x[1], x[0]) for x in jobs], key=lambda x: (x[1], x[0])))
        q = []
        heapq.heappush(q, tasks.popleft())
        current_time, total_response_time = 0, 0
    
        while len(q) > 0:
            dur, arr = heapq.heappop(q)
            current_time = max(current_time + dur, arr + dur)
            total_response_time += current_time - arr
            while len(tasks) > 0 and tasks[0][1] <= current_time:
                heapq.heappush(q, tasks.popleft())
            if len(tasks) > 0 and len(q) == 0: #heap에 job이 없는 경우 가장 빨리 들어올 job을 선정
                heapq.heappush(q, tasks.popleft())
    
        return total_response_time // len(jobs)
  • ジョブ間の間隔を500として、次のようなテストを行うと、時間差が多く見られます.
  • if __name__ == "__main__":
        start = time.time()  # 시작 시간 저장
        job1 = [[500, 3], [1, 9], [2, 6]]
        print("my ans : ", solution(job1), " | ans : 8", " time : ", time.time() - start)
    
        start = time.time()  # 시작 시간 저장
        job1 = [[500, 3], [1, 9], [2, 6]]
        print("my ans : ", solution2(job1), " | ans : 8", " time : ", time.time() - start)
    my ans :  8  | ans : 8  time :  0.000179290771484375
    my ans :  8  | ans : 8  time :  2.002716064453125e-05
    githubコード