Pagini: [1]   În jos
  Imprimă  
Ajutor Subiect: Distante!  (Citit de 3562 ori)
0 Utilizatori şi 1 Vizitator pe acest subiect.
chera_lary
De-al casei
***

Karma: -2
Deconectat Deconectat

Mesaje: 106



Vezi Profilul
« : August 13, 2008, 20:17:03 »

Buna ziua!
Doresc sa stiu cum pot determina lungimea minima dintre doua puncte ale unei matrice tinand cont ca nu te poti deplasa pe diagonala matricei (bidimensionala).
Ex matrice:
1 2 3
4 5 6
7 8 9
Distanta minima din coltul din stanga-sus pana in coltul din dreapta-jos este 21 : 1 -> 2 -> 3 ->6->9
Va multumesc ! Very Happy
« Ultima modificare: August 14, 2008, 21:16:25 de către CHERA Laurentiu » Memorat
Cosmin
Echipa infoarena
Nu mai tace
*****

Karma: 351
Deconectat Deconectat

Mesaje: 1.799



Vezi Profilul
« Răspunde #1 : August 14, 2008, 06:58:38 »

Poti folosi orice algoritm de cautare de drumuri minime.
Memorat
devilkind
Echipa infoarena
Nu mai tace
*****

Karma: 284
Deconectat Deconectat

Mesaje: 1.240



Vezi Profilul
« Răspunde #2 : August 14, 2008, 08:40:36 »

pe ex tau distanta minima nu e 21?? 1 - 2 - 3 - 6 - 9
Memorat
sigrid
De-al casei
***

Karma: 61
Deconectat Deconectat

Mesaje: 129



Vezi Profilul
« Răspunde #3 : August 14, 2008, 09:43:40 »

Ba da  Smile.

Poti folosi algoritmul lui lee. Daca nu stii cu ce se mananca ai aici un articol: http://www.ginfo.ro/revista/15_2/focus1.pdf

Spor.
Memorat
devilkind
Echipa infoarena
Nu mai tace
*****

Karma: 284
Deconectat Deconectat

Mesaje: 1.240



Vezi Profilul
« Răspunde #4 : August 14, 2008, 11:52:05 »

nu poti folosi lee deoarece ai costuri. Poti folosi algoritmul lui Djikstra in schimb.
Memorat
chera_lary
De-al casei
***

Karma: -2
Deconectat Deconectat

Mesaje: 106



Vezi Profilul
« Răspunde #5 : August 14, 2008, 12:13:10 »

Va multumesc pentru ajutor!
Intradevar, distanata minima este 1 -> 2 -> 3 -> 6 -> 9 ! Tongue Imi cer scuze pentru greseala facuta  Rolling Eyes
Memorat
sima_cotizo
Nu mai tace
*****

Karma: 219
Deconectat Deconectat

Mesaje: 596



Vezi Profilul
« Răspunde #6 : August 15, 2008, 14:52:34 »

nu poti folosi lee deoarece ai costuri. Poti folosi algoritmul lui Djikstra in schimb.

popular tot "lee" ii zice Very Happy
Memorat
Marius
Nu mai tace
*****

Karma: 154
Deconectat Deconectat

Mesaje: 572



Vezi Profilul
« Răspunde #7 : August 15, 2008, 15:28:19 »

nu poti folosi lee deoarece ai costuri. Poti folosi algoritmul lui Djikstra in schimb.

În cazul în care ai cost pe noduri poţi folosi o coadă simplă. Şi cred că se numeşte Lee, deşi văd că nu e mare diferenţă de Bellman Ford cu coadă.

Nu prea e pe SGU problema... Smile
« Ultima modificare: August 15, 2008, 18:37:32 de către Marius Stroe » Memorat

Faceti lucrurile simplu: pe cat de simplu posibil, dar nu mai simplu.
sigrid
De-al casei
***

Karma: 61
Deconectat Deconectat

Mesaje: 129



Vezi Profilul
« Răspunde #8 : August 15, 2008, 16:32:27 »

Nu conteaza asa mult cum se numeste  Smile.

Algoritmul este interesant pentru un incepator.
Laurentiu ai reusit sa rezolvi problema?
Memorat
chera_lary
De-al casei
***

Karma: -2
Deconectat Deconectat

Mesaje: 106



Vezi Profilul
« Răspunde #9 : August 16, 2008, 00:53:56 »

Da, am reusit sa rezolv problema! Smile
Va multumesc pentru ajutorul acordat, si pentru ca v-ati implicat! Very Happy
Memorat
Marius
Nu mai tace
*****

Karma: 154
Deconectat Deconectat

Mesaje: 572



Vezi Profilul
« Răspunde #10 : August 16, 2008, 14:43:06 »

În primul rând felicitări. În al doilea rând, ai grijă unde postezi data viitoare. Smile

Iată ce ai pe prima pagină din Index:

Informatica
Informatica, algoritmi, structuri de date, matematica... stii tu Wink
Memorat

Faceti lucrurile simplu: pe cat de simplu posibil, dar nu mai simplu.
chera_lary
De-al casei
***

Karma: -2
Deconectat Deconectat

Mesaje: 106



Vezi Profilul
« Răspunde #11 : August 17, 2008, 15:12:30 »

Am reusit urmatoarea implementare Very Happy :
Matrice :
10 3
1 2 5
1 3 1
0 8 1
10 = suma de bani avuta initial;
n = 3;
Programul afiseaza suma maxima de bani ramasa angajatului dupa ce traverseaza firma de la un birou la altul (1 - stanga sus; la 1-dreapta jos);

Cod:
/*Taxe*/
#include <stdio.h>
#define fin "taxe.in"
#define fout "taxe.out"

int n,s;
long int taxa[10][10];
long int taxaMin[10][10];
long int infinit=1000;

void citeste();
void drum();
int minTaxeVecini(int,int);
int minim(int,int);
void tipar();

void init(){
for(int i=0;i<=n+1;++i)
  for(int j=0;j<=n+1;++j)
    taxaMin[i][j]=infinit;
taxaMin[1][1]=taxa[1][1];
}

void main(){
citeste();
init();
        tipar();
drum();
tipar();
}

void citeste(){
FILE *f=fopen(fin,"rt");
fscanf(f,"%d %d\n",&s,&n);
for(int i=1;i<=n;++i)
  for(int j=1;j<=n;++j)
    fscanf(f,"%d",&taxa[i][j]);
        fclose(f);
}

void drum(){
int i,j,min;
int amOptimizare;

amOptimizare=1;
while(amOptimizare){
  amOptimizare=0;
  for(int i=1;i<=n;++i)
    for(int j=1;j<=n;++j){
      min=minTaxeVecini(i,j);
      if(min+taxa[i][j]<taxaMin[i][j]){
taxaMin[i][j]=min+taxa[i][j];
                amOptimizare=1;
      }
    }
}
if(taxaMin[n][n]<=s)
  printf("%d\n",s-taxaMin[n][n]);
else
  printf("%d\n",-1);
}

int minTaxeVecini(int i, int j){
int min1,min2;
min1=minim(taxaMin[i-1][j],taxaMin[i+1][j]);
        min2=minim(taxaMin[i][j-1],taxaMin[i][j+1]);
        return minim(min1,min2);
}

int minim(int a, int b){
if(a>b) return b;
else return a;
}

void tipar(){
for(int i=1;i<=n;++i){
  for(int j=1;j<=n;++j)
    printf("%d ",taxaMin[i][j]);
  printf("\n");
}
        printf("\n");
}
« Ultima modificare: August 17, 2008, 15:20:12 de către CHERA Laurentiu » Memorat
Marius
Nu mai tace
*****

Karma: 154
Deconectat Deconectat

Mesaje: 572



Vezi Profilul
« Răspunde #12 : August 17, 2008, 20:43:19 »

E corect algoritmul. Dacă iterai while()ul de N2 ori obţineai acelaşi rezultat. Algoritmul se numeşte Bellman Ford. Dar dacă iterezi cât timp mai poţi relaxa, atunci ai o optimizare. Smile Complexitatea lui e O(N4).

Cu algoritmul lui Dijkstra de drumuri minime, poţi obţine complexitatea O(N2 logN2). Mult mai eficient.
Memorat

Faceti lucrurile simplu: pe cat de simplu posibil, dar nu mai simplu.
Dastas
Vorbaret
****

Karma: 11
Deconectat Deconectat

Mesaje: 170



Vezi Profilul
« Răspunde #13 : August 18, 2008, 15:49:34 »

Problema nu merge si cu memoizare?

Fie f(i, j) costul minim pentru a ajunge de la punctul de plecare (x, y) pana in (i, j). f(i, j) = cost[ i ][ j ] + min(f(i+1, j), f(i, j+1), f(i-1, j), f(i, j-1)).

f(x, y) se initializeaza cu cost[ x ][ y ] si eventual mai trebuie avut grija sa nu se apeleze recursiv pentru zone inaccesibile (i, j < 0 etc)

Pare corect. Complexitatea nu ar fi patratica daca se aplica memoizare?
Memorat
chera_lary
De-al casei
***

Karma: -2
Deconectat Deconectat

Mesaje: 106



Vezi Profilul
« Răspunde #14 : August 18, 2008, 16:00:52 »

Metoda pe care ai prezentat-o nu are o eroare? De exemplu:
In matricea,
1 2 5
1 3 1
0 8 1
, algoritmul cand va ajunge in nodul (1,0), nu o sa aleaga intre 3 si 0 pe 0   Rolling Eyes, nodul (2,0) al matricei. In cazul in care va alege nodul (2,0) programul va afisa un rezultat eronat, deoarece drumul minim este : 1->1->3->1->1 si nu 1->1->0->8->1 Smile !
Memorat
Dastas
Vorbaret
****

Karma: 11
Deconectat Deconectat

Mesaje: 170



Vezi Profilul
« Răspunde #15 : August 18, 2008, 17:34:09 »

Tu ai ales minimul dintre valori ale matricii costurilor. Eu am zis ca se alege minimul dintre apeluri recursive.

Uite un program care l-am scris rapid, nu stiu daca e 100% corect, dar pe exemplul tau da corect: 7.

Cod:
int n, m;
int a[maxn][maxn];
int memo[maxn][maxn];
int v[maxn][maxn];

int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};

int back[maxn][maxn];

int go(int x, int y)
{
    if ( memo[x][y] != -1 )
        return memo[x][y];

    if ( v[x][y] )
        return 1 << 29;

    v[x][y] = 1;

    for ( int i = 0; i < 4; ++i )
    {
        int X = x + dx[i];
        int Y = y + dy[i];

        if ( X > 0 && Y > 0 && X <= n && Y <= m )
            if ( go(X, Y) + a[x][y] < memo[x][y] || memo[x][y] == -1 )
                memo[x][y] = go(X, Y) + a[x][y], back[x][y] = i;
    }

    v[x][y] = 0;

    return memo[x][y];
}

int main ()
{
    fscanf(in, "%d %d", &n, &m);

    for ( int i = 1; i <= n; ++i )
        for ( int j = 1; j <= m; ++j )
            fscanf(in, "%d", &a[i][j]), memo[i][j] = -1;

    memo[1][1] = a[1][1];

    printf("%d\n", go(3, 3));

    for ( int i = 1; i <= n; ++i )
    {
        for ( int j = 1; j <= m; ++j )
            printf("%d ", back[i][j]);
        printf("\n");
    }

    return 0;
}
Memorat
Pagini: [1]   În sus
  Imprimă  
 
Schimbă forumul:  

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