通常、(シーケンシャル) 離散イベント シミュレーターでは1 つのイベント キューを使用する必要があります。「期限切れ」イベントの意味がよくわかりませんが、これらのイベントが無効になったために無視される場合、単純な解決策は、処理する代わりに破棄することです。たとえば、次の疑似 Java コードを参照してください。
while (!terminationConditionMet() && !eventQueue.isEmpty()) {
Event currentEvent = eventQueue.getNextEvent();
if(currentEvent.isExpired())
continue;
List<Event> newEvents = currentEvent.process();
eventQueue.addEvents(newEvents);
}
一般に (十分な大きさのイベント セットの場合)、これは、各ステップの後にイベント リストを再ソートするよりもはるかに高速です。
ところで、多くのイベント キューの実装は O(1) でデキューを実現します。一部の操作では、最悪の場合のパフォーマンスが並べ替えよりも優れていない可能性がありますが、実際の実装ははるかにうまく機能します (つまり、定数が小さくなり、平均パフォーマンスが向上します)。Java を使用している場合は、いくつかのイベント キューの実装を提供し、オープン ソースであるJAMES IIを参照することをお勧めします (免責事項: 私は開発者の 1 人です)。
編集(再定式化された質問への対処):
一般に、プロセスベースの離散イベント シミュレーションを実装する便利な方法はコルーチンです。詳細については、たとえばこのレポートを参照してください。ただし、実装に固執したい場合は、優先度をタプルに変更し(timeStep,processPriority)
、上記の疑似コードの適合バージョンを次のように使用できます。
while (!terminationConditionMet() && !queue.isEmpty()) {
//Read out event
Tuple minTime = queue.getMinTime();
ProcessEvent currentEvent = queue.dequeue();
//Execute event
List<ProcessEvent> newlySpawnedProcesses = processEvent.process();
//Re- and enqueue new events
int nextTimeStep = minTime.getTime() + 1;
if(!currentEvent.finalStateReached())
queue.requeue(currentEvent, new Tuple(nextTimeStep, currentEvent.getPriority()));
for(ProcessEvent event : newlySpawnedProcesses)
queue.enqueue(event, new Tuple(nextTimeStep, event.getPriority()));
}
もちろん、これは、カスタム コンパレータを指定するなどして、独自の種類の時間/優先度の順序を指定できるように十分に汎用的なイベント キューの実装を使用していることを前提としています。