Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

оптимальный алгоритм

333
15 октября 2008 года
GHopper
200 / / 28.12.2004
Здравствуйте!
Есть задачка: найти наибольшую сумму непрерывного подмассива в массиве.
Массив называется непрерывным, когда индексы его элементов следеют друг за другом ([5]=>1,[6]=>2,[7]=>3).
Например: массив (1,2,3,-4,5) - наибольшая непрерывная сумма подмассива равна 7 (сумма всех элементов массива). Для массива (1,2,3,-40,5) эта сумма будет равна 5 (сумма первых трех)

Итак, алгоритм:

Слишком тупой:
Код:
$maxSum = 0;

for ($i=0;$i<count($inputArray);$i++) {
  for ($ii=count($inputArray);$ii>0;$ii--) {
    $sum = 0;
    for ($iii=$i;$iii<$ii-$i;$iii++) {
      $sum += $inputArray[$iii];
    }
    if ($sum>$maxSum)
      $maxSum = $sum;
  }
}
Не самый оптимальный:
Код:
$maxSum = 0;
for ($i=0;$i<count($inputArray);$i++) {
  if (($inputArray[$i]>0) || check($i))
    $maxSum += $inputArray[$i];
  else
    break;
}

echo $maxSum;

function check($p) {
  global $inputArray;
  $sum = 0;
  for ($i=$p+1;$i<count($inputArray);$i++) {
    if (($inputArray[$i]>0) || check($i))
      $sum += $inputArray[$i];
    else
      return false;
  }
  if (abs($inputArray[$p])<$sum)
    return true
  else
    return false;
}
В один цикл:
Код:
$maxSum = 0;
$sum = null;
$n = false;
$negVal = 0;

for ($i=0;$i<count($inputArray);$i++) {
  if ($inputArray[$i]>0) {
      $sum += $inputArray[$i];
    if ($n && ($sum>0)) {
      $n = false;
      $sum = $maxSum + $sum;
    }
  }
  else {
    if (!is_numeric($sum)) {
      if ($i==0 || ($negVal< $inputArray[$i]))
        $negVal = $inputArray[$i];
    }
    else {
      if (!$n) {
        $n = true;
        $maxSum = $sum;
        $sum =  $inputArray[$i];
      }
      else
        $sum += $inputArray[$i];
    }
  }
  echo $sum."\r\n";
}
if (!is_numeric($sum))
  $maxSum = $negVal;
elseif ($maxSum<$sum)
  $maxSum = $sum;
echo $maxSum;
Но говорят, что существует еще более оптимальый алгоритм решения этой проблемы. Есть предложения?
36K
15 октября 2008 года
Alno
34 / / 23.06.2008
Что-нибудь в таком духе:

Это, если мы учитываем непрерывные пустые подмассивы. В этом случае максимальная сумма 0, если все элементы массива отрицательные, иначе равна максимальной из сумм последовательных неотрицательных элементов.

Код:
$maxSum = 0;
$curSum = 0;

for ( $inputArray as $elem ) {
   if ( $elem >= 0 ) {
      $curSum += $elem;
   } else {
      if ( $curSum > $maxSum ) {
         $maxSum = $curSum;
      }

      $curSum = 0;      
   }
}


Это, если мы не учитываем пустые непрерывные подмассивы. В этом случае сумма равна максимальному элементу, если все элементы отрицательны, иначе равна максимальной из сумм последовательных неотрицательных элементов.
Код:
$maxSum = null;
$curSum = null;

for ( $inputArray as $elem ) {
   if ( $elem >= 0 ) {
      if ( !is_numeric( $curSum ) ) {
         $curSum += $elem;
      } else {
         $curSum = $elem;
      }
   } else {
      if ( !is_numeric( $maxSum ) || $elem > $maxSum ) {
         $maxSum = $elem;
      }
      if ( is_numeric( $curSum ) && $curSum > $maxSum ) {
         $maxSum = $curSum;
      }
      $curSum = null;      
   }
}


По асимптотике быстрее, чем O(n) здесь ничего быть не может. Величина константы - вопрос открытый, но думаю, что что-то намного быстрее придумать сложно.
5
15 октября 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: GHopper
Есть задачка: найти наибольшую сумму непрерывного подмассива в массиве.
Массив называется непрерывным, когда индексы его элементов следеют друг за другом ([5]=>1,[6]=>2,[7]=>3).
Например: массив (1,2,3,-4,5) - наибольшая непрерывная сумма подмассива равна 7 (сумма всех элементов массива). Для массива (1,2,3,-40,5) эта сумма будет равна 5 (сумма первых трех)

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

14
15 октября 2008 года
Phodopus
3.3K / / 19.06.2008
Блин.. Еле врубился :)
Я так понял суть задачи - найти такие последовательные элементы массива, сумма которых была бы максимальной (сумма никаких других последовательных элементов не была бы больше найденной). Верно?
333
16 октября 2008 года
GHopper
200 / / 28.12.2004
Задача решена. http://www.rosettacode.org/wiki/Maximum_subarray.

Сам не знал, что сумма не может быть отрицательной...
14
16 октября 2008 года
Phodopus
3.3K / / 19.06.2008
Цитата: GHopper
Сам не знал, что сумма не может быть отрицательной...


А как насчет массива (-1,-2,-3,-4,-5) ???

333
16 октября 2008 года
GHopper
200 / / 28.12.2004
Цитата: Phodopus
А как насчет массива (-1,-2,-3,-4,-5) ???


А как насчет по ссылке сходить?!
"Given an array of integers, find a subarray which maximizes the sum of its elements, that is, the elements of no other single subarray add up to a value larger than this one. An empty subarray is considered to have the sum 0; thus if all elements are negative, the result must be the empty sequence."

14
16 октября 2008 года
Phodopus
3.3K / / 19.06.2008
Цитата: GHopper
А как насчет по ссылке сходить?!


Ээээ! Не грубить! При чем тут ссылка и изначально поставленное вами условие задачи?!
ПыСы. По ссылке все еще "иду". В процессе я..

9.0K
16 октября 2008 года
t-34
129 / / 30.11.2007
Цитата: GHopper
Задача решена. http://www.rosettacode.org/wiki/Maximum_subarray.

Сам не знал, что сумма не может быть отрицательной...



больше всего мне понравилась реализация на языке J...

14
16 октября 2008 года
Phodopus
3.3K / / 19.06.2008
Кстати изменив две строчки в алгоритме на C он будет работать и с "отрицательными" массивами..
5
16 октября 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: Phodopus
А как насчет массива (-1,-2,-3,-4,-5) ???


Т.е. вы хотите сказать, что операция суммирования не определена на отрицательных числах и сумма (какой кошмар) не может быть отрицательным числом?

14
17 октября 2008 года
Phodopus
3.3K / / 19.06.2008
Цитата: hardcase
Т.е. вы хотите сказать, что операция суммирования не определена на отрицательных числах и сумма (какой кошмар) не может быть отрицательным числом?


Если это ко мне, то я ничего такого сказать не хочу :) Совсем наоборот!

333
17 октября 2008 года
GHopper
200 / / 28.12.2004
Если все элементы массива отрицательный, то должен вернуться 0. Это условия задачи.
5
17 октября 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: GHopper
Если все элементы массива отрицательный, то должен вернуться 0. Это условия задачи.


Если сумма отрицательная, значит вертаем 0. ;)

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог