Найти интервал, на котором сумма максимальная

NightBomber
Дата: 21.09.2017 00:24:10
Всем привет.

Помогите с азимутом поиска задачю. Даже не знаю, как соотв-щая область математики зовётся.
В общем есть временной интервал и для каждого момента времени - результат вычисления некоторой ф-ции:
time07:0007:0507:1007:1507:2007:2507:3007:3507:4007:4507:5007:55
func-1917123-812-11-21311-101

Требуется найти такую часть этого интервала, на котором сумма результатов ф-ции будет максимальной.
Часть интервала может содержать от 1 до N элементов и может начинаться / заканчиваться на любом из них.

Как такое решать ? Неужели только тупым перебором ?
NightBomber
Дата: 21.09.2017 00:35:29
Отбой, кажись. Нарыл, что это такое:

https://en.wikipedia.org/wiki/Maximum_subarray_problem

Буду теперь осиливать алгоритмы.
YuRock
Дата: 21.09.2017 01:04:40
NightBomber
Неужели только тупым перебором ?
Даже не представляю, как по-другому можно получить суммы всех интервалов, чтобы сравнить их.
В один проход делается ведь (в двух циклах).
NightBomber
Дата: 21.09.2017 01:25:38
Наивный перебор - это O(n^3). А умные люди, оказывается, давно нашли алгоритмы со сложностью O(n).

http://e-maxx.ru/algo/maximum_average_segment
http://rosettacode.org/wiki/Greatest_subsequential_sum#Python
Barlone
Дата: 21.09.2017 07:08:06
NightBomber
Всем привет.

Помогите с азимутом поиска задачю. Даже не знаю, как соотв-щая область математики зовётся.
В общем есть временной интервал и для каждого момента времени - результат вычисления некоторой ф-ции:
timet07:00t07:05t07:10t07:15t07:20t07:25t07:30t07:35t07:40t07:45t07:50t07:55
funct-19t17t1t23t-8t12t-11t-2t13t11t-10t1

Требуется найти такую часть этого интервала, на котором сумма результатов ф-ции будет максимальной.
Часть интервала может содержать от 1 до N элементов и может начинаться / заканчиваться на любом из них.

Как такое решать ? Неужели только тупым перебором ?
Двигаясь с левого края, суммируем. Если сумма стала отрицательной, обнуляем ее, и левый край интервала сдвигаем на следующий элемент. Запоминаем, на каком интервале сумма достигла максимума. Вроде в один проход получается.
leftmax=0; rightmax=0; summax=0;
left=0; sum=0;
for(right=0; right<N; ++right)
{
  sum += arr[right];
  if (sum > summax) 
  {
     summax = sum;
     leftmax = left;
     rightmax = right;
  }
  if (sum < 0)
  {
     sum = 0;
     left = right+1;
  }
}

Вот примерно так
Akina
Дата: 21.09.2017 07:38:35
Сворачиваете массив данных, суммируя соседние данные одного знака. Исходный массив
time7:007:057:107:157:207:257:307:357:407:457:50
func-1917123-812-11-21311-10

преобразуется в
time7:007:05-7:157:207:257:30-7:357:40-7:457:50
func-1941-812-1324-10

Следующий этап свёртки такой: Если абс. значение отрицательного элемента меньше значения каждого из положительных соседей - эти три элемента сворачиваются в один (само собой, краевые отрицательные алгоритм игнорирует, у них нет одного из соседей). Массив преобразуется в
time7:007:05-7:257:30-7:357:40-7:457:50
func-194511-10-10

Этот этап повторяется до тех пор, пока не кончатся группы, пригодные к свёртке.

Осталось выбрать максимальное положительное значение, в данном случае это интервал 7:05-7:25 и сумма 45.
Akina
Дата: 21.09.2017 07:47:17
Пардон, ошибка от невнимательности. Вот правильный вариант:

Сворачиваете массив данных, суммируя соседние данные одного знака. Исходный массив
time7:007:057:107:157:207:257:307:357:407:457:50
func-1917123-812-11-21311-10

преобразуется в
time7:007:05-7:157:207:257:30-7:357:40-7:457:50
func-1941-812-1324-10

Следующий этап свёртки такой: Если абс. значение отрицательного элемента меньше значения каждого из положительных соседей - эти три элемента сворачиваются в один (само собой, краевые отрицательные алгоритм игнорирует, у них нет одного из соседей). Этап повторяется, пока возможно.

На первом шаге массив
time7:007:05-7:157:207:257:30-7:357:40-7:457:50
func-1941-812-1324-10

преобразуется в
time7:007:05-7:257:30-7:357:40-7:457:50
func-1945-1324-10

Возможен ещё один шаг этапа, он даёт
time7:007:05-7:457:50
func-1956-10

Ответ: интервал 7:05-7:45, сумма 56.
982183
Дата: 21.09.2017 10:18:29
Почему сворачиваем?
Надо разворачивать.
В N раз.

Лет 20 назад вставала такая практическая задача.
Только диапазон был не дискретный.
Не помню как решали...
982183
Дата: 21.09.2017 10:19:33
сории. понял задачу ствертки.
982183
Дата: 21.09.2017 10:21:27
Akina
Осталось выбрать максимальное положительное значение, в данном случае это интервал 7:05-7:25 и сумма 45.

Но это при N>=3
А если N=2 ?