Pagini: [1]   În jos
  Imprimă  
Ajutor Subiect: Generare submultimi in alta ordine  (Citit de 2040 ori)
0 Utilizatori şi 1 Vizitator pe acest subiect.
cipri_tom
Strain


Karma: 0
Deconectat Deconectat

Mesaje: 12



Vezi Profilul
« : August 05, 2014, 13:43:00 »

Salut,

Ma lupt cu urmatoarea problema de cateva zile si nu prea imi iese cum vreau Brick wall. Ma gandeam ca poate aveti voi putina inspiratie sau imi vindeti un pont. Merci.

Dandu-se un sir a, de lungime m, sa se genereze toate sirurile b cu proprietatea 0 <= b[j] <= a[j], j = 1, m, in ordinea crescatoare a sumei elementelor.
Exemplu:
a = {2, 2, 2}b0 = { 0, 0, 0 }
b1 = { 1, 0, 0 }
b3 = { 0, 1, 0 }
b6 = { 0, 0, 1 }
b2 = { 2, 0, 0 }
b4 = { 1, 1, 0 }
b5 = { 0, 2, 0 }
b7 = { 1, 0, 1 }
b8 = { 0, 1, 1 }
b9 = { 0, 0, 2 }

Am reusit si sa le fac in alta ordine cu un backtracking. Apoi le-am reordonat cautand liniar sirurile de fiecare ordine, dar desigur asta nu e destul de eficient.

Am o idee care se bazeaza pe generarea consecutiva. Initial le construim pe cele de suma 1, care e doar o matrice cu 1 pe diagonala principala.
Apoi, fiecare suma S se obtine prin insumarea element cu element a unui sir de suma 1 si un sir de suma S-1. Problema e cum sa nu generam sirurile de 2 ori. Am reusit cand sirul a are aceleasi elemente ({2, 2, 2}), dar nu reusesc cand elementele sunt diferite ({2, 3, 2}).

Idei?
Pot posta ce cod am pana acum, desi nu e foarte elegant.

P.S. Nu sunt sigur daca ar trebui categorizat ca tema. Nu e pt scoala, e pt lucru  Very Happy.

Memorat
tudorv96
Strain


Karma: -6
Deconectat Deconectat

Mesaje: 17



Vezi Profilul
« Răspunde #1 : August 05, 2014, 18:04:53 »

Care este ordinea de generare cand suma este aceeasi? (b-urile alea sunt sortate sau nu?)

Memorat
cipri_tom
Strain


Karma: 0
Deconectat Deconectat

Mesaje: 12



Vezi Profilul
« Răspunde #2 : August 05, 2014, 18:21:45 »

deocamdata nu este o ordine specifica atunci cand suma este aceeasi, deci orice varianta e buna. Cu cat mai eficienta, cu atat mai bine Very Happy.
Ordinea pe care am pus-o eu la b-uri rezulta din ideea precizata, obtinem un sir de suma S dintr-un sir de suma S-1 si un sir de suma 1. In acest fel generez mereu doar siruri valide.
Memorat
tudorv96
Strain


Karma: -6
Deconectat Deconectat

Mesaje: 17



Vezi Profilul
« Răspunde #3 : August 05, 2014, 21:24:55 »

Daca nu ma insel, tot timpul vor exista (a[1] + 1) * (a[2] + 1) * (a[3] + 1) *... * (a[m] + 1) solutii. (Incerci sa obtii toate combinatiile posibile). Nu exista algoritmi care au complexitatea mai buna decat Backtracking.

LE: Se pot aplica optimizari, precum cele care le-ai precizat mai sus, dar in fond tot backtracking este  Smile

Mai sunt si alte restrictii si precizari?
« Ultima modificare: August 05, 2014, 21:30:25 de către Tudor Varan » Memorat
cipri_tom
Strain


Karma: 0
Deconectat Deconectat

Mesaje: 12



Vezi Profilul
« Răspunde #4 : August 06, 2014, 12:43:22 »

Daca nu ma insel, tot timpul vor exista (a[1] + 1) * (a[2] + 1) * (a[3] + 1) *... * (a[m] + 1) solutii. (Incerci sa obtii toate combinatiile posibile). Nu exista algoritmi care au complexitatea mai buna decat Backtracking.
Da, asa este, avem nevoie de toate acele solutii, insa in generarea lor trebuie sa incercam cat mai putine care sunt invalide  Very Happy.

Citat
LE: Se pot aplica optimizari, precum cele care le-ai precizat mai sus, dar in fond tot backtracking este  Smile
Prin backtracking inteleg acele metode in care incerci solutii si apoi le verifici. Ideea precizata genereaza direct solutiile bune, fara alte verificari, deci imi suna mai mult a programare dinamica. In fine, e doar terminologie. In final, da, avem nevoie de toate solutiile Very Happy.

Citat
Mai sunt si alte restrictii si precizari?
Nu. Problema nu e din ceva concurs, e din viata reala, deci putem fi flexibili. In final, va trebui sa compar diverse metode pentru a obtine rezultatul si vedem care e mai convenabila in ceea ce priveste timpul de executie si memoria folosita. Daca se poate si paraleliza, ar fi perfect, dar aia nu e o prioritate si ma indoiesc ca se poate Very Happy.
Memorat
tudorv96
Strain


Karma: -6
Deconectat Deconectat

Mesaje: 17



Vezi Profilul
« Răspunde #5 : August 06, 2014, 19:09:33 »

Citat
Prin backtracking inteleg acele metode in care incerci solutii si apoi le verifici.

Da, iei pe rand fiecare combinatie posibila de numere. Insa, pentru a afisa in ordine crescatoare dupa S si pentru a evita solutiile invalide apar niste complicatii.  Confused

O metoda ar fi sa faci pentru toate S-urile un back(int k, int sum, int sum_now) (k ii pozitia curenta pentru care generezi, sum ii suma la care vrei sa se ajunga, sum_now ii suma curenta a numerelor pana la pozitia k-1, inclusiv)
De asemenea, retinerii sumei partiale pentru fiecare element ajuta pentru calcularea mai rapida. (sp[ i ] = sp[ i-1 ] + a[ i ])

pentru fiecare pozitie k va fi un for in care se testeaza elementele:

Cod:
void back(int k, int sum, int sum_now) {
        for(int i = max (0, sum - sum_now - (sp[ m ] - sp[ k ]); i <= min(sum - sum_now, a[ k ]); ++i) {
               v[ k ] = i;
               back(k+1, sum, sum_now + i);
       }
}

max (0, sum - sum_now - (sp[ m ] - sp[ k ]) - verifica cazul in care toate elementele de la k+1 pana la m vor fi maxime, astfel incat sa se evite problema solutiilor invalide (in care suma obinuta in back e mai mica decat ar trebui sa fie)

Nu ar trebui sa se obtina nici duplicate, nici solutii invalide cand ajungi la k maxim.  Cool
Citat
Nu. Problema nu e din ceva concurs, e din viata reala, deci putem fi flexibili.

Orice alta precizare poate modifica radical algoritmul, inclusiv ordinea aceea cand S-urile sunt egale. Smile
Memorat
Pagini: [1]   În sus
  Imprimă  
 
Schimbă forumul:  

Powered by SMF 1.1.19 | SMF © 2006-2013, Simple Machines