Как решить «максимальный подмассив фиксированного размера», используя подход «разделяй и властвуй»?

#algorithm #divide-and-conquer

#алгоритм #разделяй и властвуй

Вопрос:

Отказ от ответственности:Я знаю, что эта проблема может быть решена с помощью одного прохода массива очень эффективно, но я заинтересован в том, чтобы сделать это с помощью «разделяй и властвуй», потому что это немного отличается от типичных проблем, которые мы решаем с помощью «разделяй и властвуй».

Предположим, вам предоставлен массив с плавающей запятой X [1: n] размером n и длиной интервала l. Проблема заключается в разработке алгоритма «разделяй и властвуй» для нахождения подмассива длины l из массива с максимальной суммой.

Вот что я придумал.Для массива длиной n существует n-l 1 подмассивы из l последовательных элементов. Например, для массива длиной n = 10 и l = 3 будет 8 подмассивов длиной 3.

Теперь, чтобы разделить проблему на две половины, я решил разбить массив на n-l 1/2, чтобы равное количество подмассивов было распределено на обе половины моего деления, как показано в алгоритме ниже. Опять же, для n = 10, l = 3, n-l 1 = 8, поэтому я разделил проблему на (n-l 1) / 2 = 4. Но для 4-го подмассива мне нужны элементы массива до 6, т.Е. (n l-1) /2.

 void FixedLengthMS(input: X[1:n], l, output: k, max_sum)
{
   if(l==n){//only one sub-array
      sum = Sumof(X[1:n]);
      k=1;
   }
   int kl, kr;
   float sum_l, sum_r;
   FixedLengthMS(X[1:(n l-1)/2], l, kl, sum_l);
   FixedLengthMS(X[(n-l 3)/2:n], l, kr, sum_r);

   if(sum_l >= sum_r){
      sum = sum_l;
      k = kl;
   }
   else{
      sum = sum_r;
      k = n-l 1/2   kr;
   }
}
  

Примечание: чтобы очистить индексацию массива
для подмассива, начинающегося с (n-l 1) / 2, нам нужны элементы массива до (n-l 1) / 2 l-1 = (n l-1) / 2

Моя проблема: для применения «разделяй и властвуй» я использовал некоторые элементы данных в обоих массивах, поэтому я ищу другой метод, который позволяет избежать дополнительного хранилища.

Более быстрый метод будет оценен по достоинству.

Пожалуйста, игнорируйте синтаксис раздела кода, я просто пытаюсь дать обзор алгоритма.

Комментарии:

1. Хотя исходная проблема с максимальным подмассивом на самом деле может быть решена с помощью D amp; C (выполнение этого включает вычисление для любого заданного интервала не только максимального подмассива в этом интервале, но и максимального подмассива, начинающегося с левого края интервала, и максимального подмассива, заканчивающегося на правом краю; затем родительскийпроблема может вычислить свои ответы на эти 3 вопроса, используя 3 3 = 6 ответов из своих 2 подзадач), этот вариант (т. Е., Где Длина l фиксирована) проблема плохо подходит для D amp; C. Я не понимаю, как возможен алгоритм D amp; C в режиме O (n), если вы не ограничите l значением o (n).

Ответ №1:

Вам не нужно разделять и властвовать. Для этой задачи можно использовать простой однопроходный алгоритм. Предположим, что массив достаточно большой. Затем:

 double sum = 0;
for (size_t i = 0; i < l;   i)
    sum  = X[i];

size_t max_index = 0;
double max_sum = sum;

for (int i = 0; i < n - l;   i) {
    sum  = X[i   l] - X[i];
    if (sum > max_sum) {
        max_sum = sum;
        max_index = i;
    }
}
  

Комментарии:

1. Я знаю, я могу сделать это за один проход массива. Я просто хотел знать, как это сделать, используя подход «разделяй и властвуй». В любом случае спасибо за ответ 🙂

2. @BibekBhattarai когда вы сказали, что максимальный подмассив фиксированного размера, вы имеете в виду, что задан размер l, где l