Ném những người béo nhất ra khỏi một chiếc máy bay quá tải.


200

Giả sử bạn có một chiếc máy bay và nó ít tốn nhiên liệu. Trừ khi máy bay giảm 3000 pound trọng lượng hành khách, nó sẽ không thể đến sân bay tiếp theo. Để cứu số người tối đa, chúng tôi muốn ném những người nặng nhất ra khỏi máy bay trước.

Và oh yeah, có hàng triệu người trên máy bay, và chúng tôi muốn một thuật toán tối ưu để tìm những hành khách nặng nhất, mà không nhất thiết phải sắp xếp toàn bộ danh sách.

Đây là một vấn đề proxy cho một cái gì đó tôi đang cố gắng viết mã trong C ++. Tôi muốn thực hiện "part_sort" trên bảng kê khai hành khách theo trọng lượng, nhưng tôi không biết mình sẽ cần bao nhiêu yếu tố. Tôi có thể thực hiện thuật toán "part_sort" của riêng mình ("part_sort_accumulation_until"), nhưng tôi tự hỏi liệu có cách nào dễ dàng hơn để làm điều này bằng STL tiêu chuẩn không.


5
Nếu sự tương tự với con người, bạn có thể bắt đầu bằng cách loại bỏ những người nặng hơn X, ví dụ 120 kg, vì những người đó rất có thể nằm trong số những người béo nhất.
RedX

132
Tất cả hành khách sẽ hợp tác với bất kỳ bước nào của thuật toán?
Lior Kogan

34
chủ đề như thế này là lý do tại sao tôi yêu CNTT.
Markus

14
Cho tôi hỏi đây là hãng hàng không nào? Tôi muốn chắc chắn rằng tôi chỉ bay cùng họ trước kỳ nghỉ lễ - không phải sau khi tôi đã nuông chiều bản thân.
jp2code

24
Không cần có sự hợp tác của hành khách với các thiết bị phù hợp (như ghế phụ có vảy tích hợp).
Jim Fred

Câu trả lời:


102

Một cách sẽ là sử dụng một đống tối thiểu ( std::priority_queuetrong C ++). Đây là cách bạn làm điều đó, giả sử bạn có một MinHeaplớp học. (Vâng, ví dụ của tôi là trong C #. Tôi nghĩ bạn hiểu ý.)

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.

Theo các tài liệu tham khảo tiêu chuẩn, thời gian chạy nên tỷ lệ thuận với n log k, nsố lượng hành khách và klà số lượng vật phẩm tối đa trên heap. Nếu chúng tôi cho rằng trọng lượng của hành khách thường sẽ là 100 lbs trở lên, thì không chắc là đống đó sẽ chứa hơn 30 mặt hàng bất cứ lúc nào.

Trường hợp xấu nhất sẽ là nếu hành khách được trình bày theo thứ tự từ trọng lượng thấp nhất đến cao nhất. Điều đó sẽ yêu cầu mọi hành khách được thêm vào đống, và mọi hành khách sẽ bị xóa khỏi đống. Tuy nhiên, với một triệu hành khách và giả sử rằng chiếc máy bay nhẹ nhất nặng 100 lbs, thì n log kcông việc đã đạt đến một con số khá nhỏ.

Nếu bạn lấy trọng lượng của hành khách một cách ngẫu nhiên, hiệu suất sẽ tốt hơn nhiều. Tôi sử dụng một cái gì đó khá giống như thế này cho một công cụ đề xuất (tôi chọn 200 mặt hàng hàng đầu từ danh sách vài triệu). Tôi thường kết thúc với chỉ 50.000 hoặc 70.000 mặt hàng thực sự được thêm vào heap.

Tôi nghi ngờ rằng bạn sẽ thấy một cái gì đó khá giống nhau: phần lớn các ứng cử viên của bạn sẽ bị từ chối vì họ nhẹ hơn người nhẹ nhất đã có trong đống. Và Peeklà một O(1)hoạt động.

Để biết thêm thông tin về hiệu suất của heap select và chọn nhanh, xem Khi lý thuyết đáp ứng thực hành . Phiên bản ngắn: nếu bạn chọn ít hơn 1% tổng số mặt hàng, thì heap select là người chiến thắng rõ ràng so với chọn nhanh. Hơn 1%, sau đó sử dụng chọn nhanh hoặc một biến thể như Introselect .


1
SoapBox đăng câu trả lời nhanh hơn.
Vịt Mooing

7
Theo tôi đọc, câu trả lời của SoapBox tương đương với câu trả lời của Jim Mischel. SoapBox đã viết mã của mình bằng C ++ và do đó anh ta sử dụng bộ std :: set, có cùng thời gian đăng nhập (N) với MinHeap.
IvyMike

1
Có một giải pháp thời gian tuyến tính. Tôi sẽ thêm nó.
Neil G

2
Có một lớp STL cho một đống nhỏ:std::priority_queue
bdonlan

3
@MooingDuck: Có lẽ bạn hiểu lầm. Mã của tôi tạo ra một đống trống, giống như mã của SoapBox tạo một tập hợp trống. Sự khác biệt chính, như tôi thấy, là mã của anh ấy cắt tập hợp trọng lượng vượt quá khi các vật phẩm có trọng lượng cao hơn được thêm vào, trong khi của tôi duy trì sự dư thừa và cắt nó ở cuối. Bộ của anh ta sẽ có khả năng giảm kích thước khi anh ta di chuyển qua danh sách tìm những người nặng hơn. Heap của tôi vẫn giữ nguyên kích thước sau khi nó đạt đến ngưỡng trọng lượng và tôi cắt nó sau khi kiểm tra mục cuối cùng trong danh sách.
Jim Mischel

119

Điều này sẽ không giúp ích cho vấn đề proxy của bạn, tuy nhiên:

Để 1.000.000 hành khách giảm 3000 pound trọng lượng, mỗi hành khách phải mất (3000/1000000) = 0,003 lbs mỗi người. Điều đó có thể đạt được thông qua việc vứt bỏ mọi chiếc áo, hoặc giày, hoặc thậm chí là cắt móng tay, cứu tất cả mọi người. Điều này giả định việc thu thập và vứt bỏ hiệu quả trước khi giảm cân cần thiết khi máy bay sử dụng nhiều nhiên liệu hơn.

Trên thực tế, họ không cho phép cắt móng tay trên tàu nữa, vì vậy đó là ra.


14
Yêu khả năng nhìn xuyên suốt vấn đề và tìm ra cách thực sự tốt hơn.
fncomp

19
Bạn là một thiên tài. :)
Jonathan

3
Tôi nghĩ rằng giày một mình sẽ bao gồm điều này
Vịt Mooing

0,003 lbs là 0,048 oz, tức là dưới 1/20 ounce. Vì vậy, nếu chỉ một trong sáu mươi người trên máy bay tận dụng quy tắc dầu gội ba ounce, bạn có thể tiết kiệm cả ngày chỉ bằng cách vứt bỏ tất cả dầu gội đó.
Ryan Lundy

43

Dưới đây là một thực hiện khá đơn giản của giải pháp đơn giản. Tôi không nghĩ có một cách nhanh hơn mà chính xác 100%.

size_t total = 0;
std::set<passenger> dead;
for ( auto p : passengers ) {
    if (dead.empty()) {
       dead.insert(p);
       total += p.weight;
       continue;
    }
    if (total < threshold || p.weight > dead.begin()->weight)
    {
        dead.insert(p);
        total += p.weight;
        while (total > threshold)
        {
            if (total - dead.begin()->weight < threshold)
                break;
            total -= dead.begin()->weight;
            dead.erase(dead.begin());
        }
    }
 }

Điều này hoạt động bằng cách điền vào tập hợp "người chết" cho đến khi nó đạt đến ngưỡng. Sau khi đạt được ngưỡng, chúng tôi tiếp tục xem qua danh sách hành khách cố gắng tìm bất kỳ vật nào nặng hơn người chết nhẹ nhất. Khi chúng tôi đã tìm thấy một, chúng tôi thêm họ vào danh sách và sau đó bắt đầu "Lưu" những người nhẹ nhất ra khỏi danh sách cho đến khi chúng tôi không thể lưu thêm nữa.

Trong trường hợp xấu nhất, điều này sẽ thực hiện tương tự như một loại của toàn bộ danh sách. Nhưng trong trường hợp tốt nhất ("danh sách chết" được lấp đầy đúng với những người X đầu tiên), nó sẽ thực hiện O(n).


