2016-02-22 31 views
5

Weź losowy zestaw współrzędnych (x, y, z), który będzie centrum mojej macierzy 3x3x3 (również uważane za lokalne minimum). Mam funkcję J, która przyjmuje te współrzędne, wykonuje obliczenia i zwraca mi liczbę. Jeśli którykolwiek z tych 26 punktów będzie mniejszy, będzie to centrum mojego następnego macierzy. W przypadku, gdy nie znajdę mniejszej wartości, promień matrycy zostanie zwiększony o 1, a my uruchomimy pętlę ponownie. Moje pytanie brzmi: jak zapętlić tylko przez "powłokę" kostki i nie wywołać funkcji dla wcześniej testowanych wartości?Matlab Dla pętli tylko dla "powłoki" macierzy

Próbowałem zilustrować to poniżej (tutaj jest tutaj 2d, ale dostajesz punkt) .. kropki to wartości, które zostały przetestowane, "?" to te, które należy obliczyć i porównać z lokalnym min.

enter image description here

oto kod

minim=100; 

%%the initial size of the search matrix 2*level +1 
level=1; 
x=input('Enter the starting coordinate for X : '); 
y=input('Enter the starting coordinate for Y : '); 
z=input('Enter the starting coordinate for Z : '); 

%%The loop 
if(level<=10) 
for m=x-level:x+level 
    for n=y-level:y+level 
     for p=z-level:z+level 
      A(m,n,p)=J(m,n,p); 
      if A(m,n,p)<minim 
       minim=A(m,n,p); 
       x=m;y=n;z=p; 
       level=1; 
      else 
       level=level+1; 

       %<<----shell loop here ---->> 

      end 

     end 
    end 
    end 
else 

%Display global min 
display(minim, 'Minim'); 
%Coordinates of the global min 
[r,c,d] = ind2sub(size(A),find(A ==minim)); 

display(r,'X'); 
display(c,'Y'); 
display(d,'Z'); 
end 
+0

Wygląda na to, że próbujesz przeprowadzić optymalizację. Czy rozważałeś użycie wbudowanej funkcji 'MATLAB', takiej jak [' fminsearch'] (http://www.mathworks.com/help/matlab/ref/fminsearch.html?requestedDomain=www.mathworks.com)? –

+0

@Jeff Irwin Popraw mnie, jeśli się mylę, ale przy użyciu fminsearch lub innych metod optymalizacji, czy nie musisz mieć wszystkich zmiennych, zanim zaczniesz na nich działać? Moja funkcja jest wypukła (nie jest idealna !, dlatego użyłem zmiennej poziomu, jeśli zwiększam promień 10 razy, to jest 21x21x21 i nie znajduję innej zmiennej mniejszej niż lokalna min, stwierdzam, że jest to min globalny) i robię małe kroki w kierunku globalnego minimum bez obliczania wszystkich wartości – Mike

+1

Nie jestem pewien, co masz na myśli przez "masz wszystkie zmienne". fminsearch ocenia twoją funkcję. Nie musisz oceniać funkcji z wyprzedzeniem. Niektóre algorytmy optymalizacji muszą również oceniać gradient funkcji, ale fminsearch nie potrzebuje gradientu. –

Odpowiedz

1

Oto proste C++ roztwór

To 5x5x5 kostka reprezentowane 2D:

a[i][j][0] 
1 1 1 1 1 
1 1 1 1 1 
1 1 1 1 1 
1 1 1 1 1 
1 1 1 1 1 

a[i][j][1] 
1 1 1 1 1 
1 0 0 0 1 
1 0 0 0 1 
1 0 0 0 1 
1 1 1 1 1 

a[i][j][2] 
1 1 1 1 1 
1 0 0 0 1 
1 0 0 0 1 
1 0 0 0 1 
1 1 1 1 1 

a[i][j][3] 
1 1 1 1 1 
1 0 0 0 1 
1 0 0 0 1 
1 0 0 0 1 
1 1 1 1 1 

a[i][j][4] 
1 1 1 1 1 
1 1 1 1 1 
1 1 1 1 1 
1 1 1 1 1 
1 1 1 1 1 

A oto kod kostki parsowania:

int a[5][5][5] 
int matrix_size = 2*level+1; 

for(int z=0;z<matrix_size;z++) 

if(z==0 || z= matrix_size-1) 
{ 
    for(int i=0;i<matrix_size-1;i++) 
     for(int j=0;j<matrix_size-1;j++) 
      { 
       //compare minim with a[i][j][z]; 
      } 
} 
else 
    for(int i=0;i<matrix_size-1;i++) 
     { 
      if(i==1 || i==matrix_size-1) 
       { 
        for(int j=0;j<matrix_size-1;j++) 
         //compare minim with a[i][j][z]; 
       } 
      else 
       { 
        //compare minim with a[i][1][z] and a[i][matrix_size-1][z]; 
       } 
     } 
1

Można użyć logicznego indeksowania, nie jestem pewien, ale jeśli zyskasz szybkość w ten sposób. Rekonstrukcja położenia min jest nieco niezręczna, ale w ten sposób pozbędziesz się wszystkich pętli for.

A = rand(7,7,7); 
%"shell" mask for extraction 
B = ones(5,5,5); 
B = padarray(B,[1,1,1]); 
B = logical(abs(B-1)); 

[val, ind] = min(A(B)) 

%reconstruct location 
tmp = zeros(1,sum(B(:))); 
tmp(ind) = 1; 
C = zeros(size(A)); 
C(B) = tmp; 
[~, ind] = max(C(:)); 
[r,c,d] = ind2sub(size(A),ind); 
1

Oto jeden sposób można dotrzeć do wszystkich „shell” elementów w jednej pętli:

clear; 
%// a cube matrix to play with 
A=nan(5,5,5); 

n=length(A(:,1,1)); %// Assuming cube matrix 
%// lets change all ot the "shell" elements to 1 
for i=1:n 
     % 1st and nth level 
     A(1,i,1)=1; 
     A(i,1,1)=1; 
     A(n,i,1)=1; 
     A(i,n,1)=1; 
     A(1,i,n)=1; 
     A(i,1,n)=1; 
     A(n,i,n)=1; 
     A(i,n,n)=1; 

     % 2nd to (n-1)th level 
     A(1,1,i)=1; 
     A(1,n,i)=1; 
     A(n,1,i)=1; 
     A(n,n,i)=1; 
end 

Należy pamiętać, że elementy narożne osiągnął więcej niż jeden raz. uzyskaną macierz:

>> A 
A(:,:,1) = 
    1  1  1  1  1 
    1 NaN NaN NaN  1 
    1 NaN NaN NaN  1 
    1 NaN NaN NaN  1 
    1  1  1  1  1 

A(:,:,2) = 
    1 NaN NaN NaN  1 
    NaN NaN NaN NaN NaN 
    NaN NaN NaN NaN NaN 
    NaN NaN NaN NaN NaN 
    1 NaN NaN NaN  1 

A(:,:,3) = 
    1 NaN NaN NaN  1 
    NaN NaN NaN NaN NaN 
    NaN NaN NaN NaN NaN 
    NaN NaN NaN NaN NaN 
    1 NaN NaN NaN  1 

A(:,:,4) = 
    1 NaN NaN NaN  1 
    NaN NaN NaN NaN NaN 
    NaN NaN NaN NaN NaN 
    NaN NaN NaN NaN NaN 
    1 NaN NaN NaN  1 

A(:,:,5) = 
    1  1  1  1  1 
    1 NaN NaN NaN  1 
    1 NaN NaN NaN  1 
    1 NaN NaN NaN  1 
    1  1  1  1  1 
+0

Na podstawie tej logiki znalazłem moje rozwiązanie, dzięki :) – Mike

+0

Świetnie! Cieszę się, że to pomogło – wdickerson