Algoritmo di Kadence: sottoarray contiguo a somma più grande

⚡ Riepilogo intelligente

L'algoritmo di Kadane trova la più grande somma di sottoarray contigui in tempo lineare tracinvece di analizzare ogni possibile sotto-array, si ottiene un massimo progressivo. Questo classico trucco della programmazione dinamica è alla base dei problemi relativi a titoli azionari, finanza e segnali.

  • 🎯 Definizione del problema: Un sottoarray contiguo è una sequenza di elementi consecutivi; l'obiettivo è trovare il sottoarray con la somma aritmetica più alta all'interno di un array misto di elementi positivi e negativi.
  • ???? Forza bruta: Due cicli annidati valutano ogni indice di inizio e fine in tempo O(N²) e stampano la finestra vincente utilizzando i marcatori di inizio e fine.
  • Il punto di vista di Kadane: Reimposta la somma progressiva ogni volta che l'elemento corrente batte l'accumulatore, mantieniping solo il prefisso migliore che potrebbe ancora evolversi nella risposta.
  • 🧭 Esempio pratico: Una breve analisi di un array con valori negativi mostra come max_sum e current_sum si evolvono passo dopo passo fino a quando non viene catturato il vero valore massimo.
  • 💻 Copertura linguistica: Entrambi i progetti editoriali di C++ and Python Le implementazioni dell'approccio semplice e dell'algoritmo di Kadane dimostrano la transizione da un tempo O(N²) a un tempo O(N).
  • 📊 Complessità: L'algoritmo di Kadane viene eseguito in tempo O(N) con spazio aggiuntivo O(1), superando nettamente il metodo di base a forza bruta su array di input di grandi dimensioni.

Algoritmo di Kadane Somma più grande Sottoarray contiguo

Qual è la somma massima di un sottoarray contiguo?

Un sottoarray è una parte continua di un array. Può essere un singolo elemento di un array o una frazione dell'array. Il sottoarray contiguo con la somma più grande indica un sottoarray che ha il valore della somma massima.

Ad esempio, si consideri l'array {-10, 5, 1, 6, -9, 2, -7, 3, -5}. I suoi sottoarray possono essere {-10, 5, 1, 6}, {5, 1, 6}, oppure {2, -7, 3, -5}, e così via. Tuttavia, {5, 1, 6, 3} non può essere un sottoarray perché gli elementi non sono in sequenza contigua.

Sottoarray contiguo con somma più grande

Come potete notare, tra tutti i sottoarray, quello evidenziato {5, 1, 6} ha il valore di somma massimo:

Sottoarray contiguo con la somma maggiore evidenziato

La somma della sotto-matrice {5, 1, 6} è 12, la somma massima tra tutte le possibili sotto-matrici della matrice sopra riportata. Pertanto, per questa matrice, la sotto-matrice contigua con somma massima è {5, 1, 6}.

Un approccio semplice per risolvere il problema della somma massima in sottoarray contigui

Il modo più semplice per risolvere questo problema è utilizzare due cicli per trovare tutti i sottoarray, calcolare la somma e quindi trovare il suo valore massimo.

Ecco il diagramma di flusso per il metodo semplice per trovare la sotto-matrice contigua con la somma maggiore. Si tratta di un approccio di forza bruta, in quanto si esaminano tutte le possibili sotto-matrici.

Approccio semplice per risolvere la somma più grande

Ecco i semplici passaggi per farlo.

Passo 1) Inizializzare somma massima con il valore intero minimo e impostato iniziare and fine a zero.

Passo 2) lasciare i and j siano gli indici dell'array dove j è più grande di O uguale a i; i segna l'inizio del sottoarray e j la sua fine.

Passo 3) somma_attuale contiene la somma progressiva. Dopo ogni aggiornamento, controlla se somma_attuale è maggiore somma massima.

Passo 4) If somma_attuale è maggiore, sostituire somma massima con esso.

Passo 5) Quando j raggiunge la fine dell'array, incrementa i e ripristina somma_attuale a 0.

Passo 6) Ripeti fino al i raggiunge la fine dell'array. somma massima quindi detiene la somma del sottoarray più grande.

Soprannome Code per un approccio semplice

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

C++ Attuazione dell'approccio semplice

#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]));
}

Produzione:

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

Python Attuazione dell'approccio semplice

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)

Produzione:

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

Algoritmo di Kadane per trovare la sotto-matrice contigua con la somma maggiore

L'algoritmo di Kadane è un metodo di programmazione dinamica che utilizza un singolo ciclo anziché due. Gestisce array con numeri misti positivi e negativi, purché almeno un valore sia non negativo.

Per trovare la sotto-matrice contigua con la somma maggiore, ci bastano due variabili. Ecco il diagramma di flusso:

Algoritmo di Kadane per trovare la somma più grande

Ecco i passaggi per l'algoritmo di Kadane:

Passo 1) Crea due variabili, somma_attuale and somma massima.

somma_attuale mantiene la somma massima che termina in uno specifico indice dell'array, mentre somma massima memorizza il valore di somma più alto osservato finora.

Passo 2) Aggiungi ogni elemento dell'array a somma_attualeQuindi, verifica le due condizioni seguenti:

  • If somma_attuale è minore dell'elemento corrente, quindi somma_attuale diventa l'elemento corrente.
  • If somma massima è meno di somma_attuale, poi somma massima diventa somma_attuale.

Passo 3) Dopo aver ripetuto il passaggio precedente per l'intero array, somma massima detiene la somma più grande del sottoarray contiguo.

Esempio dell'algoritmo di Kadane

Dimostriamo l'algoritmo di Kadane su un array di piccole dimensioni e analizziamo passo passo ogni fase del processo per trovare il sottoarray contiguo con la somma maggiore.

Supponiamo che l'array dato sia del tipo seguente:

Esempio dell'algoritmo di Kadane

Ecco i passaggi dell'algoritmo di Kadane:

Passo 1) Crea due variabili, somma_attuale and somma massima. Assegna INT_MIN a somma massima e da zero a somma_attualeQui, INT_MIN rappresenta il valore intero minimo.

Passo 2) All'indice 0, il valore è 4. Quindi, somma_attuale = 0 + 4 = 4. Poiché somma_attuale è più grande di somma massima, somma massima diventa 4.

Esempio del passaggio 2 dell'algoritmo di Kadane

Passo 3) All'indice 1, il valore è -2. Quindi, somma_attuale = 4 + (-2) = 2.

Stavolta somma_attuale è meno di somma massima. Di conseguenza, il valore di somma massima non è aggiornato.

Esempio del passaggio 3 dell'algoritmo di Kadane

Passo 4) Il valore successivo è 1. Aggiungendolo a somma_attuale dà 3. Poiché somma massima (4) è ancora maggiore di somma_attuale, somma massima non è aggiornato.

Esempio del passaggio 4 dell'algoritmo di Kadane

Passo 5) All'indice 3, il valore è 3. Incremento somma_attuale da 3 dà somma_attuale = 6.

Esempio del passaggio 5 dell'algoritmo di Kadane

In questo caso, somma massima è più piccolo di somma_attuale, Così somma massima viene aggiornato con il valore di somma_attuale.

Passo 6) Per l'ultimo elemento dell'array, abbiamo -1. Aggiungendolo a somma_attuale dà 5, che è più piccolo di somma massima. Così, somma massima rimane 6.

Esempio del passaggio 6 dell'algoritmo di Kadane

Poiché abbiamo raggiunto la fine dell'array, l'algoritmo termina qui. Ora, somma massima contiene la somma massima, che è 6. La sotto-matrice è {4, -2, 1, 3}.

Soprannome Code per l'algoritmo di 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++ Implementazione dell'algoritmo di 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]));
}

Produzione:

largest sum is 12

Python Implementazione dell'algoritmo di 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])

Produzione:

largest sum is 12

Analisi della complessità per il sottoarray contiguo della somma più grande

L'approccio semplice utilizza due cicli per calcolare ogni possibile somma di sottoarray e individuare quella più grande. È un approccio di forza bruta; ogni ciclo viene eseguito fino alla fine del schieramento, Dando O(N²) tempo.

L'algoritmo di Kadane utilizza un solo ciclo, offrendo un tempo O(N) e uno spazio aggiuntivo O(1). Su un array di 100 elementi, l'approccio semplice esegue 100 × 100 = 10,000 operazioni, mentre quello di Kadane ne esegue solo 100, un notevole incremento di velocità per input di grandi dimensioni.

DOMANDE FREQUENTI

L'algoritmo di Kadane è alla base dell'ingegneria delle caratteristiche AI ​​per i dati delle serie temporali, il rilevamento delle finestre di anomalia e la condivisione delle ricompense.ping nell'apprendimento per rinforzo, aiutaping I modelli individuano l'intervallo a somma positiva più forte nei segnali rumorosi.

Sì. GitHub Copilot e GPT producono in modo affidabile l'algoritmo di Kadane in Python, C++e Java, comprese le varianti che restituiscono gli indici di inizio e fine del sottoarray vincente.

L'algoritmo di Kadane viene eseguito in tempo O(N) e spazio ausiliario O(1) perché effettua un singolo passaggio tracre solo una somma progressiva e un valore massimo raggiunto finora.

Inizializza max_sum al primo elemento o a meno infinito invece che a zero. L'algoritmo restituirà quindi l'elemento meno negativo, che è la risposta corretta.

Gli impieghi più comuni includono finestre di profitto per l'acquisto e la vendita di azioni, somme dei bordi delle immagini, intervalli di punteggio genomico e analisi del rischio finanziario, dove la finestra di rendimento contigua ottimale è di fondamentale importanza.

Tracka è un indice di inizio temporaneo che viene utilizzato ogni volta che current_sum viene reimpostato sull'elemento corrente. Quando max_sum viene aggiornato, vengono acquisiti gli indici di inizio e fine in modo che il sottoarray di risultati possa essere suddiviso alla fine.

Il metodo divide et impera risolve il problema del sottoarray massimo in O(N log N) combinando somme a sinistra, a destra e incrociate. L'algoritmo di Kadane è più veloce, con complessità O(N), ed è più facile da implementare.

Sì. L'esempio di Kadane è un esempio canonico di programmazione dinamica con O(1) stato, dove ogni nuovo massimo che termina all'indice i dipende dal massimo che termina all'indice i meno uno più l'elemento corrente.

Riassumi questo post con: