|
|
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
Добрый день! Есть некоторая последовательность натуральных чисел, например Код: sql 1. Надо её разбить на k отрезков (определить, где поставить k-1 разделителей) как можно более равномерно, т.е. чтобы в суммы чисел в отрезках не особенно различались (чтобы разница между наибольшей и наименьшей суммой была минимальна). Числа в последовательности переставлять нельзя. Для указанного примера, требуемое разбиение на k=4 отрезков: Код: sql 1. получилась минимальная сумма - 8, максимальная - 16, разница 8. Любые другие разбивки дадут большую разницу. Какие алгоритмы есть на данную тему? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 15:15 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
Разбивальщик, 6, 10, 6, (1, 2, 8), (4, 3, 4) 11-6 = 5 Как-то ты неоптимально разбил ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 15:40 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
товарищ Брют Форс - справится ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 15:43 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
Програмёр, условие не внимательно почитали, по условию k=4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 15:43 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
бухалтер фантоцциПрограмёр, условие не внимательно почитали, по условию k=4 Да, сообразил уже после того, как ответил (неоднозначно маленько написано :) ). Ну да ладно. По алгоритму. При прочтении задачи первое о чём мне подумалось: если минимизировать разницу между каждой парой отрезков, то это минимизирует разницу между самым большим и самым маленьким из них. Кажется работает всегда. То есть, я бы поступил следующим образом: 1. Разбил ряд на k случайных отрезков 2. Перераспределил бы элементы между первым и вторым из них, минимизируя разницу. Потом между вторым и третьим, третьим и четвёртым и т.д. 3. Если на очередном круге распределения был перераспределён хоть один элемент последовательности, повторил бы шаг 2 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 15:59 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
Програмёр2. Перераспределил бы элементы между первым и вторым из них, минимизируя разницу. Вот, допустим, у нас такой первый вариант Код: sql 1. Как в общем случае замотивироваться и перекинуть 10 в первый отрезок? Это даст выигрыш на след. ходах, но в момент выравнивания первых двух отрезков мы пока об этом не знаем. а если там вообще такой расклад Код: sql 1. то тем более перераспределение только увеличит разницу, и на первом шаге до него хрен догадаешься. хотя можно, наверно, просто перекидывать элементы из большего в меньший... Но до какого предела?... ---- Начальное приближение имеет смысл делать не случайным, а взять среднюю сумму в группе (полная сумма, деленная на k), и равномерно порезать массив, а те элементы, которые оказались на линии разрезов, втолкнуть в наиболее подходящую группу для примера так и выйдет Код: sql 1. средняя сумма 11 а вот как дальше выравнивать, не очень понятно. Здесь справа всё очень ровненько вышло, но в итоге числа 1 и 2 должны уехать во вторую группу... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 16:27 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
Изопропилтоварищ Брют Форс - справитсяну это в крайнем случае. А хотелось бы чего-то полиномиального ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 16:28 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
Разбивальщик, ваша задача решается классическим алгоритмом рекурсивного исчерпывающего поиска. Если не ошибаюсь, алгоритм вы найдете в книге у Кнута и Паташника ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 17:05 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
РазбивальщикИзопропилтоварищ Брют Форс - справитсяну это в крайнем случае. А хотелось бы чего-то полиномиального Асимптотика алгоритма указанного выше составит O(kn^3), думаю вас это устроит ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 17:07 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
Разбивальщик для примера так и выйдет Код: sql 1. средняя сумма 11 а вот как дальше выравнивать, не очень понятно. Здесь справа всё очень ровненько вышло, но в итоге числа 1 и 2 должны уехать во вторую группу... не представляю простого решения, которое могло бы дать оптимальный результат. Тут только перебором. Моё решение даёт результат близкий к оптимальному :( можно, конечно, попробовать вариант с минимизацией разницы не в двух соседних отрезках, а в трёх. Но тут я тоже не уверен в 100% оптимальности. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 17:13 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
Програмёрбухалтер фантоцциПрограмёр, условие не внимательно почитали, по условию k=4 Да, сообразил уже после того, как ответил (неоднозначно маленько написано :) ). Ну да ладно. По алгоритму. При прочтении задачи первое о чём мне подумалось: если минимизировать разницу между каждой парой отрезков, то это минимизирует разницу между самым большим и самым маленьким из них. Кажется работает всегда. То есть, я бы поступил следующим образом: 1. Разбил ряд на k случайных отрезков 2. Перераспределил бы элементы между первым и вторым из них, минимизируя разницу. Потом между вторым и третьим, третьим и четвёртым и т.д. 3. Если на очередном круге распределения был перераспределён хоть один элемент последовательности, повторил бы шаг 2 К сожалению на практике такие "алгоритмы"(никаким образом не обоснованные) могут привести к ub. Более того, алгоритмом, то что вы написали, ни в коем случае не является вовсе ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 17:17 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
SashaMercuryПрограмёрпропущено... Да, сообразил уже после того, как ответил (неоднозначно маленько написано :) ). Ну да ладно. По алгоритму. При прочтении задачи первое о чём мне подумалось: если минимизировать разницу между каждой парой отрезков, то это минимизирует разницу между самым большим и самым маленьким из них. Кажется работает всегда. То есть, я бы поступил следующим образом: 1. Разбил ряд на k случайных отрезков 2. Перераспределил бы элементы между первым и вторым из них, минимизируя разницу. Потом между вторым и третьим, третьим и четвёртым и т.д. 3. Если на очередном круге распределения был перераспределён хоть один элемент последовательности, повторил бы шаг 2 К сожалению на практике такие "алгоритмы"(никаким образом не обоснованные) могут привести к ub. Более того, алгоритмом, то что вы написали, ни в коем случае не является вовсе Он был обоснован базовой логикой решения такой задачи человеком в реальном мире (метод полного перебора исключался, так как является не оптимальным и очевидным изначально). P.S. Поясни, пожалуйста, какое значение вкладывалось в буквы "ub". Одна только википедия предложила более 2 десятков аббревиатур (не применимых в данном контексте) UB в wiki ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 17:39 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
ПрограмёрSashaMercuryпропущено... К сожалению на практике такие "алгоритмы"(никаким образом не обоснованные) могут привести к ub. Более того, алгоритмом, то что вы написали, ни в коем случае не является вовсе Он был обоснован базовой логикой решения такой задачи человеком в реальном мире (метод полного перебора исключался, так как является не оптимальным и очевидным изначально). P.S. Поясни, пожалуйста, какое значение вкладывалось в буквы "ub". Одна только википедия предложила более 2 десятков аббревиатур (не применимых в данном контексте) UB в wiki Он ничем не обоснован и совершенно очевидно некорректен, как и ваша последующая идея с тремя элементами. PS Данный термин, как правило, применяется в другом контексте, нежели по отношению к алгоритмам вообще, и означает дословно undefined behavior. Т.е. результат выполнения оператора языка или участка кода не определен спецификацией языка. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 17:51 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
SashaMercuryОн ничем не обоснован и совершенно очевидно некорректен, как и ваша последующая идея с тремя элементами. Любое своё утверждение, не подкреплённое доказательством или статистикой (практикой), я сам же и ставлю под сомнение. Помогает не попадать в глупые ситуации, когда спорил пуская пену изо рта и оказался неправ. Твоё же утверждение звучит абсолютно (по типу "это так, и никак иначе"). Оно подкреплено доказательством или практическим примером, на котором вариант с тремя элементами даст неоптимальный результат? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 18:12 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
ПрограмёрSashaMercuryОн ничем не обоснован и совершенно очевидно некорректен, как и ваша последующая идея с тремя элементами. Любое своё утверждение, не подкреплённое доказательством или статистикой (практикой), я сам же и ставлю под сомнение. Помогает не попадать в глупые ситуации, когда спорил пуская пену изо рта и оказался неправ. Твоё же утверждение звучит абсолютно (по типу "это так, и никак иначе"). Оно подкреплено доказательством или практическим примером, на котором вариант с тремя элементами даст неоптимальный результат? 0. Из частного не следует общее. 1. Слишком очевидно, что это неправильно, потому в данном случае я не привожу конкретные контрпримеры. 2. Задача автора топика классическая. Ее решение указано выше, его асимптотика выше нежели того, что предлагаете вы. Вероятно, над данной задачей думал не один приличный алгорист, и если её классическое решение до сих пор имеет асимптотику выше вашей, ещё раз очевидно, что ваше решение некорректно ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 18:34 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
SashaMercuryРазбивальщик, ваша задача решается классическим алгоритмом рекурсивного исчерпывающего поиска. Если не ошибаюсь, алгоритм вы найдете в книге у Кнута и Паташникаспасибо, посмотрю. насчет кубической сложности, вот какой момент интересует: начальное приближение, которое тут 19335358 описано, даёт неплохой результат, часто близкий к оптимальному (местами требуется перекинуть числа из соседних групп), а иногда и оптимальный. Неужели всё равно понадобится допиливать этот результат за O(n^3) ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 18:42 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
Эту задачу интересно решать для больших N. В этом случае легче выйти на минимальную дельту. Чем больше количество чисел тем больше частичные суммы стремятся к норм-распределению. Разумеется я исхожу из того что число k во много раз меньше N. Тривиальный случай (k=2). N делим просто на 2 части линейным поиском. Другие крайние случаи - N и К очень близки (например отрезков всего лишь на 1 меньше чем элементов) тогда мы всего-лишь должны найти два наименьших близких соседа и создать из них группу а остальные уже есть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 18:46 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
РазбивальщикSashaMercuryРазбивальщик, ваша задача решается классическим алгоритмом рекурсивного исчерпывающего поиска. Если не ошибаюсь, алгоритм вы найдете в книге у Кнута и Паташникаспасибо, посмотрю. насчет кубической сложности, вот какой момент интересует: начальное приближение, которое тут 19335358 описано, даёт неплохой результат, часто близкий к оптимальному (местами требуется перекинуть числа из соседних групп), а иногда и оптимальный. Неужели всё равно понадобится допиливать этот результат за O(n^3) ? Если вы хотите получить решение, а не реализовать какие-то действия которые дают какой-то результат(и вы не знаете наверняка оптимальный или нет), то вам вовсе не нужно ссылаться на то, что вы ссылаетесь выше. Ваша задача называется задачей линейного разбиения(частный случай). Сейчас открыл Скиену, у него тоже этот алгоритм описан. Он вероятно более доступно объясняет, посмотрите его. Мне пора идти ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 18:55 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 18:58 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
SashaMercuryПрограмёрпропущено... Любое своё утверждение, не подкреплённое доказательством или статистикой (практикой), я сам же и ставлю под сомнение. Помогает не попадать в глупые ситуации, когда спорил пуская пену изо рта и оказался неправ. Твоё же утверждение звучит абсолютно (по типу "это так, и никак иначе"). Оно подкреплено доказательством или практическим примером, на котором вариант с тремя элементами даст неоптимальный результат? 0. Из частного не следует общее. 1. Слишком очевидно, что это неправильно, потому в данном случае я не привожу конкретные контрпримеры. 2. Задача автора топика классическая. Ее решение указано выше, его асимптотика выше нежели того, что предлагаете вы. Вероятно, над данной задачей думал не один приличный алгорист, и если её классическое решение до сих пор имеет асимптотику выше вашей, ещё раз очевидно, что ваше решение некорректно А, ну теперь то всё понятно. Не думал, что ты сможешь найти аж 3 таких весомых аргумента. :) Ладно... Разбивальщик, когда решишь задачу, кинешь сюда файлик с несколькими десятками входых и выходных массивов? Просто интересно в каком проценте случаев моё решение верно )) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 19:57 |
|
||
|
Равномерно разбить числовую последовательность
|
|||
|---|---|---|---|
|
#18+
задачу покамест не решил, но нашел http://blog.jpalardy.com/posts/the-partition-problem/ там последним параграфом идет как раз алгоритм с перекидываниями из большего блока в меньший ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2016, 20:30 |
|
||
|
|

start [/forum/topic.php?fid=16&msg=39262310&tid=1340674]: |
0ms |
get settings: |
7ms |
get forum list: |
17ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
200ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
71ms |
get tp. blocked users: |
1ms |
| others: | 216ms |
| total: | 530ms |

| 0 / 0 |
