投掷的最胖的人断过载的飞机。的人、飞机

2023-09-10 23:43:53 作者:春眠不覺曉、二逼真不少

假设你有一架飞机,它是低燃料。除非平面下降三千磅乘客的重量,它将无法到达下机场。为了挽救生命的最大数量,我们想先抛出最重的人下飞机的。

Let's say you've got an airplane, and it is low on fuel. Unless the plane drops 3000 pounds of passenger weight, it will not be able to reach the next airport. To save the maximum number of lives, we would like to throw the heaviest people off of the plane first.

和噢,现在有成千上万的人在飞机上,我们希望优化算法来找出最重的乘客,而不必进行排序的整个列表。

And oh yeah, there are millions of people on the airplane, and we would like an optimal algorithm to find the heaviest passengers, without necessarily sorting the entire list.

这是什么东西,我想code C ++中的代理问题。我想这样做的重量体现了乘客一个partial_sort,但我不知道我有多少元素将需要。我可以实现我自己的partial_sort算法(partial_sort_accumulate_until),但我不知道是否有任何简单的方法来做到这一点使用标准的STL。

This is a proxy problem for something I'm trying to code in C++. I would like to do a "partial_sort" on the passenger manifest by weight, but I don't know how many elements I'm going to need. I could implement my own "partial_sort" algorithm ("partial_sort_accumulate_until"), but I'm wondering if there's any easier way to do this using standard STL.

推荐答案

一种方法是使用最小堆 (std::priority_queue在C ++中)。这里是你如何做到这一点,假设你有一个 MinHeap 类。 (是的,我的例子是在C#中,我觉得你的想法。)

One way would be to use a min heap (std::priority_queue in C++). Here's how you'd do it, assuming you had a MinHeap class. (Yes, my example is in C#. I think you get the idea.)

int targetTotal = 3000;
int totalWeight = 0;
// this creates an empty heap!
var myHeap = new MinHeap<Passenger>(/* need comparer here to order by weight */);
foreach (var pass in passengers)
{
    if (totalWeight < targetTotal)
    {
        // unconditionally add this passenger
        myHeap.Add(pass);
        totalWeight += pass.Weight;
    }
    else if (pass.Weight > myHeap.Peek().Weight)
    {
        // If this passenger is heavier than the lightest
        // passenger already on the heap,
        // then remove the lightest passenger and add this one
        var oldPass = myHeap.RemoveFirst();
        totalWeight -= oldPass.Weight;
        myHeap.Add(pass);
        totalWeight += pass.Weight;
    }
}

// At this point, the heaviest people are on the heap,
// but there might be too many of them.
// Remove the lighter people until we have the minimum necessary
while ((totalWeight - myHeap.Peek().Weight) > targetTotal)
{
    var oldPass = myHeap.RemoveFirst();
    totalWeight -= oldPass.Weight; 
}
// The heap now contains the passengers who will be thrown overboard.

根据标准的引用文件,运行时间应该是比例 N日志氏/ code>,其中 N 是多少乘客和 K 是堆项目的最大数量。如果我们假设乘客的重量通常是百磅以上,那么它是不可能的,堆将包含30余项,在任何时候。

According to the standard references, running time should be proportional to n log k, where n is the number of passengers and k is the maximum number of items on the heap. If we assume that passengers' weights will typically be 100 lbs or more, then it's unlikely that the heap will contain more than 30 items at any time.

最坏的情况是,如果乘客psented为了从最低重量最高$ P $。这将要求每个乘客被添加到堆,每一个乘客从堆移除。不过,有一百万人次,并假设最轻的重100磅的 N日志氏/ code>工程以一个相当小的数字。

The worst case would be if the passengers are presented in order from lowest weight to highest. That would require that every passenger be added to the heap, and every passenger be removed from the heap. Still, with a million passengers and assuming that the lightest weighs 100 lbs, the n log k works out to a reasonably small number.

如果你随机得到乘客的重量,性能要好得多。我用的东西很喜欢这个的推荐引擎(我选择排名前200名的项目从几万元的列表)。我通常落得只有50000 70000项实际添加到堆中。

If you get the passengers' weights randomly, performance is much better. I use something quite like this for a recommendation engine (I select the top 200 items from a list of several million). I typically end up with only 50,000 or 70,000 items actually added to the heap.

我怀疑你会看到的东西非常相似:大部分的考生将被拒绝,因为他们比最轻的人已经在堆上轻。而皮克 O(1)操作。

I suspect that you'll see something quite similar: the majority of your candidates will be rejected because they're lighter than the lightest person already on the heap. And Peek is an O(1) operation.

有关堆的性能的详细信息选择和快速选择,请参见当理论符合实践。短版:如果你选择的项目总数的不到1%,然后堆选择是一个明显的赢家了快速选择。超过1%,然后使用快速选择,或如 Introselect 的一个变种。

For a more information about the performance of heap select and quick select, see When theory meets practice. Short version: if you're selecting fewer than 1% of the total number of items, then heap select is a clear winner over quick select. More than 1%, then use quick select or a variant like Introselect.

 
精彩推荐
图片推荐