1
Tôi nghĩ bạn phải cập nhật totalbên cạnh continue; Khác, đây là câu trả lời tôi sẽ đăng. Giải pháp siêu nhanh
Vịt Mooing

2
Đây là câu trả lời đúng, đây là câu trả lời nhanh nhất, đây cũng là câu trả lời có độ phức tạp thấp nhất.
Xander Tulip

Bạn có thể có thể vắt kiệt hơn một chút bằng cách lưu trữ dead.begin () và sắp xếp lại công cụ một chút để giảm thiểu phân nhánh, điều này trên các bộ xử lý hiện đại khá chậm
Wug

dead.begin () rất có thể là trival và gần như chắc chắn sẽ được đưa vào chỉ một truy cập dữ liệu. Nhưng vâng, di chuyển xung quanh một vài trong số các if sẽ tăng hiệu suất hơn một chút bằng cách giảm chi nhánh ... nhưng có lẽ chi phí rất lớn để dễ đọc.
SoapBox

1
Điều này là hợp lý và giải quyết TẤT CẢ các yêu cầu của OP, bao gồm cả việc không biết số lượng hành khách lên phía trước. Mặc dù đã dành nhiều thời gian trong 5 tháng qua để làm việc với STL Maps & Set, tôi chắc chắn rằng việc sử dụng rộng rãi các trình vòng lặp được sử dụng sẽ làm tê liệt hiệu suất. Chỉ cần điền vào tập hợp, và sau đó lặp từ phải sang trái cho đến khi tổng số người nặng nhất lớn hơn 3.000. Tập hợp 1 triệu phần tử, được trình bày theo thứ tự ngẫu nhiên, sẽ tải với tốc độ ~ 30 triệu / giây trên các lõi i5 || i7 3,4Ghz. Lặp lại ít nhất 100X là chậm. KISS sẽ giành chiến thắng ở đây.
dùng2548100

32

Giả sử tất cả hành khách sẽ hợp tác: Sử dụng mạng phân loại song song . (xem thêm cái này )

Đây là một cuộc biểu tình trực tiếp

Cập nhật: Video thay thế (nhảy đến 1:00)

Yêu cầu các cặp người so sánh trao đổi - bạn không thể nhanh hơn thế này.


1
Đây vẫn là một loại và sẽ là O (nlogn). Bạn chắc chắn có thể nhận được nhanh hơn, như một O (nlogk) trong đó k << n, giải pháp đã được cung cấp.
Adam

1
@Adam: Đó là loại song song. Sắp xếp có giới hạn dưới của các bước O (nlog n) SEQUENTIAL. Tuy nhiên chúng có thể song song, vì vậy độ phức tạp thời gian có thể thấp hơn nhiều. xem ví dụ cs.umd.edu/~gasarch/ramsey/parasort.pdf
Lior Kogan

1
Vâng, OP nói "Đây là một vấn đề proxy cho một cái gì đó tôi đang cố mã hóa trong C ++." Vì vậy, ngay cả khi hành khách sẽ hợp tác, họ sẽ không tính toán cho bạn. Đó là một ý tưởng gọn gàng, nhưng giả định của bài báo rằng bạn có nbộ xử lý không giữ được.
Adam

@LiorKogan - video demo trực tiếp không còn có sẵn trên youtube
Adelin

@Adelin: Cảm ơn bạn, video thay thế đã được thêm
Lior Kogan

21

@Blastfurnace đã đi đúng hướng. Bạn sử dụng quickselect trong đó các pivots là ngưỡng trọng lượng. Mỗi phân vùng chia một bộ người thành các bộ và trả về tổng trọng số cho mỗi bộ người. Bạn tiếp tục phá vỡ thùng thích hợp cho đến khi xô của bạn tương ứng với người có trọng lượng cao nhất là hơn 3000 pounds và thùng thấp nhất của bạn trong bộ đó có 1 người (nghĩa là không thể chia thêm nữa.)

Thuật toán này được khấu hao theo thời gian tuyến tính, nhưng trường hợp xấu nhất bậc hai. Tôi nghĩ rằng nó là thuật toán thời gian tuyến tính duy nhất .


Đây là một giải pháp Python minh họa thuật toán này:

#!/usr/bin/env python
import math
import numpy as np
import random

OVERWEIGHT = 3000.0
in_trouble = [math.floor(x * 10) / 10
              for x in np.random.standard_gamma(16.0, 100) * 8.0]
dead = []
spared = []

dead_weight = 0.0

while in_trouble:
    m = np.median(list(set(random.sample(in_trouble, min(len(in_trouble), 5)))))
    print("Partitioning with pivot:", m)
    lighter_partition = []
    heavier_partition = []
    heavier_partition_weight = 0.0
    in_trouble_is_indivisible = True
    for p in in_trouble:
        if p < m:
            lighter_partition.append(p)
        else:
            heavier_partition.append(p)
            heavier_partition_weight += p
        if p != m:
            in_trouble_is_indivisible = False
    if heavier_partition_weight + dead_weight >= OVERWEIGHT and not in_trouble_is_indivisible:
        spared += lighter_partition
        in_trouble = heavier_partition
    else:
        dead += heavier_partition
        dead_weight += heavier_partition_weight
        in_trouble = lighter_partition

print("weight of dead people: {}; spared people: {}".format(
    dead_weight, sum(spared)))
print("Dead: ", dead)
print("Spared: ", spared)

Đầu ra:

Partitioning with pivot: 121.2
Partitioning with pivot: 158.9
Partitioning with pivot: 168.8
Partitioning with pivot: 161.5
Partitioning with pivot: 159.7
Partitioning with pivot: 158.9
weight of dead people: 3051.7; spared people: 9551.7
Dead:  [179.1, 182.5, 179.2, 171.6, 169.9, 179.9, 168.8, 172.2, 169.9, 179.6, 164.4, 164.8, 161.5, 163.1, 165.7, 160.9, 159.7, 158.9]
Spared:  [82.2, 91.9, 94.7, 116.5, 108.2, 78.9, 83.1, 114.6, 87.7, 103.0, 106.0, 102.3, 104.9, 117.0, 96.7, 109.2, 98.0, 108.4, 99.0, 96.8, 90.7, 79.4, 101.7, 119.3, 87.2, 114.7, 90.0, 84.7, 83.5, 84.7, 111.0, 118.1, 112.1, 92.5, 100.9, 114.1, 114.7, 114.1, 113.7, 99.4, 79.3, 100.1, 82.6, 108.9, 103.5, 89.5, 121.8, 156.1, 121.4, 130.3, 157.4, 138.9, 143.0, 145.1, 125.1, 138.5, 143.8, 146.8, 140.1, 136.9, 123.1, 140.2, 153.6, 138.6, 146.5, 143.6, 130.8, 155.7, 128.9, 143.8, 124.0, 134.0, 145.0, 136.0, 121.2, 133.4, 144.0, 126.3, 127.0, 148.3, 144.9, 128.1]

3
+1. Đây là một ý tưởng thú vị, mặc dù tôi không chắc rằng nó khá tuyến tính. Trừ khi tôi thiếu thứ gì đó, bạn phải lặp đi lặp lại các vật phẩm để tính tổng trọng lượng của thùng và bạn phải tính lại thùng cao (ít nhất là một phần) mỗi khi bạn tách. Nó vẫn sẽ nhanh hơn cách tiếp cận dựa trên đống của tôi trong trường hợp chung, nhưng tôi nghĩ bạn đang đánh giá thấp sự phức tạp.
Jim Mischel

2
@Jim: Nó phải phức tạp tương tự như quickselect . Tôi biết mô tả trên wikipedia không phải là tốt nhất, nhưng lý do là thời gian khấu hao tuyến tính là vì mỗi khi bạn thực hiện một phân vùng, bạn chỉ làm việc với một bên của phân vùng. Không nghiêm ngặt, hãy tưởng tượng mỗi phân vùng chia nhóm người thành hai. Sau đó, bước đầu tiên lấy O (n), rồi O (n / 2), v.v. và, n + n / 2 + n / 4 + ... = 2n.
Neil G

2
@Jim: Dù sao, thuật toán của bạn có thời gian trường hợp xấu nhất, trong khi của tôi có thời gian trường hợp trung bình tốt nhất. Tôi nghĩ rằng cả hai đều là giải pháp tốt.
Neil G

2
@JimMischel, NeilG: codepad.org/FAx6hbtc Tôi đã xác minh tất cả đều có kết quả giống nhau và đã sửa lỗi của Jim. FullSort: 1828 tick. JimMischel: 312 tick. Xà phòng 109 tick. NeilG: 641 tích tắc.
Vịt Mooing

2
@NeilG: codepad.org/0KmcsvwD Tôi đã sử dụng phân vùng std :: để thực hiện thuật toán của bạn nhanh hơn. stdsort: 1812 tick. FullHeap 312 tick. Hộp xà phòng / JimMichel: 109 tick, NeilG: 250 tick.
Vịt Mooing

11

Giả sử rằng, giống như trọng lượng của mọi người, bạn có ý tưởng tốt về những giá trị tối đa và tối thiểu có khả năng sẽ được sử dụng một loại cơ số để sắp xếp chúng trong O (n). Sau đó, chỉ cần làm việc từ đầu nặng nhất của danh sách theo hướng nhẹ nhất. Tổng thời gian chạy: O (n). Thật không may, không có triển khai loại radix trong STL, nhưng nó khá đơn giản để viết.


Tuy nhiên, tôi sẽ không sử dụng một loại cơ số chung, vì bạn không phải sắp xếp đầy đủ danh sách để rút ra câu trả lời.
Vịt Mooing

1
Để làm rõ, một loại cơ số một ý tưởng tốt. Chỉ cần chắc chắn để viết một tùy chỉnh tối ưu hóa.
Vịt Mooing

1
@Mooing: Đúng là bạn không cần phải thực hiện một loại cơ số hoàn chỉnh, nhưng tại thời điểm tôi đăng bài này, không có thuật toán O (n) nào được đăng và đây là một thuật toán dễ thấy. Tôi nghĩ rằng câu trả lời của Neil G là câu trả lời hay nhất của anh ấy bây giờ khi anh ấy giải thích nó đầy đủ hơn và rõ ràng bắt đầu sử dụng trung vị làm trụ cột cho lựa chọn của mình. Nhưng việc sử dụng một loại cơ số tiêu chuẩn sẽ dễ dàng hơn một chút và ít có các lỗi triển khai tinh vi hơn, vì vậy tôi sẽ để lại câu trả lời của mình. Thực hiện một loại cơ số một phần tùy chỉnh chắc chắn sẽ nhanh hơn, nhưng không có triệu chứng như vậy.
Keith Irwin

6

Tại sao bạn không sử dụng quicksort một phần với quy tắc hủy bỏ khác với "sắp xếp". Bạn có thể chạy nó và sau đó chỉ sử dụng nửa cao hơn và tiếp tục cho đến khi trọng lượng trong nửa cao hơn này không chứa trọng lượng ít nhất phải được ném ra nữa, hơn là bạn quay lại một bước trong đệ quy và sắp xếp danh sách. Sau đó, bạn có thể bắt đầu ném mọi người ra khỏi danh sách cao cấp được sắp xếp đó.


Đó là khái niệm cơ bản đằng sau thuật toán Neil G của tôi nghĩ .
Vịt Mooing

đó là bản chất của quickselect, đó là những gì Neil G đang sử dụng.
Michael Donohue

6

Sắp xếp giải đấu song song lớn: -

Giả sử ba chỗ ngồi tiêu chuẩn mỗi bên của ailse: -

  1. Yêu cầu hành khách ngồi ghế bên cửa sổ di chuyển đến ghế giữa nếu họ nặng hơn người ngồi ở cửa sổ.

  2. Yêu cầu hành khách ngồi ở ghế giữa để trao đổi với hành khách ở lối đi nếu họ nặng hơn.

  3. Yêu cầu hành khách ở ghế bên trái lối đi để trao đổi với hành khách ở ghế bên phải id họ nặng hơn.

  4. Bong bóng sắp xếp hành khách ở ghế bên phải. (Thực hiện n bước cho n hàng). - yêu cầu hành khách ở ghế bên phải để trao đổi với người ở phía trước n -1 lần.

5 Ném chúng ra khỏi cửa cho đến khi bạn đạt 3000 pounds.

3 bước + n bước cộng với 30 bước nếu bạn có tải hành khách thực sự gầy.

