Algoritmo de Kadence: Subarranjo Contíguo de Maior Soma

Qual é a maior submatriz contígua de soma?

Um subarray é uma parte contínua de um array. Pode ser um único elemento de uma matriz ou alguma fração da matriz. A submatriz contígua de maior soma significa uma submatriz que possui o valor de soma máximo.

Por exemplo, uma matriz é {-10, 5, 1, 6, -9, 2, -7, 3, -5}. Suas submatrizes podem ser: {-10,5,1,6} ou {5,1,6} ou {2,7,3, -5} etc. Mas {5,1,6,3} não pode ser uma subarray porque eles não estão mantendo as sequências.

Subarray Contíguo de Maior Soma

Se você notar, entre todos os subarranjos, o seguinte subarranjo destacado (5,1,6) tem o valor máximo de soma:

Subarray Contíguo de Maior Soma

A soma do subarray {5,1,6} = 11, é a soma máxima em todas as combinações possíveis de subarray do array acima. Portanto, para a matriz acima, a submatriz máxima é {5,1,6}.

Algoritmo de Kadence: Subarranjo Contíguo de Maior Soma

Abordagem simples para resolver o subarranjo contíguo de maior soma

A maneira simples de resolver esse problema é usar dois loops para encontrar todas as submatrizes, calcular a soma e então encontrar seu valor máximo.

Aqui está o fluxograma para a abordagem simples para encontrar a submatriz contígua de maior soma. Esta é uma abordagem de força bruta, pois examinamos todos os subarranjos possíveis.

Abordagem simples para resolver a maior soma

Aqui estão as etapas simples para fazer isso.

Passo 1) Inicialize max_sum com valor inteiro mínimo e atribua as variáveis ​​“begin” e “end” com zero.

Passo 2) Sejam i e j o índice do array, onde “j” é maior que igual a “i”. Ele representa o índice inicial da submatriz e “j” representa o índice final da submatriz.

Passo 3) “Current_sum” conterá a soma do subarray. Após calcular a soma atual, verifique se current_sum é maior que max_sum.

Passo 4) Se current_sum for maior, substitua max_sum pela soma atual.

Passo 5) Verifique se “j” chega ao final do array ou não. Se “j” atingir o final do array, aumente “i” e altere o valor current_sum para 0.

Passo 6) Execute todas essas etapas, até que “i” chegue ao final do array.

Passo 7) No final desses dois loops, o max_sum conterá a maior soma do subarray.

Pseudocódigo para abordagem simples

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

C++ Implementação de abordagem simples

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

Saída:

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

Python Implementação de abordagem simples

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)

Saída:

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

Algoritmo de Kadane para encontrar o subarranjo contíguo de maior soma

O Algoritmo de Kadane é uma espécie de método de “Programação Dinâmica”. Aqui usaremos um loop em vez de dois loops. A implementação geral do Algoritmo de Kadane funciona apenas para matrizes de números positivos.

Precisamos apenas de duas variáveis ​​para encontrar o subarranjo contíguo de maior soma. Aqui está o fluxograma do Algoritmo de Kadane:

Algoritmo de Kadane para encontrar a maior soma

Aqui estão as etapas para o Algoritmo de Kadane:

Passo 1) Crie duas variáveis, current_sum e max_sum.

“Current_sum” manterá o valor da soma máxima que termina em um índice de array específico, enquanto “max_sum” armazenará o valor máximo da soma até o momento.

Passo 2) Adicionaremos o valor com current_sum para cada elemento do array. Então verificaremos duas condições abaixo:

  • Se current_sum for menor que o elemento atual, então o valor current_sum será o elemento atual.
  • Se max_sum for menor que current_sum, então max_sum será current_sum.

Passo 3) Realizando a etapa anterior para todo o array, teremos o subarray contíguo de maior soma na variável “max_sum”.

Exemplo de Algoritmo de Kadane

Demonstraremos o algoritmo de Kadanes com um array de tamanho pequeno e discutiremos cada etapa para encontrar o subarray contíguo de maior soma.

Vamos supor que o array fornecido seja semelhante ao seguinte:

Exemplo de Algoritmo de Kadane

Aqui estão as etapas do Algoritmo de Kadane:

Passo 1) Crie duas variáveis, current_sum e max_sum. Atribua INT_MIN ao max_sum e zero ao current_sum. (Aqui, INT_MIN significa o número inteiro mínimo).

Passo 2) No índice 0, o valor é 4. Portanto, current_sum = 0 + 4 ou 4. Aqui current_sum é maior que max_sum, max_sum será 4.

Exemplo de Algoritmo de Kadane

Passo 3) No índice 1, o valor é -2. Portanto, soma_atual = 4 + (-2) ou 2.

Desta vez, current_sum é menor que max_sum. Como resultado, o valor de max_sum não será atualizado.

Exemplo de Algoritmo de Kadane

Passo 4) O próximo valor é 1. Se somarmos isso com a soma_atual, então a soma_atual será 3. Ainda assim, a soma_max é maior que a soma_atual. Portanto, max_sum não será atualizado.

Exemplo de Algoritmo de Kadane

Passo 5) No índice 3, o valor é três. Atualizaremos o valor incrementando a soma_atual em 3. Portanto, a soma_atual será 6.

Exemplo de Algoritmo de Kadane

Neste caso, max_sum é menor que current_sum. Portanto, max_sum será atualizado com o valor de current_sum.

Passo 6) Para o último elemento do array, temos -1. Se adicionarmos isso à soma_atual, a soma_atual será 5, que é menor que a soma_max. Portanto, max_sum permanecerá 6.

Exemplo de Algoritmo de Kadane

Quando chegamos ao final do array, o algoritmo termina aqui. Agora, “max_sum” contém o subarray de soma máxima. Qual é 5. A submatriz é {4,-2,1,3}.

Pseudocódigo para o algoritmo de Kadane

function KadaneAlgorithm():
    input: array
    maximum_sum, current_sum = 0
    for each elements 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++Implementação do Algoritmo de Kadane

#include < iostream >
using namespace std;
void kadane(int array[], int n) {
  int current_sum = 0;
  int max_sum = -1e9;
  // -1e9 means -10000000
  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]));
}

Saída:

largest sum is 12

Python Implementação do Algoritmo de 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])

Saída:

largest sum is 12

Análise de complexidade para a maior submatriz contígua de soma

A abordagem simples usa dois loops. Esse método calcula todas as somas possíveis de submatrizes para encontrar a maior delas. É uma abordagem de força bruta. Cada loop é executado até o final do ordem.

Se uma matriz tiver um total de N elementos, então usando dois loops, passaremos por N2 elementos. Como resultado, a complexidade de tempo para uma abordagem simples para encontrar a maior soma de submatrizes contíguas será O(N2). Aqui, “O” significa a função de complexidade.

Por outro lado, o Algoritmo de Kadane é o método de Programação Dinâmica para encontrar a submatriz de soma contígua máxima. Se você seguir o exemplo ou o código, verá que estamos usando apenas um loop.

Como resultado, se a matriz de entrada tiver um tamanho de N, então a complexidade de tempo do algoritmo de Kadane será O(N). Isso é mais rápido do que a abordagem simples. Por exemplo, uma matriz contendo 100 elementos. A abordagem simples levará 100*100 ou 10,000 tempo de CPU. Mas o Algoritmo de Kadane levará apenas 100 CPUs.