Search
 
 
  Engleski
 
 
 
Open in this window (click to change)
Forum@DeGiorgi: Početna
Forum za podršku nastavi na PMF-MO
Login Registracija FAQ Smajlići Članstvo Pretražnik Forum@DeGiorgi: Početna

Particioniranje multiskupa
WWW:

Moja sarma
 
Započnite novu temu   Odgovorite na temu   printer-friendly view    Forum@DeGiorgi: Početna -> Kolegiji 1. godine, preddiplomski studij Matematika -> Programiranje 1 i 2
Prethodna tema :: Sljedeća tema  
Autor/ica Poruka
Gost






PostPostano: 11:44 sub, 1. 1. 2005    Naslov: Particioniranje multiskupa Citirajte i odgovorite

Zanima me kako na sve moguce nacine particionirati dani multiskup na dvije (neuredjene - dakle isto je {{1},{1,2}} i {{1,2},{1}}) particije tako da svaka particija ima barem jedan element. Treba mi konkretna procedura (sto efikasniji algoritam) a ne samo broj takvih particija.

Za one koji ne znaju: multiskup je kolekcija elemenata ciji poredak je nevazan a koji medjusobno ne moraju nuzno biti razliciti.
(Dakle {1,1,2} i {1,1,1,2} su dva razlicita multiskupa, prvi kardinaliteta 3, drugi 4)

Meni je prva ideja bila da idem po kardinalnom broju prve particije (druga se uvijek lako dobije komplementiranjem)... za k=1 je jednostavno, treba samo uzeti sve razlicite elemente, vec za k=2 nastaju mali problemi... Treba proci po svim razlicitim prvim elementima, te uzeti sve druge elemente (pazeci da ne dobijemo dva ista multiskupa; dakle ok, neka bude sortiran polazni multiskup pa cemo u drugoj petlji proci jednom sve medjusobno razlicite i >= prvom) Za k=3 treba uzeti sve moguce kombinacije iz k=2 i pridodati im novi... Drugim rijecima imamo slozenost O(n^3), a ocito je da imamo neke stvari redundantne jer pri svakom vecem k mi ponovno konstruiramo multiskupice koje smo sve vec konstruirali za k-1.
Dakle zakljucak toga je da treba ici po (medjusobno razlicitim) elementima. Za prvu particiju (card >0, <=n/2) uzmemo na sve moguce nacine prvi element (opet pretpostavimo da imamo sortiran polazni multiskup, pa je to jedna linearna setnja) i onda s njim pokusamo realizirati sve moguce kombinacije... dodamo prazan skup, pa sve moguce multipodskupove polaznog iz kojeg smo izvadili prvi (sada kardinaliteta >0, <=n/2-1), sto je zapravo smanjeni polazni problem. Dakle imamo rekurziju u kojoj prenosimo kao argumente citave multiskupove (koji mogu biti veliki) sto mi se opet bas ne svidja.

Ima li sta efikasnije i elegantnije??

Please ljudi, hitno mi je, tako da cu biti zahvalan na svakoj ideji.
Zanima me kako na sve moguce nacine particionirati dani multiskup na dvije (neuredjene - dakle isto je {{1},{1,2}} i {{1,2},{1}}) particije tako da svaka particija ima barem jedan element. Treba mi konkretna procedura (sto efikasniji algoritam) a ne samo broj takvih particija.

Za one koji ne znaju: multiskup je kolekcija elemenata ciji poredak je nevazan a koji medjusobno ne moraju nuzno biti razliciti.
(Dakle {1,1,2} i {1,1,1,2} su dva razlicita multiskupa, prvi kardinaliteta 3, drugi 4)

Meni je prva ideja bila da idem po kardinalnom broju prve particije (druga se uvijek lako dobije komplementiranjem)... za k=1 je jednostavno, treba samo uzeti sve razlicite elemente, vec za k=2 nastaju mali problemi... Treba proci po svim razlicitim prvim elementima, te uzeti sve druge elemente (pazeci da ne dobijemo dva ista multiskupa; dakle ok, neka bude sortiran polazni multiskup pa cemo u drugoj petlji proci jednom sve medjusobno razlicite i >= prvom) Za k=3 treba uzeti sve moguce kombinacije iz k=2 i pridodati im novi... Drugim rijecima imamo slozenost O(n^3), a ocito je da imamo neke stvari redundantne jer pri svakom vecem k mi ponovno konstruiramo multiskupice koje smo sve vec konstruirali za k-1.
Dakle zakljucak toga je da treba ici po (medjusobno razlicitim) elementima. Za prvu particiju (card >0, <=n/2) uzmemo na sve moguce nacine prvi element (opet pretpostavimo da imamo sortiran polazni multiskup, pa je to jedna linearna setnja) i onda s njim pokusamo realizirati sve moguce kombinacije... dodamo prazan skup, pa sve moguce multipodskupove polaznog iz kojeg smo izvadili prvi (sada kardinaliteta >0, <=n/2-1), sto je zapravo smanjeni polazni problem. Dakle imamo rekurziju u kojoj prenosimo kao argumente citave multiskupove (koji mogu biti veliki) sto mi se opet bas ne svidja.

Ima li sta efikasnije i elegantnije??

Please ljudi, hitno mi je, tako da cu biti zahvalan na svakoj ideji.


[Vrh]
ahri
Forumaš(ica)
Forumaš(ica)


Pridružen/a: 19. 11. 2003. (23:16:07)
Postovi: (193)16
Sarma = la pohva - posuda
= 7 - 0

PostPostano: 19:41 sub, 1. 1. 2005    Naslov: Citirajte i odgovorite

nisi bas napisao ogranicenja, koliko razlicitih elemenata moze biti, etc.
no, dobro.
za pocetak napises multiskup onako kako se multiskup zapisuje ;)
a1^x1 a2^x2... an^xn, gdje su a1..an razliciti elementi multiskupa, x1..xn broj ponavljanja istih.

napravis polje od N elemenata u koje ces zapisivati koliko si istih elemenata uzeo i rekurziras kroz to.

npr multiskupich aabbbc ce biti prvo zapisan kao 2, 3, 1 u tom nizu, N = 3.
i sad rekurzija koja ide do dubine N i uzima 0..xi elemenata (i je trenutna dubina - tj. polozaj u nasem nizu).


evo neka jednostavna implementacija tog primjera sa skupom aabbbc

[code:1]
void rek (int *a, int *b, int x, int n) {
int i, j;
if (x==n) { /*kada smo izgenerirali sve razlicite elemente, ispisemo sto smo generirali*/
for (i=0;i<n;i++)
for (j=0;j<b[i];j++)
printf("%c", i+'a');
printf(" ");
for (i=0;i<n;i++)
for (j=b[i];j<a[i];j++)
printf("%c", i+'a');
printf("\n");
return; /* i onda ubijemo rekurziju */
}

for (i=0;i<=a[x];i++) { /* za prvi skup mozemo uzeti bilokoji broj elemenata, ukljucno sa nulom */
b[x]=i;
rek(a, b, x+1, n);
}

}



int main () {

int a[3], b[3];

/* u a se nalazi koliko kojih elemenata imamo u multiskupu
u b ce se nalaziti trenutna particija multiskupa */
a[0]=2;
a[1]=3;
a[2]=1;
rek(a, b, 0, 3);

return 0;
}

[/code:1]

tu se dalje moze svasta raditi. svatis elemente skupova kao proste brojeve, pa ti je zapravo skup isto sto i neki slozeni broj, te mu nadjes sve djelitelje...
nisi bas napisao ogranicenja, koliko razlicitih elemenata moze biti, etc.
no, dobro.
za pocetak napises multiskup onako kako se multiskup zapisuje ;)
a1^x1 a2^x2... an^xn, gdje su a1..an razliciti elementi multiskupa, x1..xn broj ponavljanja istih.

napravis polje od N elemenata u koje ces zapisivati koliko si istih elemenata uzeo i rekurziras kroz to.

npr multiskupich aabbbc ce biti prvo zapisan kao 2, 3, 1 u tom nizu, N = 3.
i sad rekurzija koja ide do dubine N i uzima 0..xi elemenata (i je trenutna dubina - tj. polozaj u nasem nizu).


evo neka jednostavna implementacija tog primjera sa skupom aabbbc

Kod:

void rek (int *a, int *b, int x, int n) {
   int i, j;
   if (x==n) { /*kada smo izgenerirali sve razlicite elemente, ispisemo sto smo generirali*/
      for (i=0;i<n;i++)
         for (j=0;j<b[i];j++)
            printf("%c", i+'a');
      printf(" ");
      for (i=0;i<n;i++)
         for (j=b[i];j<a[i];j++)
            printf("%c", i+'a');
      printf("\n");
      return; /* i onda ubijemo rekurziju */
   }

   for (i=0;i<=a[x];i++) { /* za prvi skup mozemo uzeti bilokoji broj elemenata, ukljucno sa nulom */
      b[x]=i;
      rek(a, b, x+1, n);
   }

}



int main () {

   int a[3], b[3];

   /* u a se nalazi koliko kojih elemenata imamo u multiskupu
      u b ce se nalaziti trenutna particija multiskupa */
   a[0]=2;
   a[1]=3;
   a[2]=1;
   rek(a, b, 0, 3);

   return 0;
}



tu se dalje moze svasta raditi. svatis elemente skupova kao proste brojeve, pa ti je zapravo skup isto sto i neki slozeni broj, te mu nadjes sve djelitelje...



_________________
[Vrh]
Korisnički profil Pošaljite privatnu poruku Pošaljite e-mail
vsego
Site Admin
Site Admin


Pridružen/a: 06. 10. 2002. (22:07:09)
Postovi: (3562)16
Spol: zombi
Sarma = la pohva - posuda
854 = 1068 - 214
Lokacija: /sbin/init

PostPostano: 3:54 ned, 2. 1. 2005    Naslov: Citirajte i odgovorite

Ja sam vec odgovorio na topic i onda sam skuzio da sam odgovorio o ispisu svih podskupova, a ne svih particija, pa sam odustao od postanja... :(

Ahri, cini mi se da si i ti rijesio podskupove, a ne particije... :?
Ja sam vec odgovorio na topic i onda sam skuzio da sam odgovorio o ispisu svih podskupova, a ne svih particija, pa sam odustao od postanja... Sad

Ahri, cini mi se da si i ti rijesio podskupove, a ne particije... Confused



_________________
U pravilu ignoriram pitanja u krivim topicima i kodove koji nisu u [code]...[/code] blokovima.
Takodjer, OBJASNITE sto vas muci! "Sto mi je krivo?", bez opisa u cemu je problem, rijetko ce zadobiti moju paznju.
Drzim prodike
[Vrh]
Korisnički profil Pošaljite privatnu poruku
Gost






PostPostano: 5:22 ned, 2. 1. 2005    Naslov: Citirajte i odgovorite

Ne, pa dobro je ljudi. Kako trebam particionirat na samo dvije particije, svako particioniranje je jednoznacno odredjeno prvom particijom, a druga se onda dobije komplementiranjem - dakle trazimo sve podskupove kardinaliteta <=n/2 (jer nije bitan poredak samih particija). Dakle ahri je u principu rijesio problem, jedino kaj u rekurziju treba stavit jos jedan argument - kolko smo do tog trenutka nafilali elemenata - da ne prijedjemo onda tih famoznih n/2.
Thanx ahri na ovakvom pogledu na multiskupove, to mi puno olaksava stvari. :D

Svima sve najbolje u novoj nam 2005-oj!
Ne, pa dobro je ljudi. Kako trebam particionirat na samo dvije particije, svako particioniranje je jednoznacno odredjeno prvom particijom, a druga se onda dobije komplementiranjem - dakle trazimo sve podskupove kardinaliteta <=n/2 (jer nije bitan poredak samih particija). Dakle ahri je u principu rijesio problem, jedino kaj u rekurziju treba stavit jos jedan argument - kolko smo do tog trenutka nafilali elemenata - da ne prijedjemo onda tih famoznih n/2.
Thanx ahri na ovakvom pogledu na multiskupove, to mi puno olaksava stvari. Very Happy

Svima sve najbolje u novoj nam 2005-oj!


[Vrh]
ahri
Forumaš(ica)
Forumaš(ica)


Pridružen/a: 19. 11. 2003. (23:16:07)
Postovi: (193)16
Sarma = la pohva - posuda
= 7 - 0

PostPostano: 5:32 ned, 2. 1. 2005    Naslov: Citirajte i odgovorite

tocno... tek sam sad malo bolje procitao
:(
ali slobodno ostavi, mozda ce nekom koristit. mozes editirat i nekom bojom napisati da je to rjesenje za podskupe

zapravo, vec osmislih nesto.

pod uvijetom da shvatimo multiskup kao neki prirodan broj (dakle, prosti brojevi na potencije) onda mozemo rijesiti slicno kao i zadatak "ispisi sve razlicite produkte koji daju broj N"
za npr. 24 to je
2*2*2*3
2*2*6
2*3*4
2*12
3*8
4*6


a taj zadatak sam rijesio ovako:

[code:1]
int rek(int n, int maxv) {
int sum=1;
for (int i=maxv; i*i<=n; i++)
if (n%i==0) sum+=rek(n/i, i);
return sum;
}

int refactor(int n) {
return rek(n, 2)-1;
}
[/code:1]

koji doduse ispisuje koliko ih ukupno ima, ali to se lahko preradi da ispise sto je dobio... te djelitelje (ili faktore) potrpamo u niz, i onda iz njih lako generiramo koji su to elementi multiskupa.
a ispisujemo npr. kada je n>maxv.

u mom zadatku je maxv je djelitelj, a n broj koji dijelim
i idem tako da stalno dijelim s brojevima koji su veci od prethodnih

npr. nakon sto 24 podijelim s 2, onda mogu nastavit dijelit s svim vecim od 2 .. ali ako ga u nekom trenu podijelim s 6, onda vise ne mogu s manjima od 6...
nadam se da me razumijete, ako ne, prosecite malo "rucno" kroz kod.

[10 mins later]
zapravo... evo, iskodirah.
ispise ti sve, a pretvaranje prostih brojeva u skupove ces zbilja sam... :). [napravi si listu prostih brojeva, strpaj to u niz i vrtiii:)]