Đối với mặt phẳng hai lối đi - các hướng dẫn phức tạp hơn nhưng hiệu suất là như nhau.


giống như câu trả lời của Lior Kogan, nhưng chi tiết hơn nhiều.
Vịt Mooing

7
Một giải pháp "đủ tốt" sẽ là cung cấp "hotdogs miễn phí" và ném ra mười lăm đầu tiên đạt đến mặt trận. Sẽ không cung cấp giải pháp tối ưu mọi lúc nhưng chạy ở dạng "O" đơn giản.
James Anderson

Sẽ không tốt hơn nếu vứt bỏ 15 người cuối cùng vì những người nặng hơn có thể sẽ chậm hơn?
Peter

@Patriker - Tôi tin rằng mục tiêu là giảm 3000 pound với số lượng người tối thiểu. Mặc dù bạn có thể tối ưu hóa thuật toán bằng cách thay đổi bước 4 thành "trao đổi với người từ n - 29 lần", điều này sẽ giúp 30 người trở nên dễ thương nhất ở phía trước, tuy nhiên, không theo thứ tự nghiêm ngặt.
James Anderson

4

Tôi có thể sẽ sử dụng std::nth_elementđể phân vùng 20 người nặng nhất trong thời gian tuyến tính. Sau đó, sử dụng một phương pháp phức tạp hơn để tìm và vượt qua những thiên đường nặng nhất.


3

Bạn có thể thực hiện một lần vượt qua danh sách để lấy giá trị trung bình và độ lệch chuẩn, sau đó sử dụng số đó để ước tính số lượng người phải đi. Sử dụng part_sort để tạo danh sách dựa trên số đó. Nếu dự đoán thấp, hãy sử dụng part_sort một lần nữa trên phần còn lại với dự đoán mới.



2

Đây là một giải pháp dựa trên heap sử dụng mô đun heapq tích hợp của Python. Nó trong Python vì vậy không trả lời câu hỏi ban đầu, nhưng nó sạch hơn (IMHO) so với giải pháp Python được đăng khác.

import itertools, heapq

# Test data
from collections import namedtuple

Passenger = namedtuple("Passenger", "name seat weight")

passengers = [Passenger(*p) for p in (
    ("Alpha", "1A", 200),
    ("Bravo", "2B", 800),
    ("Charlie", "3C", 400),
    ("Delta", "4A", 300),
    ("Echo", "5B", 100),
    ("Foxtrot", "6F", 100),
    ("Golf", "7E", 200),
    ("Hotel", "8D", 250),
    ("India", "8D", 250),
    ("Juliet", "9D", 450),
    ("Kilo", "10D", 125),
    ("Lima", "11E", 110),
    )]

# Find the heaviest passengers, so long as their
# total weight does not exceeed 3000

to_toss = []
total_weight = 0.0

for passenger in passengers:
    weight = passenger.weight
    total_weight += weight
    heapq.heappush(to_toss, (weight, passenger))

    while total_weight - to_toss[0][0] >= 3000:
        weight, repreived_passenger = heapq.heappop(to_toss)
        total_weight -= weight


if total_weight < 3000:
    # Not enough people!
    raise Exception("We're all going to die!")

# List the ones to toss. (Order doesn't matter.)

print "We can get rid of", total_weight, "pounds"
for weight, passenger in to_toss:
    print "Toss {p.name!r} in seat {p.seat} (weighs {p.weight} pounds)".format(p=passenger)

Nếu k = số lượng hành khách quăng và N = số lượng hành khách, thì trường hợp tốt nhất cho thuật toán này là O (N) và trường hợp xấu nhất cho thuật toán này là Nlog (N). Trường hợp xấu nhất xảy ra nếu k ở gần N trong một thời gian dài. Dưới đây là một ví dụ về dàn diễn viên tệ nhất:

weights = [2500] + [1/(2**n+0.0) for n in range(100000)] + [3000]

Tuy nhiên, trong trường hợp này (ném người ra khỏi máy bay (bằng dù, tôi đoán vậy)) thì k phải nhỏ hơn 3000, đó là << "hàng triệu người". Do đó thời gian chạy trung bình nên là về Nlog (k), là tuyến tính với số lượng người.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.