Αλγόριθμος Kadence: Largest Sum Contiguous Subarray

⚡ Έξυπνη Σύνοψη

Ο αλγόριθμος του Kadane βρίσκει τον μεγαλύτερο συνεχόμενο υποπίνακα αθροίσματος σε γραμμικό χρόνο ως εξής: tracΧρησιμοποιήστε ένα τρέχον μέγιστο αντί να σαρώνετε κάθε πιθανό υποπίνακα. Αυτό το κλασικό κόλπο δυναμικού προγραμματισμού λύνει προβλήματα μετοχών, χρηματοοικονομικών και σημάτων.

  • 🎯 Ορισμός του προβλήματος: Ένας συνεχόμενος υποπίνακας είναι μια ακολουθία διαδοχικών στοιχείων· ο στόχος είναι ο υποπίνακας με το υψηλότερο αριθμητικό άθροισμα μέσα σε έναν μικτό θετικό και αρνητικό πίνακα.
  • 🐢 Ωμή Δύναμη: Δύο ένθετοι βρόχοι αξιολογούν κάθε δείκτη έναρξης και λήξης σε χρόνο O(N²) και εκτυπώνουν το παράθυρο που κερδίζει χρησιμοποιώντας δείκτες έναρξης και λήξης.
  • Η διορατικότητα του Kadane: Μηδενίστε το τρέχον άθροισμα κάθε φορά που το τρέχον στοιχείο ξεπερνά τον συσσωρευτή, διατηρώνταςping μόνο το καλύτερο πρόθεμα που θα μπορούσε ακόμα να εξελιχθεί στην απάντηση.
  • 🧭 Παράδειγμα εργασίας: Μια σύντομη περιήγηση σε έναν πίνακα με αρνητικά δείχνει πώς οι συναρτήσεις max_sum και current_sum εξελίσσονται βήμα προς βήμα μέχρι να καταγραφεί το πραγματικό μέγιστο.
  • 💻 Κάλυψη γλώσσας: Και τα δύο C++ και Python Οι υλοποιήσεις της απλής προσέγγισης και του Αλγορίθμου του Kadane καταδεικνύουν τη μετάβαση από τον χρόνο O(N²) στον χρόνο O(N).
  • 📊 Περίπλοκο: Ο αλγόριθμος του Kadane εκτελείται σε χρόνο O(N) με επιπλέον χώρο O(1), ξεπερνώντας δραματικά την απόδοση της γραμμής βάσης brute-force σε μεγάλους πίνακες εισόδου.

Αλγόριθμος Kadane - Συνεχής υποπίνακας με το μεγαλύτερο άθροισμα

Ποιο είναι το μεγαλύτερο άθροισμα συνεχόμενων υποπίνακων;

Ένας υποπίνακας είναι ένα συνεχές μέρος ενός πίνακα. Μπορεί να είναι ένα μεμονωμένο στοιχείο ενός πίνακα ή κάποιο κλάσμα του πίνακα. Ο συνεχής υποπίνακας μεγαλύτερου αθροίσματος σημαίνει υποσυστοιχία που έχει τη μέγιστη τιμή αθροίσματος.

Για παράδειγμα, πάρτε τον πίνακα {-10, 5, 1, 6, -9, 2, -7, 3, -5}. Οι υποπίνακες του μπορούν να είναι {-10, 5, 1, 6}, {5, 1, 6} ή {2, -7, 3, -5}, και ούτω καθεξής. Ωστόσο, το {5, 1, 6, 3} δεν μπορεί να είναι υποπίνακας επειδή τα στοιχεία δεν βρίσκονται σε συνεχόμενη ακολουθία.

Μεγαλύτερο άθροισμα συνεχόμενου Subarray

Αν παρατηρήσετε, μεταξύ όλων των υποπίνακων, ο επισημασμένος υποπίνακας {5, 1, 6} έχει τη μέγιστη τιμή αθροίσματος:

Μεγαλύτερο άθροισμα Συνεχής υποπίνακας με επισήμανση

Το άθροισμα του υποπίνακα {5, 1, 6} είναι 12, το μέγιστο άθροισμα όλων των πιθανών υποπινάκων του παραπάνω πίνακα. Έτσι, για αυτόν τον πίνακα, το μέγιστο άθροισμα ενός συνεχόμενου υποπίνακα είναι {5, 1, 6}.

Απλή προσέγγιση για την επίλυση του μεγαλύτερου αθροίσματος συνεχόμενων υποπίνακα

Ο απλός τρόπος για να λύσετε αυτό το πρόβλημα είναι να χρησιμοποιήσετε δύο βρόχους για να βρείτε όλους τους υποπίνακες, να υπολογίσετε το άθροισμα και στη συνέχεια να βρείτε τη μέγιστη τιμή του.

Ακολουθεί το διάγραμμα ροής για την απλή προσέγγιση εύρεσης του μεγαλύτερου αθροίσματος συνεχόμενου υποπίνακα. Πρόκειται για μια προσέγγιση ωμής βίας, καθώς εξετάζουμε κάθε πιθανό υποπίνακα.

Απλή προσέγγιση για την επίλυση του μεγαλύτερου αθροίσματος

Εδώ είναι τα απλά βήματα για να το κάνετε αυτό.

Βήμα 1) αρχικοποίηση μέγιστο_άθροισμα με την ελάχιστη ακέραια τιμή και ορίστε αρχίζουν και τέλος στο μηδέν.

Βήμα 2) Ας i και j να είναι δείκτες πίνακα όπου j είναι μεγαλύτερο ή ίσο με i; i σηματοδοτεί την έναρξη του υποπίνακα και j το τέλος του.

Βήμα 3) τρέχον_άθροισμα περιέχει το τρέχον άθροισμα. Μετά από κάθε ενημέρωση, ελέγξτε αν τρέχον_άθροισμα είναι μεγαλύτερη από ό, τι μέγιστο_άθροισμα.

Βήμα 4) If τρέχον_άθροισμα είναι μεγαλύτερο, αντικαταστήστε μέγιστο_άθροισμα με αυτό.

Βήμα 5) Κατά τη j φτάνει στο τέλος του πίνακα, αυξάνεται i και επαναφορά τρέχον_άθροισμα να 0.

Βήμα 6) Επαναλάβετε μέχρι i φτάνει στο τέλος του πίνακα. μέγιστο_άθροισμα τότε περιέχει το μεγαλύτερο άθροισμα υποπίνακα.

Παρατσούκλι Code για Απλή Προσέγγιση

function maximumSubarraySum():
    input: array
    for all possible subArray from array:
        calculate sum of each subarray
        store the maximum subArray
    return the maximum sum

C++ Εφαρμογή Απλής Προσέγγισης

#include <stdio.h>
#include <iostream>
using namespace std;
void maximumSubarraySum(int array[], int n) {
    int max_sum = -1e9;
    int begin = 0;
    int end = 0;
    for (int i = 0; i < n; i++) {
        int current_sum = 0;
        for (int j = i; j < n; j++) {
            current_sum += array[j];
            if (max_sum < current_sum) {
                max_sum = current_sum;
                begin = i;
                end = j;
            }
        }
    }
    cout << "largest sum is " << max_sum << endl;
    cout << "largest sum contiguous subarray: ";
    for (int i = begin; i <= end; i++) {
        cout << array[i] << "\t";
    }
}
int main() {
    int array[] = {-10, 5, 1, 6, -9, 2, -7, 3, -5};
    maximumSubarraySum(array, sizeof(array) / sizeof(array[0]));
}

Παραγωγή:

largest sum is 12
largest sum contiguous subarray: 5      1       6

Python Εφαρμογή Απλής Προσέγγισης

