Nano Hash - криптовалюты, майнинг, программирование

Как найти алгоритм: задан массив целых чисел, какова максимальная сумма подмножества целых чисел, такого что

Для заданного массива целых чисел какова максимальная сумма подмножества целых чисел, при котором целые числа в подмножестве изначально не были рядом друг с другом?

Примеры:

[3, 8, 4] => max sum is 8, since 8 > (3+4)
[12, 8, 9, 10] => max sum is 12 + 10 = 22, since this is greater than 12 + 9 and 8 + 10

Я заинтересован в выяснении алгоритма для этого. Методология / мыслительный процесс = высоко ценится.

РЕДАКТИРОВАТЬ: Целые числа варьируются от 1 до 1000 включительно. (Поскольку это полностью учебное упражнение, мне все равно было бы интересно узнать о различных методах, если бы целые числа находились в диапазоне, скажем, от -1000 до 1000.)

04.11.2011

  • Целые числа также могут иметь отрицательные значения? 04.11.2011
  • Очень похожую задачу (с решением) можно найти, погуглив не максимальную сумму отрезка. Это есть в книге под названием Pearls of Functional Algorithm Design. Попробуйте изменить решение, чтобы решить вашу проблему 04.11.2011
  • @webclectic Я обновляю свой ответ. 05.11.2011

Ответы:


1

Пусть у вас есть массив A {Ai, 1 <= i <= n }

F(i) - Максимальная сумма подмассива Aj { 1 <= j <= i }, тогда

F(0) = 0 - пустой подмассив

F(1) = A(1) - только первый элемент

F(i) = max(F(i-2) + A(i), F(i-1)) , 2 <= i <= n

F(n) - ответ

Реализация С++:

int GetMaximumSubarraySum(const vector<int>& a)
{
    // note that vector a have 1-based index
    vector<int> v(a.size());
    v[0] = 0;
    v[1] = a[1];
    for(int i =2; i < a.size(); i++)
        v[i] = max(v[i-2] + a[i], v[i-1]);

    return v.back();
}

Пояснение:

Во-первых, основная идея заключается в использовании динамического программирования. Мы пытаемся решить задачу для массива с N элементом, используя известный ответ для массива с N-1 и N-2 первыми элементами. Если N = 0, ответ 0, а если N = 1, ответ A[1]. Ясно. Для N >= 2 у нас есть 2 разных способа:

  1. Используйте элемент A[N],, тогда ответ будет A[N] + F[N-2] (поскольку мы не можем использовать элемент A[N-1], а F[N-2] является лучшим решением для подмассива 1..N-2, нас не волнует, используется элемент F[N-2] или нет, это просто лучшее решение для подмассива 1..N-2.

  2. Не используйте элемент A[N], тогда ответ будет F[N-1] (потому что мы можем использовать элемент A[N-1], а F[N-1] — лучшее решение для подмассива 1..N-1, также нас не волнует, используется элемент F[N-1] или нет.

Итак, нам нужно получить максимум из этих двух ситуаций. Для решения задачи нужно посчитать F[N] в порядке возрастания и запомнить ответы.

Посмотрим на вашем примере:

[12, 8, 9, 10]

F[0] = 0

F[1] = 12 - использовать 1-й элемент

F[2] = max(F[0]+A[2], F[1]) = max(8, 12) = 12 - использовать 1-й элемент

F[3] = max(F[1]+A[3], F[2]) = max(21, 12) = 21 - использовать 1-й, 3-й элемент

F[4] = max(F[2]+A[4], F[3]) = max(22, 21) = 22 - использовать 1-й, 4-й элемент

Ответ F[4] = 22.

04.11.2011
  • Не могли бы вы добавить больше деталей/комментариев, чтобы объяснить этот метод? Существует ли всеобъемлющая идея, которую можно применить к множеству проблем? 09.11.2011
  • @daze, см. отредактированный ответ. Я пытаюсь объяснить, но мой английский не очень хорош( 09.11.2011
  • Ничего себе, это невероятно - и действительно полезно. Большое спасибо! Теперь я вижу трюк с алгоритмом... динамическое программирование изящно. По сути, мне нужно подумать о создании специального массива для хранения максимальных значений, F[i], который сообщает мне максимальное значение подмассива данного массива, A, из A 1-е значение к его ith значению. :) Кажется, теперь я это понял... теперь я попробую написать для него код разными способами. Индекс на основе 1 тоже интересен. Я привык к индексам, начинающимся с 0. 10.11.2011

  • 2

    Единственный известный мне одинаково успешный мыслительный процесс — это увидеть проблему раньше. Глядя на ваш вопрос, моей первой мыслью было: «Мне нужно максимизировать сумму с учетом того, что кажется набором довольно простых логических ограничений». В Knuth Vol 4A, раздел 7.1.4 Алгоритм B, Кнут описывает, как решить такую ​​проблему, если ограничения могут быть выражены в виде http://en.wikipedia.org/wiki/Binary_decision_diagram управляемого размера. Если у вас уже есть пакет BDD, вы можете решить целый класс проблем этого типа, просто создав BDD, описывающий ваши конкретные ограничения.

    Второй моей мыслью было отметить, что позже в том же разделе Кнут показывает связи между BDD и линейными сетями булевой логики. Учитывая это, для вашей проблемы должно быть приемлемое решение динамического программирования. Если вы ищете общую методологию для изучения, динамическое программирование — довольно хороший кандидат. В этом случае это, кажется, приводит к алгоритму, очень похожему на представленный Иваном Бенко, хотя он, кажется, работает в соответствии с предположением, поддерживаемым вашими примерными данными, что все целые числа >= 0, и это может работать для общего целые числа с еще несколькими операторами if.

    04.11.2011
  • Спасибо! Это действительно полезно. 11.11.2011

  • 3

    Думайте рекурсивно: лучший результат - максимальный из случаев - использовать первый элемент (первый в ветке рекурсии) или не использовать его в сумме.

    Лучший (i) = Макс (A [i] + Лучший (i + 2), Лучший (i + 1))

    04.11.2011

    4

    Вот решение, известное как алогитм Кадане.

    Algorithm 1 Kadane’s algorithm
       M ← 0, t ← 0
       i ← 1
       for j ← 1 to n do          
          t ← t + a[j]
          if t > M then M ← t, (x1 , x2 ) ← (i, j)           
          if t ≤ 0 then t ← 0, i ← j + 1// reset the accumulation
       end for
       output M , (x1 , x2 )
    
    04.11.2011
  • Спасибо - я не знаком с этой нотацией... но полезно знать термин "алгоритм Кадане". 11.11.2011
  • Разве алгоритм Кадане не подходит для другой задачи? en.wikipedia.org/wiki/Maximum_subarray_problem 14.11.2011
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..