Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Подскажите, пожалуйста, алгоритм поиска возможных комбинаций  (Прочитано 37955 раз)
0 Пользователей и 1 Гость смотрят эту тему.
wrangels
Гость
« : 18-04-2007 08:10 » 

В общем есть такая задача.
Есть массив случайных целых чисел
 14 15 22 11 17
Дано число N,
Требуется в массиве найдти, все возожные варианты комплектов N

Допустим N равно 3, нужно найдти все возможных варианты
 ( Позиции цифр в нутри варианта не играет роли , главное найти все варианты наборов N чисел)
 список будет таким
14 15 22 11 17

14 15 22
14 15 11
14 15 17
14 22 11
14 22 17
14 11 17
15 22 11
15 22 17
15 11 17

 Подскажите пожалуйста , алгоритм поиска таких кобинаций, Плиизз
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 18-04-2007 09:06 » 

а что по этому поводу говорит теория?
сочетания? комбинации?
алгоритма нет, есть формула
Нет формулы - есть учебник (основы теории вероятности)
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
wrangels
Гость
« Ответ #2 : 18-04-2007 09:22 » 

Не пойму причем тут теория вероятности?
Нужны кобинаци из N цифр
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #3 : 18-04-2007 10:33 » 

Слава имел ввиду комбинаторику. Ага Иногда её рассматривают как часть теории вероятности.

На самом деле всё очень просто. Кстати у тебя могут числа повторяться? например 14 15 22 11 17 15
Скорей всего нет. Ну да ладно.

Итак, в самом общем случае формула очень простая:

а в степени n   a^n, где а - база, n - число разрядов (совпадает с твоим N)

например у тебя есть последовательность 0 1 - всего два числа (а=2), ты хочешь узнать число комбинаций для n=4

те 2^4=16 всевозможных комбинаций от 0000 до 1111

0000
0001
0010
0011
...
1101
1110
1110

Знакомо? До боли. Ага

в твоём случае база равна пяти - пять отличных друг от друга чисел, число разрядов - 3
те 5^3=125

Тебе остаётся только ввести дополнительные ограничения на повторяющиеся комбинации, если того требуют условия задачи. Например

допустимо ли повторение? 17 17 15 или 15 15 15

допустимы симметричные комбинации? 17 11 15 и 15 11 17

ну и тд

Подсказака - факториал Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Sands
Помогающий

ua
Offline Offline

« Ответ #4 : 18-04-2007 11:18 » 

Судя по описанию задачи, тут надо найти C(k,n)=n!/k!*(n-k)! или я неправильно понял. Опять же одно дело пощитать количество, а совсем друго - писать алгоритм и программу.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #5 : 18-04-2007 11:33 » 

Sands, а ты как формулу получил? Ага Они ведь выводятся. Чем не база для алгоритма? Ага В данном случае фразу "подскажите алгоритм" следует понимать как "сделайте за меня". А на это ни у меня, ни у Славы нет ни времени ни желания. Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
wrangels
Гость
« Ответ #6 : 18-04-2007 11:34 » 

После штудирования матчасти получилось вот так:

function Facs(n: Integer;n1: Integer): Integer;
    var NN,I1,I2,I3:integer;

  begin

    NN:=1;

for I1:=1 to N-2 do
  begin
for I2:=I1+1 to N-1 do
  begin
for I3:=I2+1 to N  do
begin

RMs1[1,NN]:=RMs[I1];
RMs1[2,NN]:=RMs[I2];
RMs1[3,NN]:=RMs[I3];

sss:=RMs1[1,NN]+RMs1[2,NN]+RMs1[3,NN];
Form1.ListB6.Items.Add(sss);

NN:=NN+1;

END;
END;
END;

end;

Это для фиксированного числа элементов, а мне нужно N. ни как не могу придумать как ?
Записан
wrangels
Гость
« Ответ #7 : 18-04-2007 11:44 » 

C(k,n)=n!/k!*(n-k)!
ты верно понял так и есть это вычисляется количество комбинаций, но мне нужны сами кобинации
Задачка называется "сочетания из N по K элементов"
Записан
Sands
Помогающий

ua
Offline Offline

« Ответ #8 : 18-04-2007 13:05 » 

Ну, к примеру, можно использовать рекурсию, для получения очередной комбинации, правда плохо то, что этот метод требует много памяти во время работы, а следовательно можно потерпеть с глубиной рекурсии
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 18-04-2007 13:21 » 

wrangels,  а ты не можешь алгоритм записать. У меня от паскалевского кода, да ещё не форматированого в глазах рябит.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 18-04-2007 13:40 » 

интересно, а рекурсия поможет отцу русской демократии?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Sands
Помогающий

ua
Offline Offline

« Ответ #11 : 18-04-2007 13:43 » 

Как один из вариантов вполне может подойти.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 18-04-2007 13:49 » 

Sands, там той глубины -совсем ничего - C(k,n)
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Finch
Спокойный
Администратор

il
Online Online
Пол: Мужской
Пролетал мимо


« Ответ #13 : 18-04-2007 14:51 » 

Я в свое время решал данную проблему так:
Колличество комбинаций ограничено. Значит каждую комбинацию можно пронумеровать от 0 и до n. Теперь самая сложность заключается в том, как по номеру, найти саму требуемую комбинацию Улыбаюсь
Цитата
Допустим N равно 3, нужно найдти все возможных варианты
 ( Позиции цифр в нутри варианта не играет роли , главное найти все варианты наборов N чисел)
 список будет таким
14 15 22 11 17
Введем для ясности еше одно обозначение L это количество значений в массиве.

Я решал так
1) Берем номер комбинации и ишем остаток от деления на L, получаем элемент комбинации
2) Данный элемент помечаем, как использованный
3) Делим номер комбинации на L
4) Уменьшаем L на 1
5) Уменьшаем N на 1
6) Если N  больше 0, перейти к пункту 1
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Sands
Помогающий

ua
Offline Offline

« Ответ #14 : 18-04-2007 15:51 » 

Finch, если не секрет, а что делать если мы попадем на уже использованный элемент(к примеру для комбинации №1 остаток от деления 1 на любое число, кроме 1, будет 1)?
Ето просто, чтоб лучше понять. Вообще твой алгоритм выглядит красивою
Записан
Finch
Спокойный
Администратор

il
Online Online
Пол: Мужской
Пролетал мимо


« Ответ #15 : 18-04-2007 16:06 » 

Sands, Смотри пункт 2 "2) Данный элемент помечаем, как использованный". Использованный элемент исключается как бы из массива. Я лично делал еше один массив флагов, Потом просто в цикле проходил по массиву флагов, и находил элемент, с заданным номером и не используемый. Этот метод хорош для случайного доступа к комбинациям.   
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Sands
Помогающий

ua
Offline Offline

« Ответ #16 : 18-04-2007 16:29 » 

Finch, спасибо. Фактически - это получается рекурсивный алгоритм, только переписанный в итеративной форме Улыбаюсь Красота!!!
Записан
wrangels
Гость
« Ответ #17 : 19-04-2007 06:51 » 

Бльшое спасибо всем за помощь студенту Улыбаюсь
в итоге алгоритм получился таким:
Код:
 
procedure omb(Start, N, K: Integer; OldComb: string);
var i:integer;
  NewComb:string;
begin

for i := Start to N-K+1 do begin
  NewComb := OldComb + RMs[i];
  if K = 1 then
     Form1.ListB6.Items.Add(NewComb)
  else
    omb(i + 1, N, K -1, NewComb)
end;
end;
« Последнее редактирование: 20-04-2007 07:01 от wrangels » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #18 : 19-04-2007 08:31 » 

wrangels, оборачивай код тегами [code]  ...  [/code] - в твоем посте [i] интерпретировалось как italic!
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Finch
Спокойный
Администратор

il
Online Online
Пол: Мужской
Пролетал мимо


« Ответ #19 : 21-04-2007 08:34 » 

В довершении пьянки Улыбаюсь
Код:
#include <stdio.h>

#define null 0

/*
GetKombinat - Функция из набора данных формирует уникальную комбинацию по заданным критериям
    Buf    - Набор данных, которые нужно комбинировать
Lenght - Длина набора (Lenght>0)
ResBuf - Набор комбинации
ResLen - Длина Результируюнего буфера. Должна быть ((ResLen>0) & (ResLen<=Lenght))
Num    - Номер комбинации (от 0 и до (Lenght!)/(Lenght-ResLen)!) Если будет сверх этого числа, то
         функция вернет значение false
    Если комбинация была получена, то функция вернет значение true, иначе false
*/
bool GetKombinat(int *Buf, int Lenght, int *ResBuf, int ResLen, int Num)
{
bool res=false;
if ((Buf != null) && (ResBuf != null) && (Lenght>0) && (ResLen>0) && (ResLen<=Lenght) && (Num>=0))
{
char *fl=new char[Lenght];
if (fl !=null)
{
for (int i=0; i<Lenght; i++) fl[i]=0;
int begRes=0;
int tl;
int beg;
int zn;
while (begRes < ResLen)
{
tl=Num % Lenght;
beg=-1;
zn=-1;
while (zn !=tl)
{
beg++;
if (fl[beg]==0) zn++;
}
ResBuf[begRes]=Buf[beg];
fl[beg]=1;
begRes++;
Num /=Lenght;
Lenght--;
}
if (Num==0) res=true;
}
delete []fl;
}
return res;
}

int main()
{
int Buffer[36];
for (int i=0; i<36; i++)  Buffer[i]=i+1;
int ResBuf[2];
int beg=0;
while (GetKombinat(Buffer,sizeof(Buffer)/sizeof(int), ResBuf, sizeof(ResBuf)/sizeof(int),beg))
{
printf("%d - ",beg);
for (int i=0; i<(sizeof(ResBuf)/sizeof(int)); i++) printf("%d, ",ResBuf[i]);
printf("\n");
beg++;
}
return 0;
}
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines