1

私は学校向けのプログラムをやっていて、それをどうやってやるべきかを決めようとしています。

これはレストランのシミュレーションです。テーブルと待機中のパーティのランダムなリストを生成します。順番待ちリストに載っていない予約のあるパーティーがランダムにあります。予約のある方を優先してほしいです。

予約のあるすべての関係者が一方の側にあり、もう一方の側がないようにリストを並べ替えるのは、これを行うための良い方法ですか?

次に、リストを評価して、パーティーがテーブルに収まるかどうかを確認し、それらを着席させるか、次のパーティーに進みます。それとも、これを回避するためのよりスマートな方法はありますか?どんな入力でも大歓迎です!

4

5 に答える 5

6
var groupedParties = parties.GroupBy(p => p.HasReservation);

それは私が今まで見た中で最もきれいな方法です。2つのグループのリストが表示されます。1つは予約なしのパーティーあり、もう1つは予約付きのパーティーです。これで、さまざまな種類の待機パーティの座席を個別に処理できるようになりました。

編集

static void Main(string[] args)
{
    GenerateRandomDataSomehow();
    var groupedParties = _parties.GroupBy(p => p.HasReservation)
    SeatParty(groupedParties.FirstOrDefault(g => g.Key == true));
    SeatParty(groupedParties.FirstOrDefault(g => g.Key == false));
}

private static void SeatParty(IEnumerable<Party> partyGroup)
{
    if (partyGroup == null) return;

    foreach (var party in partyGroup.OrderBy(p => p.ArrivalTime))
    {
        var properTable = _tables.FirstOrDefault(t => t.SeatsCount == party.PersonsCount &&
                                                      t.Party == null);
        if (properTable == null) continue;
        properTable.Party = party;
    }
}

ここでは、より多くのLINQを使用した非常に単純な実装を示します。選択基準を適切に拡張する必要があります。このテーブルでは、他のパーティがこのテーブルに着席していない場合、および人数数が正確に対応するテーブルのシート数である場合、「適切」と評価されます。適切なテーブルが見つからない場合、グループはスキップされます。

于 2013-03-01T10:29:10.850 に答える
3

リストではなく、キューまたはキューのような構成を使用してレストランをモデル化し、別のアプローチを採用することをお勧めします。このように、到着した順に人を保存するので、並べ替えは必要ありません。

人々をPartyオブジェクトにグループ化します。締約国が到着したら、それらをキューに追加できます。次に、キューを確認し、パーティに予約がある場合は、それらをキューから削除して、テーブルに送信します。パーティーに予約がない場合は、そのサイズのパーティーでテーブルが利用可能かどうかを確認し、利用可能な場合は、そのパーティーをキ​​ューから削除します。

それ以外の場合は、テーブルが使用可能になるまで待つことができます。そのイベントが発生すると、テーブルのサイズに合うパーティーを探して、再びキューを歩くことができます。また、この時点でキューに予約のあるパーティーが含まれているかどうかを確認することもできます。つまり、優先されます。これを使用Queue.First(x => x.HasReservation && x.Size <= Table.Places)して、予約があり、テーブルに収まる最初のセットの人々をキューから取得します**。それ以外の場合はQueue.First(x => x.Size <= Table.Places)、テーブルに収まる最初のキューのセットを取得します。

キューを使用する利点は、並べ替えが不要なことです。人のパーティを到着順に処理し、予約のある人を優先します。

2つのポイントでキューをチェックします。

  1. 到着時(予約はありますか、テーブルはありますか)
  2. テーブルが利用可能になったら、最初に予約をしてテーブルに収まるようになっている人を探します。一致するものがない場合は、テーブルサイズに一致する(またはテーブルに収まる)キューから最初の人のセットを取得します

それは始めるのに良い場所です。

アップデート

ご存知のように、キューの途中からアイテムを削除することはできません。これは、キューが先入れ先出し(FIFO)であるためです[後入れ先出しのスタックとは対照的に-LIFO]。ソートを回避するために、セマンティクスのようなキュー付きリストを使用できます。この回答には良い例があります。

**ここにはもう1つの興味深いキューイングの問題があります。それは、効率の問題です。4か所のテーブルができたらどうしますか?テーブルに収まる最初に到着したパーティに渡すか、テーブルに収まるキュー内の最大のパーティに渡します。明らかに、最初のオプションは最も長く待っている人を座っているのでカスタマーサービスに最適ですが、2番目のオプションはテーブルをより十分に活用しているので利益を最大化します:-)

于 2013-03-01T10:45:50.377 に答える
2

リストを並べ替える場合:

を使用してEnumerable.OrderByDescendingThenByDescending

var ordered = parties.OrderByDescending(p => p.HasReservation)
                     .ThenByDescending(p => p.PersonCount);
// if you want a new list use ordered.ToList()
foreach(var party in ordered)
{
    // ...
}

List<T>.Sort元のリストを並べ替える場合は、カスタムデリゲートで使用できます。

parties.Sort((p1, p2) =>
{
    if (p1.HasReservation != p2.HasReservation)
        return p1.HasReservation ? 1 : -1;
    else
        return p1.PersonCount.CompareTo(p2.PersonCount);
});
于 2013-03-01T10:30:30.373 に答える
0

System.Linqこの状況でリストを並べ替えるには、おそらく使用するのが最善のオプションです。

何かのようなもの:

var sorted = tables.OrderByDescending(o => o.IsReserved);
于 2013-03-01T10:30:34.430 に答える
0

私は単純に2つのキューを使用します(あなたのパーティーがというタイプで表されていると仮定しますParty。タイプを適切に変更します):

Queue<Party> withReservation = new Queue<Party>();
Queue<Party> withoutReservation = new Queue<Party>();

次のように、パーティをキューに追加できます。

if (party has reservation) { // (condition in pseudo code)
    withReservation.Enqueue(party);
} else {
    withoutReservation.Enqueue(party);
}

あなたはこのようなパーティーに着席します:

if (withReservation.Count > 0) {
    Seat(withReservation.Dequeue());
} else if (withoutReservation.Count > 0) {
    Seat(withoutReservation.Dequeue());
}
于 2013-03-03T15:38:01.240 に答える