0/1 Рюкзак с иррациональными весами - PullRequest
4 голосов
/ 03 июня 2010

Рассмотрим задачу 0/1 о ранце . Стандартный алгоритм динамического программирования применяется только тогда, когда емкость, а также весовые коэффициенты для заполнения рюкзака являются целыми / рациональными числами. Что вы делаете, когда емкость / вес иррациональны?

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

Есть ли какой-нибудь стандартный метод решения этой проблемы? Любые комментарии по сложности этой проблемы? Любая эвристика?

А как насчет связанных повторений, таких как (например):
f(x)=1, for x< sqrt(2) <p> f(x)=f(x-sqrt(2))+sqrt(3),otherwise

Или проблема числа Пибоначчи здесь: http://www.spoj.pl/problems/PIB/?

Ответы [ 2 ]

5 голосов
/ 03 июня 2010

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

В любом случае, иногда мы можем дать действительно быстрые алгоритмы, используя проблему (см. Решение sqrt (2) и sqrt (3) ниже.

Сокращение таких проблем до ранца может быть не очень хорошей идеей, так как я ожидаю, что будут другие способы, которые будут намного быстрее.

Итак, чтобы ответить на ваши вопросы:


Проблема, связанная с sqrt (2) и sqrt (3)

Сначала я отвечу на ваш второй вопрос.

f(x) = 1 for x < sqrt(2). (x >= 0 also, I presume)
f(x) = f(x-sqrt(2)) + sqrt(3)

Это может быть решено очень быстро (за O (log logn)!), Используя только целочисленную арифметику (которая предполагается O (1)), ожидайте один последний шаг, который требует умножения на sqrt (3) и добавления 1 .

Учитывая n, нам нужно найти наименьшее m такое, что

n - m sqrt(2) < sqrt(2)
* * Тысяча двадцать-одиной т.е.
n - m sqrt(2) < sqrt(2) => n < (m+1)*sqrt(2) => n * sqrt(2) < m+1

и

n - (m-1)sqrt(2) > sqrt(2) => n > m sqrt(2) => n*sqrt(2) > m.

Таким образом, m является целой частью n*sqrt(2)

и имеем f (n) = (m-1) * sqrt (3) + 1.

Таким образом, нам нужно только вычислить [n *sqrt(2)] целую часть n*sqrt(2).

Это можно быстро рассчитать, используя Continued Fractions из sqrt (2), которые являются рациональными приближениями к sqrt (2) и в некотором смысле являются «наилучшими» приближениями с заданными размерами знаменателя.

Непрерывная дробь a (i) / b (i) sqrt (2) может быть сформирована с использованием повторения:

a0 = 1
b0 = 1
a(i+1) = a(i) +2*b(i)
b(i+1) = a(i) + b(i)

Можно показать, что для аппроксимации [n * sqrt (2)] достаточно рассмотреть нечетное i, для которого b (i)> 10 * n ^ 2 (используя Теорема приближения Лиувилля * 1045) * и теоремы о продолженных дробях) и что [n*sqrt(2)] = [n*a(i)/b(i)] для этого я.

Теперь a (i), b (i) удовлетворяют матричному уравнению

[1 2] [a(i)]    [a(i+1)]
[1 1] [b(i)]  = [b(i+1)]

Таким образом, нам нужно вычислить степени матрицы

[1 2]
[1 1]

Чтобы записи были больше 10 * n ^ 2.

Можно показать, что требуемая мощность матрицы составляет O (logn) и, таким образом, ее можно рассчитать за время O (log log n), используя только целочисленную арифметику (при условии, что это O (1)).

Таким образом, значение вашей функции f при n можно вычислить за время O (log logn), используя только целочисленную арифметику (за исключением последнего шага, где вам нужно умножить целое число на sqrt (3)).


Число Пибоначчи

Из вашего комментария это проблема

g(x) = 1 if 0 <= x < 4
g(x) = g(x-1) + g(x-pi) x >= 4

Это можно решить, используя памятку:

Пусть h(m,n) = g(m - n*pi)

Тогда у нас есть это

h(m,n) = h(m-1, n) + h(m, n+1)

Итак, у нас есть это

g(m) = g(m-1) + h(m, 1)

Теперь вы можете использовать памятку, сохраняя две таблицы, одну для g (m) и другую для h (m, n). Обратите внимание, что даже если вам нужно вычислить h(m,n+1), увеличение n только уменьшает m -n * pi и станет между 0 и 4 в течение разумного времени (я полагаю, O (m)), таким образом, вы не будете продолжать вечно .

Это не так хорошо (или быстро), как решения sqrt (2) и sqrt (3), но я полагаю, что оно дает способ сделать расчет.


0-1 Рюкзак с иррациональными коэффициентами

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

Я предполагаю, что фиксированная точка в этой итерации даст вам решение.

Конечно, по мере приближения аппроксимации W в O (nW) их алгоритма динамического программирования может скоро стать экспоненциальным, и вам может быть лучше, просто рассмотрите все возможности.

1 голос
/ 03 июня 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...