def maximumSubarraySum(numbers):
    max_sum, begin, end = -1e9, 0, 0
    for i in range(len(numbers)):
        current_sum = 0
        for j in range(i, len(numbers)):
            current_sum += numbers[j]
            if max_sum < current_sum:
                max_sum = current_sum
                begin, end = i, j
    print("largest sum is ", max_sum)
    print("largest sum contiguous subarray: ", end='')
    for i in range(begin, end + 1):
        print(numbers[i], end='\t')

numbers = [-10, 5, 1, 6, -9, 2, -7, 3, -5]
maximumSubarraySum(numbers)

Παραγωγή:

largest sum is 12
largest sum contiguous subarray: 5      1       6

Αλγόριθμος Kadane για την εύρεση του μεγαλύτερου συνεχόμενου υποπίνακα αθροίσματος

Ο Αλγόριθμος Kadane είναι μια μέθοδος Δυναμικού Προγραμματισμού που χρησιμοποιεί έναν μόνο βρόχο αντί για δύο. Χειρίζεται πίνακες με μικτούς θετικούς και αρνητικούς αριθμούς, εφόσον τουλάχιστον μία τιμή δεν είναι αρνητική.

Χρειαζόμαστε μόνο δύο μεταβλητές για να βρούμε τον μεγαλύτερο συνεχόμενο υποπίνακα αθροίσματος. Ακολουθεί το διάγραμμα ροής:

Ο Αλγόριθμος του Kadane για την εύρεση του μεγαλύτερου αθροίσματος

Ακολουθούν τα βήματα για τον αλγόριθμο του Kadane:

Βήμα 1) Δημιουργήστε δύο μεταβλητές, τρέχον_άθροισμα και μέγιστο_άθροισμα.

τρέχον_άθροισμα διατηρεί το μέγιστο άθροισμα που τελειώνει σε έναν συγκεκριμένο δείκτη πίνακα, ενώ μέγιστο_άθροισμα αποθηκεύει τη μεγαλύτερη αθροιστική τιμή που έχει παρατηρηθεί μέχρι στιγμής.

Βήμα 2) Προσθέστε κάθε στοιχείο πίνακα σε τρέχον_άθροισμαΣτη συνέχεια, ελέγξτε τις δύο παρακάτω συνθήκες:

  • If τρέχον_άθροισμα είναι μικρότερο από το τρέχον στοιχείο, τότε τρέχον_άθροισμα γίνεται το τρέχον στοιχείο.
  • If μέγιστο_άθροισμα είναι λιγότερο από τρέχον_άθροισμα, Τότε μέγιστο_άθροισμα γίνεται τρέχον_άθροισμα.

Βήμα 3) Αφού επαναλάβετε το προηγούμενο βήμα για ολόκληρο τον πίνακα, μέγιστο_άθροισμα περιέχει τον μεγαλύτερο συνεχόμενο υποπίνακα αθροίσματος.

Παράδειγμα αλγόριθμου Kadane

Παρουσιάζουμε τον Αλγόριθμο του Kadane σε έναν μικρό πίνακα και εξετάζουμε κάθε βήμα της εύρεσης του μεγαλύτερου συνεχόμενου υποπίνακα αθροίσματος.

Ας υποθέσουμε ότι ο δοθέντας πίνακας είναι όπως ο ακόλουθος:

Παράδειγμα αλγόριθμου Kadane

Ακολουθούν τα βήματα του αλγορίθμου Kadane:

Βήμα 1) Δημιουργήστε δύο μεταβλητές, τρέχον_άθροισμα και μέγιστο_άθροισμα. Αντιστοίχιση INT_MIN σε μέγιστο_άθροισμα και από το μηδέν έως τρέχον_άθροισμαΕδώ, το INT_MIN αντιπροσωπεύει την ελάχιστη ακέραια τιμή.

Βήμα 2) Στον δείκτη 0, η τιμή είναι 4. Έτσι, τρέχον_άθροισμα = 0 + 4 = 4. Εφόσον τρέχον_άθροισμα είναι μεγαλύτερο από μέγιστο_άθροισμα, μέγιστο_άθροισμα γίνεται 4.

Παράδειγμα του αλγορίθμου Kadane βήμα 2

Βήμα 3) Στον δείκτη 1, η τιμή είναι -2. Έτσι, τρέχον_άθροισμα = 4 + (-2) = 2.

Αυτή τη φορά τρέχον_άθροισμα είναι λιγότερο από μέγιστο_άθροισμαΩς αποτέλεσμα, η αξία του μέγιστο_άθροισμα δεν ενημερώνεται.

Παράδειγμα του αλγορίθμου Kadane βήμα 3

Βήμα 4) Η επόμενη τιμή είναι 1. Προσθέτοντάς την στο τρέχον_άθροισμα δίνει 3. Δεδομένου ότι μέγιστο_άθροισμα (4) είναι ακόμα μεγαλύτερο από τρέχον_άθροισμα, μέγιστο_άθροισμα δεν ενημερώνεται.

Παράδειγμα του αλγορίθμου Kadane βήμα 4

Βήμα 5) Στον δείκτη 3, η τιμή είναι 3. Αύξηση τρέχον_άθροισμα κατά 3 δίνει τρέχον_άθροισμα = 6.

Παράδειγμα του αλγορίθμου Kadane βήμα 5

Στην περίπτωση αυτή, μέγιστο_άθροισμα είναι μικρότερο από τρέχον_άθροισμα, Οπότε μέγιστο_άθροισμα ενημερώνεται με την τιμή του τρέχον_άθροισμα.

Βήμα 6) Για το τελευταίο στοιχείο του πίνακα, έχουμε -1. Προσθέτοντάς το στο τρέχον_άθροισμα δίνει 5, το οποίο είναι μικρότερο από μέγιστο_άθροισμα. Ετσι, μέγιστο_άθροισμα παραμένει 6.

Παράδειγμα του αλγορίθμου Kadane βήμα 6

Καθώς φτάσαμε στο τέλος του πίνακα, ο αλγόριθμος τελειώνει εδώ. Τώρα, μέγιστο_άθροισμα περιέχει το μέγιστο άθροισμα, το οποίο είναι 6. Ο υποπίνακας είναι {4, -2, 1, 3}.

Παρατσούκλι Code για τον Αλγόριθμο του Kadane

function KadaneAlgorithm():
    input: array
    maximum_sum, current_sum = 0
    for each element in array:
        add the element with current_sum
        if current_sum is greater than the maximum_sum
            then maximum_sum = current_sum
        if current_sum is less than the element
            then current_sum = element
    return the value of maximum_sum

C++ Υλοποίηση του αλγορίθμου Kadane

#include <iostream>
using namespace std;
void kadane(int array[], int n) {
    int current_sum = 0;
    int max_sum = -1e9;
    // -1e9 means -1,000,000,000
    for (int i = 0; i < n; i++) {
        current_sum += array[i];
        if (max_sum < current_sum) {
            max_sum = current_sum;
        }
        if (current_sum < array[i]) {
            current_sum = array[i];
        }
    }
    cout << "largest sum is " << max_sum << endl;
}
int main() {
    int array[] = {-10, 5, 1, 6, -9, 2, -7, 3, -5};
    kadane(array, sizeof(array) / sizeof(array[0]));
}

Παραγωγή:

largest sum is 12

Python Υλοποίηση του αλγορίθμου Kadane

def kadane(numbers):
    current_sum = 0
    max_sum = -1e9
    for i in range(len(numbers)):
        current_sum += numbers[i]
        if max_sum < current_sum:
            max_sum = current_sum
        if current_sum < numbers[i]:
            current_sum = numbers[i]
    print("largest sum is ", max_sum)

kadane([-10, 5, 1, 6, -9, 2, -7, 3, -5])

