20. oktober 2003 - 18:15Der er
34 kommentarer og 1 løsning
Lokal minima
Jeg har nogle store Arrays hvor jeg ønsker at finde de lokale minima. (i et område på f.eks. 10 elementer) Jeg har lavet en simpel løsning som dog køre alt for langsomt. Hvordan gør man dette hurtigt. (Gerne noget kode.)
Det jeg mener med et område på 10 element er følgende.
2,2,2,2,1,2,2,0,2,2,2,2,2,2 Her vil der være et lokalt minima hvis der ses på et område med størrelse 10 og to minimA hvis der ses på et område med størrelse 2
Så er du vel nødt til at løbe arrayet (eller en relevant del af det) igennem og finde alle elementer som er mindre end både det foregående og det næste element.
Det jeg gør nu er at undersøge bare et at de ti omkringlæggende elementer er mindre en det element jeg står med nu. Dette gør jeg for alle mine elementer. Dette betyder at jeg i gennemsnit laver ca. 4*N sammenligninger. Hvilket formentligt ikke er optimalt.
hvis a[i] ikke er et minima så må a[i+1]=a[i] være nok til at afvise at a[i+1] er et minima og det må kunne gøre at du kan nøjes med en sammenligning i de fleste tilfælde
int standard(int *a) { int i, j, res, minima; res = 0; for (i = 5; i < (N - 5); i++) { minima = 1; for (j = (i - 5); j <= (i + 5); j++) { if (a[j] < a[i]) { minima = 0; break; } } if (minima) { res++; } } return res; }
int unrolled(int *a) { int i, res, minima; res = 0; for (i = 5; i < (N - 5); i++) { minima = 1; if (a[i - 5] < a[i]) { minima = 0; } else if (a[i - 4] < a[i]) { minima = 0; } else if (a[i - 3] < a[i]) { minima = 0; } else if (a[i - 2] < a[i]) { minima = 0; } else if (a[i - 1] < a[i]) { minima = 0; } else if (a[i + 1] < a[i]) { minima = 0; } else if (a[i + 2] < a[i]) { minima = 0; } else if (a[i + 3] < a[i]) { minima = 0; } else if (a[i + 4] < a[i]) { minima = 0; } else if (a[i + 5] < a[i]) { minima = 0; } if (minima) { res++; } } return res; }
int main() { int *a, i, n1, n2, t1a, t1b, t2a, t2b; a = (int *)malloc(N*sizeof(int)); srand(12345); for (i = 0; i < N; i++) { a[i] = rand() % 1000; } t1a = clock(); n1 = standard(a); t1b = clock(); printf("%d %d\n",n1,(t1b - t1a)); t2a = clock(); n2 = unrolled(a); t2b = clock(); printf("%d %d\n",n2,(t2b - t2a)); return 0; }
Ja ok, jeg prøver lige at smide den ind i min kode og se om der giver noget. Jeg vender tilbage I overmorgen. Eller i morgen hvis jeg kan komme til en mail
int standard(int *a) { int i, j, res, minima; res = 0; for (i = 5; i < (N - 5); i++) { minima = 1; for (j = (i - 5); j <= (i + 5); j++) { if (a[j] < a[i]) { minima = 0; break; } } if (minima) { res++; } } return res; }
int unrolled(int *a) { int i, res, minima; res = 0; for (i = 5; i < (N - 5); i++) { minima = 1; if (a[i - 5] < a[i]) { minima = 0; } else if (a[i - 4] < a[i]) { minima = 0; } else if (a[i - 3] < a[i]) { minima = 0; } else if (a[i - 2] < a[i]) { minima = 0; } else if (a[i - 1] < a[i]) { minima = 0; } else if (a[i + 1] < a[i]) { minima = 0; } else if (a[i + 2] < a[i]) { minima = 0; } else if (a[i + 3] < a[i]) { minima = 0; } else if (a[i + 4] < a[i]) { minima = 0; } else if (a[i + 5] < a[i]) { minima = 0; } if (minima) { res++; } } return res; }
int smart(int *a) { int i, j, res, minima; res = 0; i = 5; while (i < (N - 5)) { minima = 1; for (j = (i - 5); j <= (i + 5); j++) { if (a[j] < a[i]) { minima = 0; break; } } if (minima) { res++; } j = i + 1; while((j < (i + 5)) && (a[j] > a[i])) j++; i = j; } return res; }
int smartunrolled(int *a) { int i, j, res, minima; res = 0; i = 5; while (i < (N - 5)) { minima = 1; if (a[i - 5] < a[i]) { minima = 0; } else if (a[i - 4] < a[i]) { minima = 0; } else if (a[i - 3] < a[i]) { minima = 0; } else if (a[i - 2] < a[i]) { minima = 0; } else if (a[i - 1] < a[i]) { minima = 0; } else if (a[i + 1] < a[i]) { minima = 0; } else if (a[i + 2] < a[i]) { minima = 0; } else if (a[i + 3] < a[i]) { minima = 0; } else if (a[i + 4] < a[i]) { minima = 0; } else if (a[i + 5] < a[i]) { minima = 0; } if (minima) { res++; } j = i + 1; while((j < (i + 5)) && (a[j] > a[i])) j++; i = j; } return res; }
int main() { int *a, i, n1, n2, n3, n4; int t1a, t1b, t2a, t2b, t3a, t3b, t4a, t4b; a = (int *)malloc(N*sizeof(int)); srand(12345); for (i = 0; i < N; i++) { a[i] = rand() % 1000; } for (i = 0; i < 3; i++) { t1a = clock(); n1 = standard(a); t1b = clock(); printf("standard %d %d\n",n1,(t1b - t1a)); t2a = clock(); n2 = unrolled(a); t2b = clock(); printf("unrolled %d %d\n",n2,(t2b - t2a)); t3a = clock(); n3 = smart(a); t3b = clock(); printf("smart %d %d\n",n3,(t3b - t3a)); t4a = clock(); n4 = smartunrolled(a); t4b = clock(); printf("smart unrolled %d %d\n",n4,(t4b - t4a)); } return 0; }
ok, her er en ide. Jeg ved ikke om det vil være hurtigt. Man løber sit array igennem og indsætter alle lokale minima hvor følgende gælder i et nyt array. a[i-1]>a[i]<a[i+1] hvis dette er Sandt => I[n]=i Herefter løbes det meget minde I[] igennem og hvis a[I[n-1]]>a[I[n]]<a[I[n+1]] og I[n]-I[n-1]>5 && I[n]-I[n+1]>5 må I[n] være et lokalt minima
int standard(int *a) { int i, j, res, minima; res = 0; for (i = 5; i < (N - 5); i++) { minima = 1; for (j = (i - 5); j <= (i + 5); j++) { if (a[j] < a[i]) { minima = 0; break; } } if (minima) { res++; } } return res; }
int unrolled(int *a) { int i, res, minima; res = 0; for (i = 5; i < (N - 5); i++) { minima = 1; if (a[i - 5] < a[i]) { minima = 0; } else if (a[i - 4] < a[i]) { minima = 0; } else if (a[i - 3] < a[i]) { minima = 0; } else if (a[i - 2] < a[i]) { minima = 0; } else if (a[i - 1] < a[i]) { minima = 0; } else if (a[i + 1] < a[i]) { minima = 0; } else if (a[i + 2] < a[i]) { minima = 0; } else if (a[i + 3] < a[i]) { minima = 0; } else if (a[i + 4] < a[i]) { minima = 0; } else if (a[i + 5] < a[i]) { minima = 0; } if (minima) { res++; } } return res; }
int smart(int *a) { int i, j, res, minima; res = 0; i = 5; while (i < (N - 5)) { minima = 1; for (j = (i - 5); j <= (i + 5); j++) { if (a[j] < a[i]) { minima = 0; break; } } if (minima) { res++; } j = i + 1; while((j < (i + 5)) && (a[j] > a[i])) j++; i = j; } return res; }
int smartunrolled(int *a) { int i, j, res, minima; res = 0; i = 5; while (i < (N - 5)) { minima = 1; if (a[i - 5] < a[i]) { minima = 0; } else if (a[i - 4] < a[i]) { minima = 0; } else if (a[i - 3] < a[i]) { minima = 0; } else if (a[i - 2] < a[i]) { minima = 0; } else if (a[i - 1] < a[i]) { minima = 0; } else if (a[i + 1] < a[i]) { minima = 0; } else if (a[i + 2] < a[i]) { minima = 0; } else if (a[i + 3] < a[i]) { minima = 0; } else if (a[i + 4] < a[i]) { minima = 0; } else if (a[i + 5] < a[i]) { minima = 0; } if (minima) { res++; } j = i + 1; while((j < (i + 5)) && (a[j] > a[i])) j++; i = j; } return res; }
int doublearray(int *a) { int *a2,n,i,res; a2 = (int *)malloc(N/2*sizeof(int)); n = 0; for (i = 1; i < (N - 1); i++) { if((a[i - 1] > a[i]) && (a[i] < a[i + 1])) { a2[n] = i; n++; } } res = 0; for (i = 1; i < (n - 1); i++) { if(((a2[i-1] < (a2[i] - 5)) || (a[a2[i]] < a[a2[i-1]])) && (((a2[i] + 5) < a2[i+1]) || (a[a2[i]] < a[a2[i+1]]))) { res++; } } return res; }
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.