プログラミング
 Computer >> コンピューター >  >> プログラミング >> プログラミング

列車の到着・出発時刻から必要な最小プラットフォーム数を求めるアルゴリズム

問題の概要

列車の到着時刻と出発時刻のリストが与えられます。求めるのは、どの列車も駅で待機せずに済むようにするために必要な、プラットフォーム(ホーム)の最小数です。

すべての時刻をあらかじめソートしておけば、この問題は簡単に解けます。「駅に到着したものの、まだ出発していない列車」の数を時系列に沿って追跡することで、同時に駅に存在する列車の最大数、すなわち必要なプラットフォームの最小数が分かります。

このアルゴリズムの計算量は O(n log n) であり、その大部分はソート処理にかかるコストです。

入力と出力

入力:
到着時刻と出発時刻のリスト
Arrival: {900, 940, 950, 1100, 1500, 1800}
Departure: {910, 1200, 1120, 1130, 1900, 2000}

出力:
必要な最小プラットフォーム数: 3

アルゴリズム

入力: 到着時刻のリスト、出発時刻のリスト、およびリストの要素数 n

出力: 問題を解くために必要なプラットフォームの最小数

基本的な考え方は次のとおりです。

  • 到着時刻と出発時刻をそれぞれ独立に昇順ソートします。
  • 2つのポインタ i(到着側)と j(出発側)を使い、時系列順にイベントを処理します。
  • arrival[i] < departure[j] の場合は、既存の列車が出発する前に新しい列車が到着するため、使用中のプラットフォーム数を1増やします。
  • それ以外の場合は列車が出発するため、使用中のプラットフォーム数を1減らします。
  • 処理中の platform の最大値が答えとなります。
手続き minPlatform(arrival, departure, n)

開始
    到着時刻リストと出発時刻リストをそれぞれソートする
    platform := 1、minPlatform := 1 とする
    i := 1、j := 0 とする

    到着リストのインデックス i と出発リストのインデックス j について繰り返す
        もし arrival[i] < departure[j] ならば
            platform := platform + 1
            i := i + 1
            もし platform > minPlatform ならば
                minPlatform := platform
        そうでなければ
            platform := platform − 1
            j := j + 1
    繰り返し終了
    minPlatform を返す
終了

C++による実装例

以下は、上記のアルゴリズムをC++で実装した例です。

#include<iostream>
#include<algorithm>
using namespace std;

int minPlatform(int arrival[], int departure[], int n) {
    sort(arrival, arrival+n);       // 到着時刻と出発時刻をソート
    sort(departure, departure+n);

    int platform = 1, minPlatform = 1;
    int i = 1, j = 0;

    while (i < n && j < n) {
        if (arrival[i] < departure[j]) {
            platform++;             // 使用中のプラットフォームを1つ増やす
            i++;
            if (platform > minPlatform)   // 最大値を更新
                minPlatform = platform;
        } else {
            platform--;             // 列車が出発し、プラットフォームを1つ解放
            j++;
        }
    }
    return minPlatform;
}

int main() {
    int arrival[] = {900, 940, 950, 1100, 1500, 1800};
    int departure[] = {910, 1200, 1120, 1130, 1900, 2000};
    int n = 6;
    cout << "Minimum Number of Platforms Required: " << minPlatform(arrival, departure, n);
}

出力結果

Minimum Number of Platforms Required: 3

実行例の解説

この例では、時刻をソートすると到着時刻は {900, 940, 950, 1100, 1500, 1800}、出発時刻は {910, 1120, 1130, 1200, 1900, 2000} となります。

午前11時台に注目すると、9:40に到着した列車(12:00出発)、9:50に到着した列車(11:20出発)、11:00に到着した列車(11:30出発)の3本が同時に駅に停まっている瞬間があります。このため、最低でも3つのプラットフォームが必要であることが分かります。

補足:同一時刻の扱い

このアルゴリズムでは比較に「厳密な不等号(<)」を使用しているため、到着時刻と出発時刻が同じ場合には、先に出発する列車がプラットフォームを解放してから次の列車が到着するものとして扱われます。実際の運用条件に応じて、この比較条件は適宜調整することが可能です。

  1. C++で解く!鉄道駅に必要なプラットフォームの最小数を求めるアルゴリズム

    問題の概要ある鉄道駅に到着するすべての列車の到着時刻と出発時刻が与えられたとき、どの列車も待ち時間なく停車できるようにするために必要なプラットフォーム(ホーム)の最小数を求めるのがこの問題です。入力としては、列車の到着時刻を格納した配列と、出発時刻を格納した配列の2つが与えられます。例えば以下の入力の場合、最低でも3つのプラットフォームが必要になります。列車到着時刻出発時刻列車109:0009:15列車209:3511:45列車309:4011:05列車411:0012:00列車514:3018:15列車618:0019:00アルゴリズムこの問題は、時刻を並べ替えて同時進行する列車数を数えると

  2. C++で最小ページ数を割り当てる方法|二分探索による効率的な解法

    「最小ページ数の割り当て(Allocate Minimum Number of Pages)」は、競技プログラミングや技術面接で頻出する古典的なアルゴリズム問題の一つです。この記事では、問題の内容を詳しく解説し、二分探索を用いた効率的な解法をC++のサンプルコードとともに紹介します。 問題文 n冊の異なる本のページ数が与えられます。また、これらの本を割り当てる対象としてm人の学生がいます。本はページ数の昇順に並べられており、各学生には連続した本のみを割り当てることができます。プログラムは、一人の学生が読むことになる最大ページ数を返しますが、その最大値ができるだけ小さくなるような割り当てを行う