Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.04.23;
Скачать: CL | DM;

Вниз

задача на перебор   Найти похожие ветки 

 
bogdan   (2006-04-02 17:20) [0]

Привет мастера!
есть такая задачка!
дано числа p, m;
требуется сгенерировать всевозможные наборы из m+1 чисел, числа берутся целые из отрезка [0..p-1].

Например :
p=3 -> числа следующие: {0,1,2}   m=например 2
значит нужно сформировать все комбинации из трех чисел:
{0,0,0}{0,0,1}{0,0,2}{0,1,0}{0,2,0}{0,1,1}{0,1,2}{0,2,1}{0,2,2} и т.д.

посмотрел задачу на algolist.manual.ru:
Сгенерировать все k-элементные подмножества множества A из N чисел, A={1, 2, ..., N}.

и решение :
---------

Воспользуемся следующим алгоритмом генерации сочетаний по k элементов из множества A:

В массиве B будут находиться индексы используемых на данном шаге элементов из A (общее их число k). В качестве начальной конфигурацией возьмем следующую: B[j]=j, j=1,...,k.

Ищем B[j] с максимальным индексом j такое, что

B[j]<n+j-k,

увеличиваем это B[j] на 1, а для всех m>j полагаем B[m]=B[m-1]+1 (B[j] растут с ростом j, и мы ищем и увеличиваем на 1 такое B[j] с максимальным номером j, чтобы при заполнении возрастающими значениями элементов массива B[m], m>j, последний элемент B[k] не превосходил бы n). Если такого B[j] не существует, то генерация сочетаний для данного k закончена.

---------
Но к сожалению я не могу понять, как это сделать на delphi и вааще этот алгоритм(индексы , проверки)!
если у вас есть какие-то наброски или обьяснения помогите плиз!


 
MBo ©   (2006-04-02 17:33) [1]

рекурсивный алгоритм (менее эффективный) написать не просто, а очень просто

procedure TForm5.Button2Click(Sender: TObject);
var
 n, p: Integer;

 procedure Comb(s: string; From, Level: Integer);
 var
   i: Integer;
 begin
   if Level >= n then
     Memo1.Lines.Add(s)
   else
     for i := From to p - 1 do
       Comb(s + IntToStr(i) + " ", i + 1, Level + 1);
 end;

begin
 n := 3;
 p := 6;
 Comb("", 0, 0);
end;


 
bogdan   (2006-04-02 22:44) [2]


> MBo ©   (02.04.06 17:33) [1]
> рекурсивный алгоритм (менее эффективный) написать не просто,
>  а очень просто
>
> procedure TForm5.Button2Click(Sender: TObject);
> var
>  n, p: Integer;
>
>  procedure Comb(s: string; From, Level: Integer);
>  var
>    i: Integer;
>  begin
>    if Level >= n then
>      Memo1.Lines.Add(s)
>    else
>      for i := From to p - 1 do
>        Comb(s + IntToStr(i) + " ", i + 1, Level + 1);
>  end;
>
> begin
>  n := 3;
>  p := 6;
>  Comb("", 0, 0);
> end;
> <Цитата>


этот вариант не работает


 
Думкин ©   (2006-04-03 06:30) [3]

> bogdan   (02.04.06 22:44) [2]

Для задачи по которйо ты молишь вопросом - работатет.
Для задачи, которая тебе нужна - так она иная.


 
balepa ©   (2006-04-03 06:48) [4]


> bogdan   (02.04.06 17:20)  
> Но к сожалению я не могу понять, как это сделать на delphi
> и вааще этот алгоритм(индексы , проверки)!
> если у вас есть какие-то наброски или обьяснения помогите
> плиз!

Ты хоть раз на математику ходил - вы там что индексами не пользовались и ничего не проверяли?


 
MBo ©   (2006-04-03 07:07) [5]

В первом посте у тебя описаны две разные задачи.
Я тебе дал код генерации лексикографически упорядоченных СОЧЕТАНИЙ.
Другая задача - еще проще, мог бы и сам мозгами пораскинуть:

 procedure ExtraComb(s: string; Level: Integer);
 var
   i: Integer;
 begin
   if Level >= n then
     Memo1.Lines.Add(s)
   else
     for i := 0 to p - 1 do
       ExtraComb(s + IntToStr(i) + " ", Level + 1);
 end;


 
bogdan   (2006-04-03 15:20) [6]

пасиб мастера... разобрался!

я и не говорю что я умный! умные вы а я токо учусь!


 
bogdan   (2006-04-03 15:51) [7]

а вот еще что! каким образом завершается процедура extractcomp
я не вижу там никакого условия завершения!
 обьясните плиз! а то оно работает но я не понимаю! рекурсия ж не человек, что знает когда прекратить!

пасиб


 
MBo ©   (2006-04-03 15:55) [8]

>я не вижу там никакого условия завершения!
if


 
bogdan   (2006-04-03 16:01) [9]

туплю сори


 
bogdan   (2006-04-03 18:15) [10]

Я очень извиняюсь, но придется еще раз просить о помощи! я думал. что поняв выше указаный код, смогу переделать его в случай , когда каждая строка - это вектор двумерного массива , в котором m+1 столбец и соответсвенно p^m векторов-рядков! тоесть заполнять не поля мемо а в массив! но рекурсию я так и не сумел переделать! еще не дорос видать до комбинаторики(слабо у меня здесь)
впринципе я могу написать функцию, которая уже из готовых строк memo переводит числа заполняет двумерный массив, но так коряво программировать даже самому неудобно! та и скорость заметно падет при возрастании p и m!  
просветите, плиз, и в этом случае!
А еще может кто-нить знает степень сложности алгоритма в даной задаче?


 
bogdan   (2006-04-03 22:12) [11]

народ откликнитесь плиз


 
MBo ©   (2006-04-04 07:37) [12]

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

P.S. Нерекурсивный метод генерации размещений с повторениями  можно реализовать как вывод p^n n-разрядных чисел в P-ричной системе счисления.


 
bogdan   (2006-04-04 15:07) [13]

вот именно не могу а не "не хочу"! если б я допер так я бы не спрашивал!
елементарные понятия я знаю! а вот с рекурсией и комбинаторикой плохо у меня, ПЛОХо!
по=этому и прошу помочь разобраться! а вы знаете и не хотите подсказать!


 
bogdan   (2006-04-06 00:00) [14]

привет! вот друг мне подсказал только превести на delphi я не умею

bool Add1(int *array,int m,int p,int degree)
{
 ++array[degree];//увеличиваем разряд
 if(array[degree]==p)//если некуда увеличивать,
 {
   array[degree]=0;//сбрасываем в 0
   if(degree==m)//все, прошли все m+1 разряда (от 0 до m)
     return false;
   else
     return Add1(array,m,p,degree+1);//увеличиваем следующий разряд
 }
 else
   return true;
}
...
//использование:
//выводим все 10-значные числа в 5-чной системе счисления
int array[10]={0,0,0,0,0,0,0,0,0,0};
while(true)
{
 PrintArray(array);
 if(Add1(array,9,5,0))
   break;
}


 
bogdan   (2006-04-08 13:53) [15]

все я решил задание. спасибо за помощь(моральную)


 
MBo ©   (2006-04-08 14:17) [16]

>все я решил задание
Покажи, что получилось


 
bogdan   (2006-04-09 15:28) [17]

Tvect=array [0..10000000,0..10] of integer;
procedure ZAPOV_ROW(var Row:Tvect;ind_r,p,m:integer; number:int64);
var j:integer; s:int64;t1,t:integer;
begin
 //m<10 + p<10
 s:=number;
 if (m>9)or(p>9)or(s>trunc(power(p,m+1))-1) then exit;
 for j:= m+1 downto 1 do
 begin
 t1:= trunc(power(p,j-1));
 t:= s div t1;
 row[ind_r,j]:= t;
 s:=s-row[ind_r,j]*t1;
 end;



Страницы: 1 вся ветка

Текущий архив: 2006.04.23;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.012 c
15-1143832767
Новочеркасский Волк
2006-03-31 23:19
2006.04.23
Проводник удалённого компьютера.


3-1141022734
koks
2006-02-27 09:45
2006.04.23
как запретить скроллинг по датасету


4-1138725955
Matrex
2006-01-31 19:45
2006.04.23
Handle и PID


15-1143758823
Andy BitOff
2006-03-31 02:47
2006.04.23
Интересная статья о птичьем гриппе.


3-1140767621
Bee-Bee
2006-02-24 10:53
2006.04.23
Летит база от ShotDown, глюк сортировки, неверная сортировка





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский