Ефективний алгоритм "відмов" від суми


24

Враховуючи множину натуральних чисел X, розглянемо набір усіх можливих сум:

sums(X)={iAi|AX}

Наприклад, sums({1,5})={0,1,5,6} тоді як сум({1,1})={0,1,2} .

Який найбільш ефективний алгоритм обчислення зворотної операції (вимірюється у розмірі вхідного набору сум)? Зокрема, чи можна ефективно розрахувати будь-яке з наступного:

  1. Чи є даний набір дійсним набором сум. (Наприклад, дійсна, але ні.){ 0 , 1 , 3 }{0,1,2}{0,1,3}
  2. Мультисети, що підсумовують даний набір.
  3. Найменша MultiSet , що суми в даному наборі. (Наприклад, та сума дорівнює але колишня менший.){ 1 , 1 , 1 } { 0 , 1 , 2 , 3 }{1,2}{1,1,1}{0,1,2,3}

1
Не могли б ви дати нам багатонаціональну суму, а не набір сум? Це створило б приємну симетрію (видно, як ви починаєте з багатозначного значення).
DW

1
Інше питання - вас найбільше цікавлять теоретичні результати (наприклад, асимптотична складність) чи практичні рішення (схеми, які можуть працювати нормально на практиці)? Якщо останнє, чи маєте ви уявлення про типові значення параметрів: наприклад, розмір мультисета X, розмір найбільшого елемента в мультисеті X, найвища кратність? Це може вплинути на те, чи є розумним застосовувати "великий молоток", як розв'язувач ILP або SAT.
DW

@DW Мені напевно цікаво використовувати набір сум, а не мультисети (хоча це теж може бути цікавою проблемою). Також спочатку це була проблема математичної рекреації, тому мене в основному цікавлять межі складності, а не практичне рішення.
Урі Гранта,

3
Якщо вам присвоєно багатозазначені суми, це досить просто зробити це з жагою (див., Наприклад, math.stackexchange.com/questions/201545/… ).
jschnei

@UriZarfaty Набір, поданий як вхід, вже відсортований? Нарешті це встановлено чи мультисет? Коментар все ще говорить про те, що ви хочете чистого набору.
Зло

Відповіді:


9

Рішення

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

