|
|
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
Добрый день! Есть задача (проект на работе): N объектов нужно разбить на группы (объект может находиться только в одной группе), минимум в группе - 2 объекта. Нужно найти ВСЕ возможные разбиения на группы этих N штук объектов! Алгоритм требуется детерминированный - то есть вероятностные методы (типа метода Монте-Карло и подобные), к сожалению не подходят.. Хотелось бы, если можно, какой-нибудь псевдо-код, неважно в каком виде (Pascal, C, C++, VB, C#, Java.. ) - или просто даже русскими псевдо-операторами.. Производительность роли не играет (то есть сколько угодно циклов в циклах) Буду благодарен любому совету! Заранее спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 12:28 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
_Case, Как вариант: для распределения - используйте круговой цикл. Количество групп заранее неизвестно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 14:14 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
_Case, похоже теория вероятности число сочетаний n(2)+n(3)+n(4)+n(5)+ .........kol=n!/(m!*(n-m)!) при n=6 ~по~2=15 ~~~~~~~~по~3=20 а если 6/4=15 да еще остаток из 2 позиций непонятно, что вы хотите получить ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 14:22 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
Сочетание из n элементов по m ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 14:25 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
Usman, Нет, количество групп заранее не известно ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 15:48 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
_Case, Пусть A - исходный массив длины N. Выпишем его в форме вектора: A = [a(1), ..., a(N)] Для каждой группы запишем характеристический вектор X -если элемент a(i) принадлежит группе, x(i) = 1, в противном случае - 0 например, для группы из элемента а(1) вектор будет иметь вид: X({a(1)}) = [1,0,.....,0] а X({a(1),a(2)}) = [1,1,0,....0] Очевидно, что множество характеристических векторов взаимно-однозначно отображается на множество подмножеств исходного массива, и каждый X-вектор является записью двоичного числа разрядности N (N-битный байт, двоичное число с дописанными нулями впереди). Количество X-векторов в точности равно 2^n (если включать нулевой вектор, соответствующий пустой группе) или 2^n-1 (если вырожденный случай с пустой группой выкидываем). Выписав элементы исходного вектора в обратном порядке, легко увидеть что группам из одного элемента соответствуют точные степени двойки. X-векторы легко отсортировать в естественном порядке (от 0 до 2^N-1) [0,0,...,0] (=0) [0,0,...,1] (=1) .... [1,1,...,1] (=2^n-1) Это дает общую идею алгоритма: ДЛЯ счетчик = 3 ПО 2^N-1 С ШАГОМ 1 ЦИКЛ ЕСЛИ СтепеньДвойки(счетчик) Тогда ПРОДОЛЖИТЬ; //уходим на следующую итерацию ИНАЧЕ БитоваяМаска = ЧислоВБитовуюМаску(счетчик,N); Группа = ВыбратьГруппу(ИсходныйМассив, БитоваяМаска) КОНЕЦ ЕСЛИ; КОНЕЦ ЦИКЛА; Потребуется разработать функции: СтепеньДвойки -возвращает булевский тип; Можно сначала вычислить массив степеней, и проверять попадает ли очередное значение счетчика в этот массив. Либо просто считать количество единиц в битовой маске (если 1 - то это степень двойки). ЧислоВБитовуюМаску - тут все очевидно, для примера ЧислоВБитовуюМаску(3,5) = 00101 ВыбратьГруппу - функция должна выбирать из исходного массива элементы, соответствующие 1 в битовой маске. Цикл начинаем с 3, потому что 0...01 (=1) и 0...010 (=2), очевидно, не подходят по условию задачи. Надо иметь в виду, что 2^10*n ~10^n, т.е. при N>30 количество всех возможных групп переваливает за миллиард. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 16:00 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
_Case, - M = N / 2 (количество групп) - И комбинаторика (см. выше) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 16:01 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
Usman_Case, - M = N / 2 (количество групп) - И комбинаторика (см. выше)Поправочка: M - Максимальное кол-во групп ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 16:06 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
UPD. Исправляю неверную оценку в конце предыдущего поста, 2^10*n ~ 10^3*n, множитель в степени 10 забыл :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 16:14 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
ПЕНСИОНЕРКА_Case, похоже теория вероятности число сочетаний n(2)+n(3)+n(4)+n(5)+ .........kol=n!/(m!*(n-m)!) при n=6 ~по~2=15 ~~~~~~~~по~3=20 а если 6/4=15 да еще остаток из 2 позиций непонятно, что вы хотите получить вернее n(2)+хвостик или n(3)+.... или n(4)+..... или n(5) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 16:45 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
tevellius, Вы перебираете упорядоченные разбиения. Для неупорядоченных, ИМХО, проще рекурсивно развернуть: берём первый элемент, все остальные к нему добавляем или нет (2 k-1 -1), и объединяем со всеми разбиениями оставшегося множества, если их множество непусто. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 17:35 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
_CaseНужно найти ВСЕ возможные разбиения на группы этих N штук объектов Первое, что очевидно, что количество этих групп не превышает int(N/2). Второе, что не менее очевидно, придётся выполнять полный перебор (нам нужны разбиения, а не их количество). Соответственно можем совершенно спокойно строить переборный алгоритм. Первый этап - это организация внешнего цикла перебора количества групп. Очевидно и тривиально. Второй, внутренний, этап - это генерация всех делений на заданное снаружи количество групп. Это не более не менее как создание заданного числа пустых групп, и затем рекурсивное (или псевдорекурсивное) присоединение очередного элемента к каждой из групп. С учётом ограничения "не менее 2 на группу" вводим 2 дополнительных ограничения в рекурсии - если количество нераспределённых элементов равно сумме количества групп с одним элементом и удвоенного количества пустых групп, прислединять можно только к этим группам, иначе к любым. Ну собсно и всё... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 18:23 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
ради любопытства, можно содержательную часть задачи привести? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 19:36 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
Akina_CaseНужно найти ВСЕ возможные разбиения на группы этих N штук объектов Первое, что очевидно, что количество этих групп не превышает int(N/2). Второе, что не менее очевидно, придётся выполнять полный перебор (нам нужны разбиения, а не их количество). Соответственно можем совершенно спокойно строить переборный алгоритм. Первый этап - это организация внешнего цикла перебора количества групп. Очевидно и тривиально. Второй, внутренний, этап - это генерация всех делений на заданное снаружи количество групп. Это не более не менее как создание заданного числа пустых групп, и затем рекурсивное (или псевдорекурсивное) присоединение очередного элемента к каждой из групп. С учётом ограничения "не менее 2 на группу" вводим 2 дополнительных ограничения в рекурсии - если количество нераспределённых элементов равно сумме количества групп с одним элементом и удвоенного количества пустых групп, прислединять можно только к этим группам, иначе к любым. Ну собсно и всё... Акина, спасибо за ответ! Но, я наверно, не до конца привёл условие задачи - все объекты уникальные (у каждого свой ID), а Вы указали решение для набора из тождественных (неразличимых) элементов.. То есть группа из первого и второго элемента - это совершенно другая группа, чем например группа из предпоследнего и последнего.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 19:49 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
_Case, Используйте отображение ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 20:05 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
Abstraction, упорядоченные подгруппы на самом деле не рассматриваются, но мой ответ вообще неправильный. Я не до конца понял условие задачи :( Приведенный алгоритм позволяет выделить все группы c числом элементов => 2 , а надо же найти все годные разбиения. Действительно, на ум приходит рекурсия :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 20:09 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
_CaseАкина, спасибо за ответ! Но, я наверно, не до конца привёл условие задачи - все объекты уникальные (у каждого свой ID), а Вы указали решение для набора из тождественных (неразличимых) элементов.. То есть группа из первого и второго элемента - это совершенно другая группа, чем например группа из предпоследнего и последнего.. Нет, это Вы ничего не поняли из того, что я написАл. Мой алгоритм предназначен как раз для уникальных элементов, и его надо дорабатывать, если имеются кратные элементы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 20:41 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
Akina_CaseАкина, спасибо за ответ! Но, я наверно, не до конца привёл условие задачи - все объекты уникальные (у каждого свой ID), а Вы указали решение для набора из тождественных (неразличимых) элементов.. То есть группа из первого и второго элемента - это совершенно другая группа, чем например группа из предпоследнего и последнего.. Нет, это Вы ничего не поняли из того, что я написАл. Мой алгоритм предназначен как раз для уникальных элементов, и его надо дорабатывать, если имеются кратные элементы. Да, да Вы правы, прощу прощения, я сначала неверно понял Ваш ответ, я спутал число групп с числом возможных разбиений на группы Спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 20:54 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
Usman_Case, Используйте отображение Вы имеете ввиду, "отбрасывание" симметричных групп при подсчете или какой-то конкретный существующий алгоритм ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2012, 21:03 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
_Case, Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2012, 01:09 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
_Case, а если надо, можно заменить вычисление биномиального коэффициента на вывод групп объектов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2012, 01:38 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
_CaseUsmanВы имеете ввиду, "отбрасывание" симметричных групп при подсчете или какой-то конкретный существующий алгоритм ? Просто для унификации ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2012, 04:03 |
|
||
|
Посоветуйте пожалуйста алгоритм
|
|||
|---|---|---|---|
|
#18+
исправление Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2012, 13:09 |
|
||
|
|

start [/forum/topic.php?fid=16&msg=37667742&tid=1342329]: |
0ms |
get settings: |
11ms |
get forum list: |
14ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
160ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
81ms |
get tp. blocked users: |
1ms |
| others: | 244ms |
| total: | 528ms |

| 0 / 0 |
