Zadatak - rekurzija

poruka: 17
|
čitano: 2.044
|
moderatori: XXX-Man, vincimus
1
+/- sve poruke
ravni prikaz
starije poruke gore
13 godina
neaktivan
offline
Zadatak - rekurzija
Jel bi netko znao riješit ovaj zadatak?

Napišite program koji statički ili dinamički (proizvoljno) alocira matricu 5x5, inicijalizira random brojeve [0,9] u matricu te pronalazi put od vrha do dna tako da suma brojeva na putu bude minimalna. Potrebno je ispisati matricu na konzolu radi kontrole, a nije potrebno ispisati čitav put već samo konačan rezultat. Početak puta unosi korisnik putem konzolnog sučelja tako da unese samo redni broj stupca jer je redak obavezno prvi.
 
0 4 hvala 0
12 godina
neaktivan
offline
Re: Zadatak - rekurzija

U kojem programskom jeziku? :D

13 godina
neaktivan
offline
Re: Zadatak - rekurzija

Evo rješenja u Pythonu 3 (prepisan A* algoritam s Wikipedije)

import random

def valid(v):
    return 0 <= v < 5

def neighbor_nodes(node):
    neighbors = ((node[0] + 1, node[1] - 1),
         (node[0] + 1, node[1]),
         (node[0] + 1, node[1] + 1))
    return (n for n in neighbors if valid(n[0]) and valid(n[1]))

def aStar(A, start):
    openSet = {start}
    closedSet = set()
   
    g_score = {start: 0}

    while openSet:
        current = min(openSet, key=lambda n: g_score[n])
        if current[0] == 4:
            return g_score[current]
       
        openSet.remove(current)
        closedSet.add(current)
        for neighbor in neighbor_nodes(current):
            tentative_g_score = g_score[current] + A[neighbor[0]][neighbor[1]][1]
            if neighbor in closedSet and tentative_g_score >= g_score[neighbor]:
                continue
               
            if (neighbor not in openSet) or tentative_g_score < g_score[neighbor]:
                g_score[neighbor] = tentative_g_score
                openSet.add(neighbor)

    raise Exception('Failure')
       
R = [[((row, col), random.randrange(10)) for col in range(5)] for row in range(5)]

for r in R:
    print([c[1] for c in r])

stupac = int(input('Unesi stupac:'))
if not valid(stupac):
    raise ValueError('Stupac mora biti u intervalu 0-4')

print(aStar(R, (0, stupac)))

Poruka je uređivana zadnji put uto 7.5.2013 22:36 (Bobobo-bo Bo-bobo).
12 godina
neaktivan
offline
Re: Zadatak - rekurzija

C++, nadam se da je to sto ti je trebalo.

 

#include<iostream>

 

using namespace std;

 

void rekurzija (int i,int j,int niz[],int& indeks){

 

   if((((i+1)<5))&&((j)<5)){

     if (niz[i]<niz[j]){

         indeks=i;

         if (~(j+1==5))

           rekurzija(i,j+1,niz,indeks);

           else

           indeks=4;

           }

           else{

               indeks=j;

               if (!(j+1==5))

                 rekurzija(j,j+1,niz,indeks);

                 else

                 indeks=4;

                 }

                 }

 

}

int main(){

int matrica[5][5]={{2,5,1,3,7},{1,4,6,9,2},{3,7,2,5,4},{1,9,3,6,4},{1,1,5,3,2}};

int kolona;

do{

   cout<<"Unesite redni broj kolone, od 0-4!"<<endl;

 

   cin>>kolona;

}

while (kolona>4);

int indeksi[5]; //indeksi kolona na kojima su trazeni clanovi za najmanju sumu ka dnu. Ako zelis mozes ih upariti sa indeksima redova :D

indeksi[0]=kolona;

 

for (int i=1;i<5;i++){

   rekurzija(0,1,matrica[i],indeksi[i]);

}

for (int i=0;i<5;i++)

cout<<indeksi[i]<<"  ";

cout<<endl<<"Matrica:"<<endl;

for (int i=0;i<5;i++){

   for (int j=0;j<5;j++){

     cout<<matrica[i][j]<<"  ";

   }

   cout<<endl;

}

}