[code:1]
#include <stdio.h>
#include <string.h>

int polje[50];
int k=0;

int ispisi() {
int i;
for(i=0;i<k;i++)
printf("%d ", polje[i]);
printf("\n");
return 0;
}


int rek(int n, int maxv) {
int sum=1;
if (n>maxv) {
polje[k]=n;
k++;
ispisi();
k--;
}

for (int i=maxv; i*i<=n; i++)
if (n%i==0) {
polje[k]=i; k++;
sum+=rek(n/i, i);
k--;
}
return sum;
}

int main() {
int n=24;
memset(polje, 0, sizeof(polje));
rek(n, 2)-1;

return 0;

}
[/code:1]
tocno... tek sam sad malo bolje procitao
:(
ali slobodno ostavi, mozda ce nekom koristit. mozes editirat i nekom bojom napisati da je to rjesenje za podskupe

zapravo, vec osmislih nesto.

pod uvijetom da shvatimo multiskup kao neki prirodan broj (dakle, prosti brojevi na potencije) onda mozemo rijesiti slicno kao i zadatak "ispisi sve razlicite produkte koji daju broj N"
za npr. 24 to je
2*2*2*3
2*2*6
2*3*4
2*12
3*8
4*6


a taj zadatak sam rijesio ovako:

Kod:
   
int rek(int n, int maxv) {
      int sum=1;
      for (int i=maxv; i*i<=n; i++)
         if (n%i==0) sum+=rek(n/i, i);
      return sum;
   }

   int refactor(int n) {
      return rek(n, 2)-1;
   }


koji doduse ispisuje koliko ih ukupno ima, ali to se lahko preradi da ispise sto je dobio... te djelitelje (ili faktore) potrpamo u niz, i onda iz njih lako generiramo koji su to elementi multiskupa.
a ispisujemo npr. kada je n>maxv.

u mom zadatku je maxv je djelitelj, a n broj koji dijelim
i idem tako da stalno dijelim s brojevima koji su veci od prethodnih

npr. nakon sto 24 podijelim s 2, onda mogu nastavit dijelit s svim vecim od 2 .. ali ako ga u nekom trenu podijelim s 6, onda vise ne mogu s manjima od 6...
nadam se da me razumijete, ako ne, prosecite malo "rucno" kroz kod.

[10 mins later]
zapravo... evo, iskodirah.
ispise ti sve, a pretvaranje prostih brojeva u skupove ces zbilja sam... :). [napravi si listu prostih brojeva, strpaj to u niz i vrtiii:)]

