Вирізання рівних паличок з різних паличок


10

У вас паличок довільної довжини, не обов'язково цілісних.n

Вирізавши кілька паличок (один зріз ріже одну паличку, але ми можемо різати так часто, як хочемо), ви хочете отримати палички таким чином:k<n

  • Всі ці палички мають однакову довжину;k
  • Усі палички принаймні довші, ніж усі інші палички.k

Зауважте, що ми отримуємо палички після виконання розрізів.n+CC

Який алгоритм ви використали б таким, щоб кількість необхідних скорочень була мінімальною? І яке це число?

Як приклад візьмемо і будь-який . Можна використовувати наступний алгоритм:k=2n2

  • Упорядкуйте палички по порядку зменшення довжини таким чином, щоб .L1L2Ln
  • Якщо то виріжте палицю №1 на дві рівні частини. Зараз є дві палички довжиною , які є принаймні такими ж, як і інші палички .L12L2L1/22n
  • В іншому випадку ( ) виріжте палицю №1 на два нерівні шматки розмірами та . Зараз є дві палички довжиною , що довше а інші палички .L1<2L2L2L1L2L2L1L23n

В обох випадках достатньо одного розрізу.

Я спробував узагальнити це на більші , але, здається, є багато випадків, які слід розглянути. Ви можете знайти елегантне рішення?k

Відповіді:


6

Першим основним спостереженням для вирішення цієї проблеми є те, що доцільність довжини різання ,l

Feasible(l)=[i=1nLilk] ,

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

l=max{lFeasible(l)} .

Крім того, як запропоновано інші відповіді, всі перериви стрибків мають вигляд . Це залишає перед нами дискретну одновимірну проблему пошуку, яка піддається бінарному пошуку (після сортування обмеженого набору кандидатів).Li/j

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

Тоді різні межі на призводять до алгоритмів різної ефективності.j

  • 1jk приводить до пошукового простору квадратичного розміру (в ),k
  • 1jk/i в (при що відсортовані за зменшенням розміру), іLi
  • трохи більше задіяних меж у лінійному.

Використовуючи це, ми можемо вирішити запропоновану задачу в часі та просторі .Θ(n+klogk)Θ(n+k)

Ще одне зауваження полягає в тому, що сума в зростає в на для кожного кандидата "пройшов", рахуючи дублікати. Використовуючи це, ми можемо використовувати вибір рангів замість бінарного пошуку та отримати алгоритм, який працює у часі та просторі , який є оптимальним.Feasiblel1Li/jΘ(n)

Дізнайтеся деталі в нашій статті Ефективні алгоритми для зависаючого відділу палиць із найменшими надрізами (від Reitzig and Wild, 2015).


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

4

Як запропонував @randomA, ми продовжимо дві фази: Спочатку ми знаходимо набір паличок, які будуть вирізані, а потім мінімізуємо кількість надрізів.

Як і в спеціальному випадку у питанні, ми сортуємо / називаємо палички так, щоб . Це займає час .L1L2LnO(nlogn)

Як вказував @ user1990169, нам ніколи не доводиться вирізати шматок .ik

На першому етапі ми використовуємо двійковий пошук, щоб знайти число , , щоб палички можна було розрізати на принаймні шматочки розміром (плюс кілька менших шматочків) , але палички не можна розрізати на шматочки розміром . Це займе час .s1sk1,,skLs1,,s1kLs1O(klogk)

Якщо , це значення є оптимальним розміром, і ми можемо пропустити другу фазу.Ls1=Ls

В іншому випадку ми знаємо, що оптимальний розмір задовольняє а якщо то результатом розрізання хоча б однієї палички на шматки рівних розмірів. Фаза два визначатиме :oLs1>oLso>Lsoo

Для кожної палички , визначте набір розмірів кандидатів таким чином: Якщо різання на шматки розміром перетворює палицю на шматочки (включаючи коротший, якщо такий є), то кандидати на це stick - всі значення , де і . (Дивіться відповідь @ user1990169, чому це єдиний розмір кандидата.)i1isLsriLijjriLij<Ls1

Підтримуйте для кожного кандидата розмір, як часто це траплялося. Використовуючи збалансоване дерево пошуку, це можна зробити в , оскільки загальна кількість розмірів кандидатів пов'язана з .O(klogk)iri2k

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

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

Загалом ми отримуємо час виконання в або , якщо ігнорувати (або не робити цього) початковий тип.O(nlogn)O(klogk)


На етапі двійкового пошуку, як саме ви перевіряєте, чи "палички можна розрізати на принаймні шматочки розміру "? 1,,skLs
Ерел Сегал-Халеві

Для обчислити . Сума цих значень - кількість штук, яку ви можете отримати. 1isLi/Ls
FrankW

"розмір кандидата, який траплявся найчастіше ... - це той, який дає нам оптимальне рішення" - чому?
Ерел Сегал-Халеві

Щоразу, коли це відбувається, у нас є паличка, яка дає шматочки з розрізами. tt1
FrankW

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

1

Після того, як ви замовили палички у порядку зменшення їх довжини, тоді палицю вирізають, лише якщо всі палички були вирізані.LiL1,L2,...Li1

Тепер, оскільки , ми не будемо робити жодного розрізу на паличках , оскільки ми завжди можемо мати палички довжиною .k<nLkkLk

Отже, замість ми маємо справу лише паличками (можливо, додаванням -й палиці в цілому), і максимальною кількістю розрізів, які знадобляться в гіршому випадку .nk1k=k1

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

Потім можна провести дві вкладені петлі (обидва до ). Зовнішня петля позначає номер палички , всі частини якої потрібно взяти, а внутрішня петля позначає кількість деталей виготовлених із цієї палички. Для кожного розміру перевірте, чи можна отримати реалізовані k-палички, розрізаючи палички вперед послідовно, а якщо зможете, то оновіть необхідні мінімальні розрізи, якщо потрібна кількість менше.kij
LijL1

Загальна складність вищезазначеного алгоритму становитьO(nlog(n)+k3)


1

Ідеєю високого рівня був би двійковий пошук.

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

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

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


2
Я думаю, що основна ідея вашого підходу спрацює. Але ваш опис алгоритму недостатньо зрозумілий, щоб бути впевненим. Чи можете ви додати більш детальний псевдокод?
FrankW

@FrankW Я не надто впевнений у роботі. Я побачу, що у інших людей, це досить цікаве запитання.
ПоінформованоA
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.