13 godina
neaktivan
offline
Re: Zadatak - rekurzija
codebreaker kaže...

C++, nadam se da je to sto ti je trebalo.

 

 

#include<iostream>

 

using namespace std;

 

void rekurzija (int i,int j,int niz[],int& indeks){

 

   if((((i+1)<5))&&((j)<5)){

     if (niz[i]<niz[j]){

         indeks=i;

         if (~(j+1==5))

           rekurzija(i,j+1,niz,indeks);

           else

           indeks=4;

           }

           else{

               indeks=j;

               if (!(j+1==5))

                 rekurzija(j,j+1,niz,indeks);

                 else

                 indeks=4;

                 }

                 }

 

}

int main(){

int matrica[5][5]={{2,5,1,3,7},{1,4,6,9,2},{3,7,2,5,4},{1,9,3,6,4},{1,1,5,3,2}};

int kolona;

do{

   cout<<"Unesite redni broj kolone, od 0-4!"<<endl;

 

   cin>>kolona;

}

while (kolona>4);

int indeksi[5]; //indeksi kolona na kojima su trazeni clanovi za najmanju sumu ka dnu. Ako zelis mozes ih upariti sa indeksima redova :D

indeksi[0]=kolona;

 

for (int i=1;i<5;i++){

   rekurzija(0,1,matrica[i],indeksi[i]);

}

for (int i=0;i<5;i++)

cout<<indeksi[i]<<"  ";

cout<<endl<<"Matrica:"<<endl;

for (int i=0;i<5;i++){

   for (int j=0;j<5;j++){

     cout<<matrica[i][j]<<"  ";

   }

   cout<<endl;

}

}

 

 

 

Zaboravio sam napisat da mi treba u C-u. Ugl hvala, ali nije to to šta bi trebala radit :( Znaci trebali bi na pocetku alocirat matricu 5x5 (dvodimenzionalni niz), onda izaberemo iz koje kolene krecemo i tada ulazimo u petlju(valjda) koja ce trazit najkraci put od vrha prema dolje(npr kao što je na slici) i napisat na kraju da je npr. Najkraci put: 18 i onda provjerimo po matici dal je dobro.

12 godina
neaktivan
offline
Re: Zadatak - rekurzija
Huco23 kaže...
codebreaker kaže...

C++, nadam se da je to sto ti je trebalo.

 

 

#include<iostream>

 

using namespace std;

 

void rekurzija (int i,int j,int niz[],int& indeks){

 

   if((((i+1)<5))&&((j)<5)){

     if (niz[i]<niz[j]){

         indeks=i;

         if (~(j+1==5))

           rekurzija(i,j+1,niz,indeks);

           else

           indeks=4;

           }

           else{

               indeks=j;

               if (!(j+1==5))

                 rekurzija(j,j+1,niz,indeks);

                 else

                 indeks=4;

                 }

                 }

 

}

int main(){

int matrica[5][5]={{2,5,1,3,7},{1,4,6,9,2},{3,7,2,5,4},{1,9,3,6,4},{1,1,5,3,2}};

int kolona;

do{

   cout<<"Unesite redni broj kolone, od 0-4!"<<endl;

 

   cin>>kolona;

}

while (kolona>4);

int indeksi[5]; //indeksi kolona na kojima su trazeni clanovi za najmanju sumu ka dnu. Ako zelis mozes ih upariti sa indeksima redova :D

indeksi[0]=kolona;

 

for (int i=1;i<5;i++){

   rekurzija(0,1,matrica[i],indeksi[i]);

}

for (int i=0;i<5;i++)

cout<<indeksi[i]<<"  ";

cout<<endl<<"Matrica:"<<endl;

for (int i=0;i<5;i++){

   for (int j=0;j<5;j++){

     cout<<matrica[i][j]<<"  ";

   }

   cout<<endl;

}

}

 

 

 

Zaboravio sam napisat da mi treba u C-u. Ugl hvala, ali nije to to šta bi trebala radit :( Znaci trebali bi na pocetku alocirat matricu 5x5 (dvodimenzionalni niz), onda izaberemo iz koje kolene krecemo i tada ulazimo u petlju(valjda) koja ce trazit najkraci put od vrha prema dolje(npr kao što je na slici) i napisat na kraju da je npr. Najkraci put: 18 i onda provjerimo po matici dal je dobro.

Kako mislis najkraci put 18? sta ti to znaci? jel npr kad izaberes kolonu 2 u prvom redu smijes samo provjeravati kolone 1,2,3 u drugom redu kao sto je na slici?

Vise detalja bi bilo pozeljno :D

 

13 godina
neaktivan
offline
Re: Zadatak - rekurzija
codebreaker kaže...
Huco23 kaže...
codebreaker kaže...

C++, nadam se da je to sto ti je trebalo.

 

 

#include<iostream>

 

using namespace std;

 

void rekurzija (int i,int j,int niz[],int& indeks){

 

   if((((i+1)<5))&&((j)<5)){

     if (niz[i]<niz[j]){

         indeks=i;

         if (~(j+1==5))

           rekurzija(i,j+1,niz,indeks);

           else

           indeks=4;

           }

           else{

               indeks=j;

               if (!(j+1==5))

                 rekurzija(j,j+1,niz,indeks);

                 else

                 indeks=4;

                 }

                 }

 

}

int main(){

int matrica[5][5]={{2,5,1,3,7},{1,4,6,9,2},{3,7,2,5,4},{1,9,3,6,4},{1,1,5,3,2}};

int kolona;

do{

   cout<<"Unesite redni broj kolone, od 0-4!"<<endl;

 

   cin>>kolona;

}

while (kolona>4);

int indeksi[5]; //indeksi kolona na kojima su trazeni clanovi za najmanju sumu ka dnu. Ako zelis mozes ih upariti sa indeksima redova :D

indeksi[0]=kolona;

 

for (int i=1;i<5;i++){

   rekurzija(0,1,matrica[i],indeksi[i]);

}

for (int i=0;i<5;i++)

cout<<indeksi[i]<<"  ";

cout<<endl<<"Matrica:"<<endl;

for (int i=0;i<5;i++){

   for (int j=0;j<5;j++){

     cout<<matrica[i][j]<<"  ";

   }

   cout<<endl;

}

}

 

 

 

Zaboravio sam napisat da mi treba u C-u. Ugl hvala, ali nije to to šta bi trebala radit :( Znaci trebali bi na pocetku alocirat matricu 5x5 (dvodimenzionalni niz), onda izaberemo iz koje kolene krecemo i tada ulazimo u petlju(valjda) koja ce trazit najkraci put od vrha prema dolje(npr kao što je na slici) i napisat na kraju da je npr. Najkraci put: 18 i onda provjerimo po matici dal je dobro.

Kako mislis najkraci put 18? sta ti to znaci? jel npr kad izaberes kolonu 2 u prvom redu smijes samo provjeravati kolone 1,2,3 u drugom redu kao sto je na slici?

Vise detalja bi bilo pozeljno :D

 

 

A ovisi, koji je najkraci put, ja sam bezvene npr napisao sta bi na kraju program trebao vratit, Da je ukupni zbroj brojeva nor 16 i da je to najkraci put ako smo krenuli npr iz 3 kolone..ali ovisi, ja radim sa random brojevima u matrici, znači svaki put će biti drugaciji najkraci put. Mora provjeravat, ne znam kako bi obajsnio ako nisi skuzio. Slika je samo primjer.

 

Ako reci da je ovo nasa matrica

 

1  4  5  8  8

1  7  6  0  2

9  7  2  8  2

7  5  2  0  6

0  2  4  6  3

 

i npr krecemo iz trece kolene(od broja 5), i spuštamo se i provjeravamo koji nam je najkraci put. I sad onda on zbraja 5+7=12 pa 5+6=11, 5+0=5 i pamti, pa ide dalje: kod 5+7=12 moze gledat 5+7+9 ili 5+7+7 ili 5+7+2, pa tako provjerava i 5+6+... i 5+0+..., i tako dog ne najde najkraci put, u ovom primjeru 5+0+2+0+3=10. I ispise najkraci put: 10. Ali to je kad krecemo iz kolone 3. Da smo krenuli iz kolone 1, najkraci put bi bio 1+1+7+2+2=13. Kuzis?

12 godina
neaktivan
offline
Re: Zadatak - rekurzija

Skontao sam sad sta hoces, to je cak i lakse nego ovo sto sam ja uradio :D., rjesenje ce biti u toku dana., btw ti se pobrini za to random posto odavno nisam u c-u radio.

13 godina
neaktivan
offline
Re: Zadatak - rekurzija

ok bude, hvala unaprijed!

12 godina
neaktivan
offline
Re: Zadatak - rekurzija

#include<iostream>

 

using namespace std;

 

void rekurzija(int red,int kolona,int matrica[5][5],double& suma){

if(red<5){

   if(kolona-1<0){

     if(matrica[red][kolona]<matrica[red][kolona+1]){

       suma+=matrica[red][kolona];

       rekurzija(red+1,kolona,matrica,suma);

     }

     else{

       suma+=matrica[red][kolona+1];

       rekurzija(red+1,kolona+1,matrica,suma);

     }

   }

   else if(kolona+1==5){

     if(matrica[red][kolona]<matrica[red][kolona-1]){

       suma+=matrica[red][kolona];

       rekurzija(red+1,kolona,matrica,suma);

     }

     else{

       suma+=matrica[red][kolona-1];

       rekurzija(red+1,kolona-1,matrica,suma);

     }

 

   }

   else{

     if(matrica[red][kolona]<matrica[red][kolona+1]){

       if(matrica[red][kolona]<matrica[red][kolona-1]){

         suma+=matrica[red][kolona];

         rekurzija(red+1,kolona,matrica,suma);

       }

       else{

         suma+=matrica[red][kolona-1];

         rekurzija(red+1,kolona-1,matrica,suma);

       }

     }

     else {

       if(matrica[red][kolona+1]<matrica[red][kolona-1]){

         suma+=matrica[red][kolona+1];

         rekurzija(red+1,kolona+1,matrica,suma);

       }

       else{

         suma+=matrica[red][kolona-1];

         rekurzija(red+1,kolona-1,matrica,suma);

       }

     }

   }

 

 

 

}

 

}

 

int main(){

   int mat[5][5]={{1,2,3,4,5},{0,2,4,7,8},{1,4,2,7,1,},{0,4,7,8,4},{1,3,4,7,9}};

   unsigned int kolona;

   do{

   cout<<"Unesite redni broj kolone!!"<<endl;

   cin>>kolona;

   } while(kolona>4);

   double najmanja=mat[0][kolona];

   rekurzija(1,kolona,mat,najmanja);

   for (int i=0;i<5;i++){

   for (int j=0;j<5;j++)

   cout<<mat[i][j]<<"  ";

   cout<<endl;

   }

   cout<<"najmanja suma: "<<najmanja;

}

 

Poslao sam ti i PM al haman nisi procitao ili nisi dobio :D

13 godina
neaktivan
offline
Re: Zadatak - rekurzija
codebreaker kaže...

 

#include<iostream>

 

using namespace std;

 

void rekurzija(int red,int kolona,int matrica[5][5],double& suma){

if(red<5){

   if(kolona-1<0){

     if(matrica[red][kolona]<matrica[red][kolona+1]){

       suma+=matrica[red][kolona];

       rekurzija(red+1,kolona,matrica,suma);

     }

     else{

       suma+=matrica[red][kolona+1];

       rekurzija(red+1,kolona+1,matrica,suma);

     }

   }

   else if(kolona+1==5){

     if(matrica[red][kolona]<matrica[red][kolona-1]){

       suma+=matrica[red][kolona];

       rekurzija(red+1,kolona,matrica,suma);

     }

     else{

       suma+=matrica[red][kolona-1];

       rekurzija(red+1,kolona-1,matrica,suma);

     }

 

   }

   else{

     if(matrica[red][kolona]<matrica[red][kolona+1]){

       if(matrica[red][kolona]<matrica[red][kolona-1]){

         suma+=matrica[red][kolona];

         rekurzija(red+1,kolona,matrica,suma);

       }

       else{

         suma+=matrica[red][kolona-1];

         rekurzija(red+1,kolona-1,matrica,suma);

       }

     }

     else {

       if(matrica[red][kolona+1]<matrica[red][kolona-1]){

         suma+=matrica[red][kolona+1];

         rekurzija(red+1,kolona+1,matrica,suma);

       }

       else{

         suma+=matrica[red][kolona-1];

         rekurzija(red+1,kolona-1,matrica,suma);

       }

     }

   }

 

 

 

}

 

}

 

int main(){

   int mat[5][5]={{1,2,3,4,5},{0,2,4,7,8},{1,4,2,7,1,},{0,4,7,8,4},{1,3,4,7,9}};

   unsigned int kolona;

   do{

   cout<<"Unesite redni broj kolone!!"<<endl;

   cin>>kolona;

   } while(kolona>4);

   double najmanja=mat[0][kolona];

   rekurzija(1,kolona,mat,najmanja);

   for (int i=0;i<5;i++){

   for (int j=0;j<5;j++)

   cout<<mat[i][j]<<"  ";

   cout<<endl;

   }

   cout<<"najmanja suma: "<<najmanja;

}

 

 

Poslao sam ti i PM al haman nisi procitao ili nisi dobio :D

 

Nije to to, krivo radli, ali svejedno hvala na pokušaju. Neću te više gnjavit, budem se nekako snašao.

Hvala na trudu!

12 godina
neaktivan
offline
Re: Zadatak - rekurzija

Radi kako treba

za kolona 0:

1,2,3,4,5

0,2,4,7,8

1,4,2,7,1,

0,4,7,8,4

1,3,4,7,9 

rjesenje 3:

bold-te provjerava

underline=koji su manji


kolona 1:

1,2,3,4,5

0,2,4,7,8

1,4,2,7,1,

0,4,7,8,4

1,3,4,7,9 

 

rjesenje:4

 

kolona 2:

 

1,2,3,4,5

0,2,4,7,8

1,4,2,7,1,

0,4,7,8,4

1,3,4,7,9 

 

rjesenje: 7

kolona 3:

 

1,2,3,4,5

0,2,4,7,8

1,4,2,7,1,

0,4,7,8,4

1,3,4,7,9 

 

rjesenje: 15

 

kolona 4:

1,2,3,4,5

0,2,4,7,8

1,4,2,7,1,

0,4,7,8,4

1,3,4,7,9 

 

rjesenje : 24

probaj unijeti onu sto si postavio i provjeri jel radi. 

 

13 godina
neaktivan
offline
Re: Zadatak - rekurzija

Algoritam ti ne radi jer odabireš najmanjeg susjeda na slijedećem nivou. To slučajno prolazi kod matrice iz primjera, ali nastaje problem kad matrica izgleda ovako:

 

0  0  0  0  0
9  9  9  8  9
0  9  9  8  9
0  9  9  8  9
0  9  9  8  9

 

Ako se odabere stupac 2 tvoj program izbacuje da je najmanja suma 32 jer odabire ovakav put:

 

0  0 0  0  0
9  9  9 8  9
0  9  9 8  9
0  9  9 8  9
0  9  9 8  9

 

Pravo rješenje je 9, uz ovakav put:

 

0  0 0  0  0
9  9  8  9
0  9  9  8  9
0  9  9  8  9
0  9  9  8  9

 

Primjer rješenja U Pythonu 3:

 

def minimalna_suma(row, col, A):
    if row == 4:
        # suma 4. retka je vrijednost stupca
        return A[row][col]
    else:
        # susjedni stupci su (col-1, col, col+1), paziti da se ne pređe rub matrice
        susjedi = (i for i in (col - 1, col, col + 1) if 0 <= i < 5)

        # suma je vrijednost stupca + najmanja suma susjeda iz slijedećeg retka
        return A[row][col] + min(minimalna_suma(row + 1, c, A) for c in susjedi)

# testna matrica
M = [[0,0,0,0,0],
    [9,9,9,8,9],
     [0,9,9,8,9],
     [0,9,9,8,9],
    [0,9,9,8,9]]
# ispis
for r in range(5):
    print(' '.join(str(M[r][c]) for c in range(5)))

kolona = int(input('Stupac:'))
print(minimalna_suma(0, kolona, M))

Poruka je uređivana zadnji put pon 13.5.2013 19:53 (Bobobo-bo Bo-bobo).
12 godina
neaktivan
offline
Re: Zadatak - rekurzija

Ja sam algoritam po slici radio na nacin da trazim najmanjeg ispod trazene kolone. Po slici nisam nikako mogao zakljuciti drugacije.

13 godina
neaktivan
offline
Re: Zadatak - rekurzija

U tekstu piše da se traži algoritam koji "pronalazi put od vrha do dna tako da suma brojeva na putu bude minimalna".

 

Ja sam u prvom rješenju napravio suprotnu grešku. Pročitao sam tekst, ali nisam pogledao sliku - mislio sam da su na putu dozvoljeni pomaci gore/dolje/lijevo/desno, a ne samo na donje susjede.

12 godina
neaktivan
offline
Re: Zadatak - rekurzija

Znas li mozda kako se zove ovaj metod ili sta je vec da malo googlam :)

Uglavnom to sto si uradio u phyton-u prebaci u c i to je to. Kao sto sam i rekao ja sam razumio da trazis najmanjeg ispod no ispade da sam pogresno razumio. 

13 godina
neaktivan
offline
Zadatak - rekurzija

 

Bobobo-bo Bo-bobo je u pravu! To sam ti htio reci..

 

npr ovako:

 

#include <stdio.h>

#include <stdlib.h>

#include <malloc.h>

#include <time.h>

 

 

#define DEFAULT 5

 

int racunaj(int redak, int stupac, int *p, int n)

{

int min = 0;

int iduci_stupac = stupac;

 

if(stupac > 0 && stupac < n)

{

min = p[n*redak + stupac - 1];

--iduci_stupac;

if(p[n*redak + stupac] < min)

{

min = p[n*redak + stupac];

++iduci_stupac;

}

if(p[n*redak + stupac + 1] < min)

{

min = p[n*redak + stupac + 1];

iduci_stupac+=2;

}

}

 

else if(stupac == 0)

{

min = p[n*redak + stupac];

if(p[n*redak + stupac + 1] < min)

{

min = p[n*redak + stupac + 1];

iduci_stupac++;

}

}

 

else if(stupac == n)

{

min = p[n*redak + stupac - 1];

--iduci_stupac;

if(p[n*redak + stupac] < min)

{

min = p[n*redak + stupac];

++iduci_stupac;

}

}

else return 0;

 

printf("min= %d\n", min);

 

if(redak == (n - 1)) return min;

else if(redak < (n-1)) return min + racunaj(redak+1, iduci_stupac, p, n);

else return 0;

}

 

int main()

{

float broj;

int *p, n;

n = DEFAULT;

p = (int *) malloc (n * n * sizeof (int));

 

if (p == NULL) printf("Nema dovoljno memorije za ucitati matricu");

else

{

int i, j, redak, stupac, suma = 0;

 

srand ((unsigned) time(NULL) );

 

for(i=0;i<n;i++)

for(j=0;j<n;j++)

{

broj = (float) rand()/(RAND_MAX+1)*10;

p[i*n + j] = (int) broj;

}

 

for(i=0;i<n;i++)

{

for(j=0;j<n;j++)

{

printf("%d\t", p[i*n + j]); 

}

printf("\n\n\n");

}

 

printf("Unesite pocetni stupac (1 - 5):\t");

scanf("%d", &stupac);

stupac -= 1;

printf("Vrijednost stupca je %d\n", p[stupac]);

if(stupac < 0 || stupac > 4)

{

printf("Ne valja!\n\n");

free(p);

return 0;

}

redak = 1;

suma += p[stupac];

suma += racunaj(redak, stupac, p, n);

printf("Minimalna suma: %d\n\n", suma);

}

free(p);

return 0;

}

 

 

Samo što ovdje ima grešku da nema granice za matricu kad se izabare 4 ili 5 kolona.. 

 

Poruka je uređivana zadnji put uto 14.5.2013 12:14 (Huco23).
 
0 0 hvala 0
1
Nova poruka
E-mail:
Lozinka:
 
vrh stranice