私は教えていますCS2(Java and data structures
)、そしてキューを教えるときに使用する良い例を思い付くのが困難です。私がそれらを使用する2つの主要なアプリケーションはmultithreaded
メッセージパッシングです(ただし、MTプログラミングはコースの範囲外です)、およびBFS-style algorithms
(そして、私は学期の後半までグラフをカバーしません)。
不自然な例も避けたいです。私が考えているほとんどのことは、実際にシングルスレッド方式で解決する場合は、キューではなくリストを使用するだけです。処理と検出がインターリーブされている場合(検索など)、または長さ制限のあるバッファー(たとえば、最後を維持する場合[〜#〜] n [〜#〜 ]個のアイテム)。実用的な範囲で、私は生徒に実際のプログラムで実際に物事を行うための優れた方法を教えるようにしています。機能を披露するおもちゃだけではありません。
例として使用できるが、他の最小限の事前知識が必要な、キューの優れたシンプルなアルゴリズムまたはアプリケーションの提案はありますか?
待ち行列を学んでいるとき、教授はいつも店の例を使いました。常に1つ以上のレジスターが開いており、顧客はキューを1つまたは別のキューに入れ、そのキューを移動してすべてのアイテムを購入します。
実際には、RegisterQueueを介して顧客を移動できる単純なプログラムを実装する必要があったので、実際にプログラムを探している場合は、この例を単純で簡単なものにするだけでなく、すべての学生が実際に目にしたものなどを生徒に与えることができます。それは彼らが概念をよりよく理解するのを助けるかもしれません。
キューを知ったとき、先生は警察のコントロールで車のラインナップを使ってキューを紹介してくれました。車を保持するキュー(「待機キュー」)があり、警官は常にキュー内の次の車を制御し、さらに検査するために同僚に送るか、車を通過させました。
非常によく使用される例は、スーパーマーケットのキューです...
生徒に例を挙げてもらいませんか?
私の頭に浮かぶ一例は、例えばハンバーガー加工ラインです。マクドナルド。それらはいくつかの種類の異なるハンバーガーであり、それぞれがいくつかの異なる労働者によって生産され、それぞれが独自のキューを持っています。そこから、しばらくして、準備が整ったハンバーガーがFIFOの順序で、その種類のハンバーガーを注文したレジ係の1人によって取得されます。
したがって、複数のプロデューサーとコンシューマーがあり、各キューは制限されています。
Amazonを例として使用することを考えました。その大規模なシステムのどこかに、処理する必要がある注文のキューがあるはずです。これは、単純なエンキューとデキューで処理できます。システムは、顧客が本を購入するたびにシステム内の注文をキューに入れ、保管庫の担当者は、それを取り出してポストするためにキューから取り出します。
プライオリティキューについて話し始めるのは簡単です。キューにジャンプする可能性のある主要な顧客を紹介することで、プライオリティキューを紹介できます。
どんな教科書を使っていますか?
キューの完璧な例は、口座に対する取引を処理する銀行です。通常、1日の終わりに「保留中」のトランザクションのリストが表示されます。アカウンティングが完了すると、それらのトランザクションがアカウントに適用されます。これにより、優先キューの領域に入ることができます。ほとんどの銀行は、夜間のトランザクションを処理する際に借方を優先するようです。そのため、保留中のクレジットを適用する前に、ドラフト料金を超えてあなたを指名できます。
トランザクションは、実行時間順にキューに挿入され、アカウンティングプロセスによってデキューされ、アカウントに適用されます。
私は以前は通信プログラマーでしたので、これが頭に浮かびます:
カスタマーサービスホットライン。通話が着信し、通話を処理するのに十分なオペレーターがいないため、通話がキューに入れられます。次のコールが着信し、それもキューに入れられます。次に、次のオペレーターが応対可能になると、キューに入った最初の呼び出しが、使用可能なオペレーターに割り当てられます。
明らかな現実世界の例は、チェックアウト行などですが、厳密に計算に根ざした例を探しているので、ジョブスケジューリングキューをお勧めしますか?
生徒の何人がオペレーティングシステムのクラスを受講したかはわかりませんが、すべての生徒がタスクマネージャを使用して、ある時点または他の時点でプロセスをチェックしているのは確かです。スケジューリングキューの簡単な例を紹介し、それらに宿題を割り当てて、所定のサイズの「タスク」を生成(または受け入れ)し、それらをFIFOの順序で処理する彼らがそれを「始めた」とき。
これは理解するのがかなり簡単な概念であり、キューがコンテンツを受け入れる順に処理するという考え方を示し、CPUスケジューリングの概要を(非常に初歩的で単純化された)紹介します。ちょうど私の2つのビット。
あなたは彼らのアプリケーションをマルチスレッドで立ち上げるかもしれませんが、学生がすでにスレッド化されたプログラムを書いた経験がない限り、私は彼らに仕事を割り当てたくありません。大学2年でデータ構造の学習に問題があったことを覚えています(特にJavaで、C++を実行しておらず、ポインターについても学習していなかったため)。
データ構造を教える際、私は通常、顧客がキューで待機し、いくつかのサービスウィンドウがあるバンクキューシミュレーションのアプリケーションを使用します。
問題は、次の統計を見つけるためにプロセスをシミュレーションすることです:キューで待機している顧客(最大、最小、平均)、およびキューで待機している顧客の数。私は、事前定義された頻度で毎日1分ごとに新しい顧客に到着し、乱数発生器からの値を使用してサービスウィンドウで顧客の平均サービス時間を使用します。
その結果、顧客満足を保証するのに最適な数のサービスウィンドウと待機ホールの最適な数の椅子が推奨されます。学生にとって非常に興味深いアプリケーション。
スケジューリングアルゴリズムには、ほとんどの場合、キューが含まれます。
これは、単純な先着順のキューから、単一のコンシューマへのバッファリクエストまでさまざまです。
「タスク」が優先順位を持つことができ、「ワーカー」が異なる機能を持つことができる複雑なジョブスケジューリングキューに。
「中央のプリントサーバーに4つのプリンターがあり、2つはカラー、もう1つは両面に印刷、もう1つはより大きな用紙に印刷できます。ユーザーはRushジョブに追加料金を支払うことができます。または、彼らが長く待つことを気にしない場合は少なくなります。配信を遅くして、できるだけ多くのスループットが必要になると、ペナルティが発生する可能性があります。」
現実の世界:
非現実世界:
while(queue.peek)
を使用できます。私は例としてゲームを使用するのが好きです。なぜなら、それは一般的にファイルIOまたはあなたが思いつく他の何かよりも少しエキサイティングだからです。
したがって、戦略ゲームのユニットに複数のコマンドを続けて発行する場合(たとえば、基地の4つのコーナーを順番に偵察するようにZerglingを行ってから、基地の中心に自殺する場合は、キューを選択することをお勧めします。 。)
または、1秒あたり30フレームしか処理できないアプリケーションがあるのに、フレーム間で4つまたは5つの入力を取得する場合があります。武器変更入力とシュート入力がある場合、それらが受信された順序で処理されることを確認する必要があります。そうでない場合、ナイフを使用したいときに手榴弾を使用する可能性があります。そして、ナイフを使いたいときに手榴弾を弾くと、悪い時間を過ごすことになります。 (それをスキーのインストラクターのミームに入れて、スライドに入れてください):)
リクエストを処理するサーバーも良い例です。
入力を受け取るCNCマシン。マシンは非常に高速でしか実行できないため、入力をキューに入れる必要があります。
私が考えることができるいくつかの例:
製造ラインはキューでいっぱいです。充填機に向かう空のボトルのラインを考えてください。先入れ先出しは、多くのオブジェクトにプロセスを順番に適用する自然な方法です。キューは、あるプロセスを別のプロセスから分離するためにも使用されます。ラベリングマシンに短期的な問題がある場合、充填機はすぐに停止する必要はありません。
キューは、ソフトウェアでもほぼ同じ方法で使用されます。あるプロセスの出力は、別のプロセスへの入力のためにキューに入れることができます。これは、プロセス間通信、スレッド間通信、または単純に複雑なプロセスをすべて同じスレッドで処理される可能性のある部分に分割する場合に当てはまります。
オペレーティングシステムでは、キューは入力を順番に処理するためによく使用されます。たとえば、ファイルシステムはストレージデバイスからブロックを読み取り、それらをキューに追加する場合があります。または、キーの押下やマウスの動きなどを処理する割り込みにより、イベントキューに追加されるイベントが作成されるため、入力時に「キュー」ではなく「uqeeu」が取得されません。
単純な学生の課題の場合、いくつかの入力を受け入れ、それらを処理するタスクはすべて機能すると思います。たとえば、単純な後置式エバリュエーターを作成させることができます。 3つの部分があります。
入力を読み取り、それを入力キューに追加し、入力がなくなるまで繰り返します。
キューからアイテムを取得する
出力キューからアイテムを読み取り、それを印刷して、出力キューが空になるまで繰り返します。