Алгоритм мінімального набору

  1. Знайдіть максимальний елемент із сукупності (множин). P , потенційний мінімальний (багаторазовий) набір спочатку порожній.амП

  2. Якщо є тільки одна група, представляє усіма можливими способами , як пари сум , які складаються в вигляді т , S я J = { ( я , J ) | a i + a j = a m }амамSij={(аi,аj)|аi+аj=ам}

  3. Перевірте, чи включені всі елементи з набору сум.

  4. Знайти максимальний елемент з усіх S я J ( що означає разом) з наступним властивістю: для кожного S я J , s або в S я J , або ми можемо знайти в р з безлічі сум , так що р + a s є в S i j .асSijSijасSijаpаp+асSij

  5. Якщо це так , що не містить S , просто сума и + р , видалити р + S з S я J (або просто встановити мітку , щоб ігнорувати його) і вставити в р і а , ів в S я J замість.Sijасас+аpаp+асSijаpасSij

  6. Якщо елемент присутній в кожному видалити його з усіх S я J один раз (або просто встановити мітку , щоб ігнорувати його і не чіпати його більше) і додати його в список елементів потенційного мінімального безлічі P .SijSijП

  7. Повторюйте, поки всі не порожніSij

  8. Якщо частина залишається порожньою, і ми не можемо продовжити, спробуйте ще раз з максимальним значенням для всіх S i j .SijSij

  9. Відтворити рекурсивні кроки без вилучень і продовжити з алгоритмом булеан покриття над . (Перед цим можна зробити безпечну перевірку того, що P містить усі елементи, які не можуть бути представлені у вигляді суми двох елементів, тому вони обов'язково повинні знаходитись в нижньому наборі. Наприклад, мінімальний елемент повинен бути в P. )ППП

(10. Зауважте, що мінімально задане рішення, яке є ціллю алгоритму, не може містити більше одного повторення одного і того ж числа.)

Приклад:

{2,3,5,7,8,10,12,13,15}

Представляйте 15 усіма можливими способами у вигляді суми двох чисел із набору сум.

(13,2),(12,3),(10,5),(8,7)

Спробуйте знайти максимальну кількість, яка є у всіх групах або яка може бути представлена ​​як сума. Очевидно, що ми можемо почати його шукати з 8, немає сенсу переходити над ним.

13 з першої групи 13 = 8 + 5, тому 13 - це добре, але 12 з другої групи - це не добре, оскільки немає 4, щоб зробити 12 = 8 + 4 у наборі сум. Далі ми спробуємо з 7. Але відразу 13 не можна покрити, немає 6.

Далі пробуємо 5. 13 = 5 + 8, 12 = 5 + 7, 10 = 5 + 5, а для останніх або 8 = 5 + 3, або 7 = 5 + 2, але не обидва. Зараз групи:

((5,8),2),((5,7),3),((5,5),5),((5,3),7)

5 повторюється у всіх групах, тому ми дістаємо його . Ми витягуємо 5 лише один раз з кожної групи.П={5}

(8,2),(7,3),(5,5),(3,7)

Очевидно, що немає сенсу перевищувати 5, тому ми спробуємо 5 ще раз. 8 = 5 + 3, 7 = 5 + 2, тому все добре

((5,3),2),((5,2),3),(5,5),(3,(5,2))

Витягніть ще один 5 з усіх груп, оскільки це повторюється. (Це не є загальним явищем, але наш випадок навмисно створений, щоб відобразити, що робити, якщо у нас є повторення.) П={5,5}

(3,2),(2,3),(5),(3,2)

Тепер ми спробуємо з 3 і маємо 5 = 3 + 2. Додайте його до групи.

(3,2),(2,3),(3,2),(3,2)

Тепер витягніть 3 і 2, оскільки вони повторюються скрізь, і ми добре а групи порожні.П={5,5,3,2}

(),(),(),()

Тепер нам потрібно відтворити рекурсивні кроки без видалення, це просто означає виконати вищезазначене, не дійсно видаляючи елементи з просто помістивши їх у P та позначивши, щоб більше не змінювати його.SijП

( ( 5 , 8 ) , 2 ) , ( ( 5 , 7 ) , 3 ) , ( ( 5 , 5 ) , 5 ) , ( ( 5 , 3 ) , 7

(13,2),(12,3),(10,5),(8,7)
( ( 5 , ( 5 , 3 ) ) , 2 ) , ( ( 5 , ( 5 , 2 ) ) , 3 ) , ( ( 5 , ( 3 , 2 ) ) , 5 ) , ( ( 5 , 3 ) , ( 5 , 2 ) )
((5,8),2),((5,7),3),((5,5),5),((5,3),7)
((5,(5,3)),2),((5,(5,2)),3),((5,(3,2)),5),((5,3),(5,2))

Покриття набору потужності

Мета цієї частини - перевірити, чи знайдений мінімальний набір здатний покрити встановлену суму потужності. Можливо, що знайдене рішення може покрити всі задані суми, але це не суми, встановлені потужністю. (Технічно ви можете просто створити сукупну потужність, встановлену з знайденого мінімального набору, і перевірити, чи кожна сума, як диктує набір потужності, знаходиться в початковому наборі суми. Це все, що тільки злилося з тим, що ми вже маємо, тому нічого не витрачається . Ви можете виконати цю частину під час перемотування рекурсії.)

  1. Кодуйте всі елементи з мінімального набору за допомогою послідовних потужностей 2. Порядок не важливий. Кодуйте той самий елемент з новим значенням стільки разів, скільки він повторюється. Почніть з C = 1, кожен наступний елемент має C = 2C.

(2=[1],3=[2],5=[4],5=[8])
  1. Замініть елементи у відновленому списку рекурсій,

((5,(5,3)),2),((5,(5,2)),3),((5,(3,2)),5),((5,3),(5,2))

з кодуванням: 2 з 1, 3 з 2, 5 з 4 і ще 5 з 8. Зауважте, що кожен елемент має різні кодування, навіть якщо вони повторюються.

((4,(8,2)),1),((4,(8,1)),2),((4,(2,1)),8),((8,2),(4,1))
  1. Зберіть всі проміжні суми, на даний момент у нас є (1,2,4,8)

((4,(10)),1),((4,(9)),2),((4,(3)),8),((10),(5))

Проміжні суми (1,2,3,4,5,8,9,10)

((14),1),((13),2),((7),8),(15)

Проміжні суми (1,2,3,4,5,8,9,10,13,14,15)

{(15),(15),(15),(15)}
  1. Перевірте, що результат дорівнює , де m - кількість елементів у розчині, у прикладі m = 42м-1мм=4

  2. Зберіть пропущені числа від до 2 м - 1 у списку проміжних підсумків12м-1

(6,7,11,12)

  1. Обґрунтуйте їх відсутність таким чином: представляйте кожне число у двійковій формі

( 7 = 0111 2 ) ( 11 = 1011 2 ) ( 12 = 1010 2 )(6=01102) (7=01112) (11=1011 рік2) (12=10102)

являє собою суму 3 + 5, оскільки 0110 2 охоплює другий і третій елементи з ( 2 = [ 1 ] , 3 = [ 2 ] , 5 = [ 4 ] , 5 = [ 8 ] ) . Сума цих елементів, 8, вказана у первинному списку сум { 2 , 3 , 5 , 7 , 8 , 10 , 12 , 13 , 15 }601102(2=[1],3=[2],5=[4],5=[8]){2,3,5,7,8,10,12,13,15}, тому все добре.

являє собою суму 2 + 3 + 5, оскільки 0111 2 охоплює перші три елементи з ( 2 = [ 1 ] , 3 = [ 2 ] , 5 = [ 4 ] , 5 = [ 8 ] ) . Сума цих елементів, 10, вказана у первинному списку суми, тому все добре.701112(2=[1],3=[2],5=[4],5=[8])

- це 2 + 3 + 5, а 10 - у списку. 12 - це 3 + 5, а 8 - у списку.1112

Якщо будь-яке бінарне представлення відповідає сумі, яку неможливо знайти, повідомте про відсутність рішення.

(2,3,5,5)

Обговорення

Необхідно було надати алгоритм, який збирається перевірити, чи покривають суми завершення встановленої потужності, що приховано у бінарному розширенні. Наприклад, якщо ми виключимо 8 та 7 із початкового прикладу, перша частина все-таки забезпечить рішення, лише друга частина повідомила б про відсутніх комбінаціях сум.

мнлог(м)мжурнал2(м)мнжурнал(м)

мжурналммжурнал2(м)

мжурнал3(м)

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

Неправильний старт

2,3,4,5,6,7,8,9,10,11,12,13,152,3,4,6Sij

5,4,3,3

2,2,3,4,42,3,4,6

Мета цього алгоритму - запропонувати рішення, як тільки ми все це запустили правильно.

Поліпшення

Крок 4. - це той, який можна було б оновити таким чином: замість максимального ми могли б випробувати кожен елемент у порядку зменшення, який відповідає заданій умові. Для кожного ми створюємо окрему гілку. Якщо якась філія не дає рішення, скасуйте її.

2,3,4,5,6,7,8,9,10,11,12,13,157,6,5,4окремо, оскільки всі вони проходять перший тест. (Немає ніяких причин використовувати 2 або 3, оскільки ми знаємо, що вони повинні знаходитись у базовій множині.) Та просто продовжувати так навколо, поки ми не зіберемо всі версії, які можуть досягти кінця. Це створило б рішення повного покриття, яке дозволило б виявити більше одного базового набору.

Інша справа, оскільки ми знаємо, що ми не можемо мати більше, ніж одне повторення, якщо випадок мінімальний, ми можемо включити це в наш алгоритм.

Загалом умова на кроці 4, що число повинно повторюватися в кожній групі або мати можливість створювати суму, є досить сильною, щоб вивести нас із прямої експоненціальної води, що було б алгоритмом просто випробувати кожну комбінацію та створити потужність встановити над кожним, поки ми не знайдемо відповідність.


1
Більш широко: я бачу текстовий опис алгоритму, але (a) відсутність псевдокоду та (b) відсутність підтвердження коректності. Чому ви вважаєте, що такий підхід забезпечує алгоритм, який буде правильно працювати на всіх можливих входах? Яке виправдання? Чи є у вас докази правильності цього?
DW

Я думаю, що ця проблема займає близько 30 годин роботи разом (30 разів на годину, ну ...). Але платного варіанту немає.

Нарешті прочитайте відповідь докладно, яку вона заслужила. Чудова робота!
Урі Гранта

1

ПРИМІТКА. Загалом це не зовсім працює, див. Підбірку Урі нижче.

YY

  • 0Y
  • уYуХY
  • z1<<zнYY'Y=Y'+{0,у}0Y'i=1,,nzi+yYziYziyYzi+yYzi+yYziY
  • Y'у,у',

1уО(н)О(н2)

Y={0,1,3,4,5,6,7}{0,1,3,4,6}{0,1,3,5,6}уY{а+ку}YY'


Чи очевидно, що Y 'не призводить до тупику? Адже може бути багато таких Y, що Y = Y '+ {0, y}. Наприклад {0,1,2,3,4} = {0,2,3} + {0,1} = {0,1,2,3} + {0,1}, але колишнє розкладання призводить до мертвий кінець.
Урі Гранта,

Це правда, і це справжня проблема. Я повинен побачити, чи можна це виправити. Спасибі!
Клаус Драгер

Y'кY=Y'+{0,у,,у}{0,у,,у}куY'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.