Παραγωγή:

largest sum is 12

Ανάλυση πολυπλοκότητας για το μεγαλύτερο συνεχόμενο υποσύστημα αθροίσματος

Η απλή προσέγγιση χρησιμοποιεί δύο βρόχους για να υπολογίσει κάθε πιθανό άθροισμα υποπίνακα και να εντοπίσει το μεγαλύτερο. Είναι μια προσέγγιση ωμής βίας· κάθε βρόχος εκτελείται μέχρι το τέλος του παράταξη, δίνοντας O(N²) χρόνο.

Ο αλγόριθμος του Kadane χρησιμοποιεί μόνο έναν βρόχο, δίνοντας χρόνο O(N) και επιπλέον χώρο O(1). Σε έναν πίνακα 100 στοιχείων, η απλή προσέγγιση εκτελεί 100 × 100 = 10,000 πράξεις, ενώ ο αλγόριθμος του Kadane εκτελεί μόνο 100 — μια δραματική επιτάχυνση για μεγάλες εισόδους.

Συχνές Ερωτήσεις

Ο αλγόριθμος του Kadane στηρίζει τη μηχανική χαρακτηριστικών AI για δεδομένα χρονοσειρών, ανίχνευση παραθύρων ανωμαλιών και reward-shaping στην ενισχυτική μάθηση, helping Τα μοντέλα εντοπίζουν το ισχυρότερο διάστημα θετικού αθροίσματος σε θορυβώδη σήματα.

Ναι. Το GitHub Copilot και το GPT εξάγουν αξιόπιστα τον αλγόριθμο του Kadane σε Python, C++και Java, συμπεριλαμβανομένων παραλλαγών που επιστρέφουν τους δείκτες έναρξης και λήξης του νικητήριου υποπίνακα.

Ο αλγόριθμος του Kadane εκτελείται σε χρόνο O(N) και βοηθητικό χώρο O(1) επειδή κάνει ένα μόνο πέρασμα tracβασιλιάς μόνο ένα τρέχον άθροισμα και μια καλύτερη μέχρι στιγμής τιμή.

Αρχικοποιήστε το max_sum στο πρώτο στοιχείο ή στο αρνητικό άπειρο αντί για το μηδέν. Ο αλγόριθμος επιστρέφει στη συνέχεια το λιγότερο αρνητικό στοιχείο, το οποίο είναι η σωστή απάντηση.

Συνήθεις χρήσεις είναι τα παράθυρα κέρδους αγοράς-πώλησης μετοχών, τα αθροίσματα πλεονεκτημάτων εικόνας, τα διαστήματα βαθμολόγησης γονιδιωματικής και η ανάλυση οικονομικού κινδύνου, όπου το καλύτερο παράθυρο συνεχούς απόδοσης έχει τη μεγαλύτερη σημασία.

Tracka προσωρινό δείκτη έναρξης κάθε φορά που το current_sum επαναφέρεται στο τρέχον στοιχείο. Όταν το max_sum ενημερώνεται, καταγράψτε τους δείκτες έναρξης και λήξης, ώστε ο υποπίνακας απάντησης να μπορεί να τεμαχιστεί στο τέλος.

Η μέθοδος "Διαίρει και βασίλευε" λύνει τον μέγιστο υποπίνακα σε O(N log N) συνδυάζοντας αριστερά, δεξιά και διασταυρούμενα αθροίσματα. Ο αλγόριθμος του Kadane είναι ταχύτερος σε O(N) και ευκολότερος στον κώδικα.

Ναι. Το Kadane είναι ένα κανονικό παράδειγμα δυναμικού προγραμματισμού με κατάσταση O(1), όπου κάθε νέο μέγιστο που τελειώνει στον δείκτη i εξαρτάται από το μέγιστο που τελειώνει στον δείκτη i μείον ένα συν το τρέχον στοιχείο.

Συνοψίστε αυτήν την ανάρτηση με: