powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Посоветуйте пожалуйста алгоритм
25 сообщений из 32, страница 1 из 2
Посоветуйте пожалуйста алгоритм
    #37666918
_Case
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!

Есть задача (проект на работе): N объектов нужно разбить на группы (объект может находиться только в одной группе), минимум в группе - 2 объекта. Нужно найти ВСЕ возможные разбиения на группы этих N штук объектов!

Алгоритм требуется детерминированный - то есть вероятностные методы (типа метода Монте-Карло и подобные), к сожалению не подходят..

Хотелось бы, если можно, какой-нибудь псевдо-код, неважно в каком виде (Pascal, C, C++, VB, C#, Java.. ) - или просто даже русскими псевдо-операторами.. Производительность роли не играет (то есть сколько угодно циклов в циклах)

Буду благодарен любому совету!

Заранее спасибо!
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667226
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Case,

Как вариант: для распределения - используйте круговой цикл.
Количество групп заранее неизвестно?
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667243
Фотография ПЕНСИОНЕРКА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Case,

похоже теория вероятности

число сочетаний n(2)+n(3)+n(4)+n(5)+ .........kol=n!/(m!*(n-m)!)

при n=6 ~по~2=15
~~~~~~~~по~3=20

а если 6/4=15 да еще остаток из 2 позиций
непонятно, что вы хотите получить
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667248
kmaw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667252
kmaw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сочетание из n элементов по m
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667450
_Case
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Usman,

Нет, количество групп заранее не известно
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667471
tevellius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_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 количество всех возможных групп переваливает за миллиард.
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667473
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Case,

- M = N / 2 (количество групп)
- И комбинаторика (см. выше)
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667485
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Usman_Case,

- M = N / 2 (количество групп)
- И комбинаторика (см. выше)Поправочка:
M - Максимальное кол-во групп
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667496
tevellius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
UPD. Исправляю неверную оценку в конце предыдущего поста, 2^10*n ~ 10^3*n, множитель в степени 10 забыл :)
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667545
Фотография ПЕНСИОНЕРКА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ПЕНСИОНЕРКА_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)
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667662
Abstraction
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tevellius,

Вы перебираете упорядоченные разбиения.
Для неупорядоченных, ИМХО, проще рекурсивно развернуть: берём первый элемент, все остальные к нему добавляем или нет (2 k-1 -1), и объединяем со всеми разбиениями оставшегося множества, если их множество непусто.
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667742
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_CaseНужно найти ВСЕ возможные разбиения на группы этих N штук объектов
Первое, что очевидно, что количество этих групп не превышает int(N/2).
Второе, что не менее очевидно, придётся выполнять полный перебор (нам нужны разбиения, а не их количество).
Соответственно можем совершенно спокойно строить переборный алгоритм.
Первый этап - это организация внешнего цикла перебора количества групп. Очевидно и тривиально.
Второй, внутренний, этап - это генерация всех делений на заданное снаружи количество групп. Это не более не менее как создание заданного числа пустых групп, и затем рекурсивное (или псевдорекурсивное) присоединение очередного элемента к каждой из групп. С учётом ограничения "не менее 2 на группу" вводим 2 дополнительных ограничения в рекурсии - если количество нераспределённых элементов равно сумме количества групп с одним элементом и удвоенного количества пустых групп, прислединять можно только к этим группам, иначе к любым.
Ну собсно и всё...
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667852
kmaw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ради любопытства, можно содержательную часть задачи привести?
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667870
_Case
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina_CaseНужно найти ВСЕ возможные разбиения на группы этих N штук объектов
Первое, что очевидно, что количество этих групп не превышает int(N/2).
Второе, что не менее очевидно, придётся выполнять полный перебор (нам нужны разбиения, а не их количество).
Соответственно можем совершенно спокойно строить переборный алгоритм.
Первый этап - это организация внешнего цикла перебора количества групп. Очевидно и тривиально.
Второй, внутренний, этап - это генерация всех делений на заданное снаружи количество групп. Это не более не менее как создание заданного числа пустых групп, и затем рекурсивное (или псевдорекурсивное) присоединение очередного элемента к каждой из групп. С учётом ограничения "не менее 2 на группу" вводим 2 дополнительных ограничения в рекурсии - если количество нераспределённых элементов равно сумме количества групп с одним элементом и удвоенного количества пустых групп, прислединять можно только к этим группам, иначе к любым.
Ну собсно и всё...

Акина, спасибо за ответ! Но, я наверно, не до конца привёл условие задачи - все объекты уникальные (у каждого свой ID), а Вы указали решение для набора из тождественных (неразличимых) элементов..

То есть группа из первого и второго элемента - это совершенно другая группа, чем например группа из предпоследнего и последнего..
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667896
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Case,

Используйте отображение
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667903
tevellius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Abstraction,

упорядоченные подгруппы на самом деле не рассматриваются, но мой ответ вообще неправильный.

Я не до конца понял условие задачи :(

Приведенный алгоритм позволяет выделить все группы c числом элементов => 2 , а надо же найти все годные разбиения.

Действительно, на ум приходит рекурсия :)
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667934
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_CaseАкина, спасибо за ответ! Но, я наверно, не до конца привёл условие задачи - все объекты уникальные (у каждого свой ID), а Вы указали решение для набора из тождественных (неразличимых) элементов..

То есть группа из первого и второго элемента - это совершенно другая группа, чем например группа из предпоследнего и последнего..
Нет, это Вы ничего не поняли из того, что я написАл. Мой алгоритм предназначен как раз для уникальных элементов, и его надо дорабатывать, если имеются кратные элементы.
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667943
_Case
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina_CaseАкина, спасибо за ответ! Но, я наверно, не до конца привёл условие задачи - все объекты уникальные (у каждого свой ID), а Вы указали решение для набора из тождественных (неразличимых) элементов..

То есть группа из первого и второго элемента - это совершенно другая группа, чем например группа из предпоследнего и последнего..
Нет, это Вы ничего не поняли из того, что я написАл. Мой алгоритм предназначен как раз для уникальных элементов, и его надо дорабатывать, если имеются кратные элементы.

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

Спасибо!
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37667954
_Case
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Usman_Case,

Используйте отображение

Вы имеете ввиду, "отбрасывание" симметричных групп при подсчете или какой-то конкретный существующий алгоритм ?
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37668138
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_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.
(*
Найти количество разбиений на группы n объектов.
Объект может находиться только в одной группе.
Минимальная группа - 2 объекта.
--
Решение разложением по группам, содержащим первый объект
F(n)=Sum(C(n-1,k)*F(n-k-1),k=1..n-3), где:
k=1..n-3 - количество добавленных объектов в группу первого объекта,
C(n-1,k) - количество таких групп (первый и k выбранных),
F(n-k-1) - количество групп, содежащих остальные объекты.
*)

function F(n: integer): int64;
var
  k: integer;
  c: int64;
begin;
  if n<=1 then Result:=0
  else if n<=3 then Result:=1
  else begin;
    Result:=0;
    c:=1;
    for k:=1 to n-3 do begin;
      c:=c * (n-k) div k; //c(n-1,k)
      Result:=Result + c * F(n-k-1);
      end;
    end;
  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin;
  Memo1.Lines.Clear;
  for i:=1 to 26 do Memo1.Lines.Add(IntToStr(i)+' '+IntToStr(F(i)));
  end;
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37668151
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Case,
а если надо, можно заменить вычисление биномиального коэффициента на вывод групп объектов.
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37668227
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_CaseUsmanВы имеете ввиду, "отбрасывание" симметричных групп при подсчете или какой-то конкретный существующий алгоритм ? Просто для унификации
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37668370
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
исправление
Код: 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.
(*
Найти F(n) количество разбиений n различных объектов на группы не менее чем из двух объектов.
--
Решение разложением по группам, содержащим первый объект
F(n)=1+Sum(C(n-1,k)*F(n-k-1),k=1..n-3), где:
n>=2     - количество объектов,
k=1..n-3 - количество добавленных объектов в группу первого объекта,
C(n-1,k) - количество таких групп (первый и k выбранных),
F(n-k-1) - количество групп, содержащих остальные объекты.
*)

function F(n: integer): int64;
var
  k: integer;
  c: int64;
begin;
  if n<2 then Result:=0
  else begin;
    Result:=1;                         //группа, содержащая все объекты
    c:=1;
    for k:=1 to n-3 do begin;
      c:=c * (n-k) div k;              //c(n-1,k)
      Result:=Result + c * F(n-k-1);
      end;
    end;
  end;
...
Рейтинг: 0 / 0
Посоветуйте пожалуйста алгоритм
    #37668397
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kmawради любопытства, можно содержательную часть задачи привести?

Количество способов разбить население на партии.
В каждой партии, как минимум, один начальник и один дурак.
...
Рейтинг: 0 / 0
25 сообщений из 32, страница 1 из 2
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Посоветуйте пожалуйста алгоритм
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]