Kod:

#include <stdio.h>
#include <string.h>

int polje[50];
int k=0;

   int ispisi() {
      int i;
      for(i=0;i<k;i++)
         printf("%d ", polje[i]);
      printf("\n");
      return 0;
   }


   int rek(int n, int maxv) {
      int sum=1;
      if (n>maxv) {
         polje[k]=n;
         k++;
         ispisi();
         k--;
      }

      for (int i=maxv; i*i<=n; i++)
         if (n%i==0) {
            polje[k]=i; k++;
            sum+=rek(n/i, i);
            k--;
         }
      return sum;
   }

   int main() {
      int n=24;
      memset(polje, 0, sizeof(polje));
      rek(n, 2)-1;

      return 0;

   }



_________________
[Vrh]
Korisnički profil Pošaljite privatnu poruku Pošaljite e-mail
ahri
Forumaš(ica)
Forumaš(ica)


Pridružen/a: 19. 11. 2003. (23:16:07)
Postovi: (193)16
Sarma = la pohva - posuda
= 7 - 0

PostPostano: 5:35 ned, 2. 1. 2005    Naslov: Citirajte i odgovorite

cini se da malo kasnim, ali i ovo sto napisah bi moglo biti korisno nekome kasnije, valjda ce plemeniti vsego biti milostiv :)...

i sada, u stilu mog poluidola

HTH,
ahri
cini se da malo kasnim, ali i ovo sto napisah bi moglo biti korisno nekome kasnije, valjda ce plemeniti vsego biti milostiv :)...

i sada, u stilu mog poluidola

HTH,
ahri



_________________
[Vrh]
Korisnički profil Pošaljite privatnu poruku Pošaljite e-mail
@#
Forumaš(ica)
Forumaš(ica)


Pridružen/a: 28. 01. 2004. (19:08:55)
Postovi: (36)16
Sarma = la pohva - posuda
= 0 - 0
Lokacija: math

PostPostano: 21:18 sri, 5. 1. 2005    Naslov: Citirajte i odgovorite

[quote="ahri"]poluidola[/quote]

A tko je druga polovica? :-))
ahri (napisa):
poluidola


A tko je druga polovica? :-))



_________________
--
~#!'<0 !'0 0)' ('0|'# v|)'| =v# ...
[Vrh]
Korisnički profil Pošaljite privatnu poruku Pošaljite e-mail Posjetite Web stranice
ahri
Forumaš(ica)
Forumaš(ica)


Pridružen/a: 19. 11. 2003. (23:16:07)
Postovi: (193)16
Sarma = la pohva - posuda
= 7 - 0

PostPostano: 21:36 sri, 5. 1. 2005    Naslov: Citirajte i odgovorite

[quote="@#"][quote="ahri"]poluidola[/quote]

A tko je druga polovica? :-))[/quote]

let secrets remain secrets. ;)
@# (napisa):
ahri (napisa):
poluidola


A tko je druga polovica? :-))


let secrets remain secrets. ;)



_________________
[Vrh]
Korisnički profil Pošaljite privatnu poruku Pošaljite e-mail
Prethodni postovi:   
Započnite novu temu   Odgovorite na temu   printer-friendly view    Forum@DeGiorgi: Početna -> Kolegiji 1. godine, preddiplomski studij Matematika -> Programiranje 1 i 2 Vremenska zona: GMT + 01:00.
Stranica 1 / 1.

 
Forum(o)Bir:  
Ne možete otvarati nove teme.
Ne možete odgovarati na postove.
Ne možete uređivati Vaše postove.
Ne možete izbrisati Vaše postove.
Ne možete glasovati u anketama.
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2002 phpBB Group
Theme created by Vjacheslav Trushkin
HR (Cro) by Ančica Sečan