2016-02-22 12 views
5

Lấy một tập hợp ngẫu nhiên các tọa độ (x, y, z) sẽ là trung tâm của ma trận 3x3x3 của tôi (được coi là tối thiểu cục bộ). Tôi có một hàm J lấy các toạ độ đó, tính toán và trả về cho tôi một số. Nếu bất kỳ trong số 26 điểm đó sẽ nhỏ hơn, đó sẽ là trung tâm cho matrice tiếp theo của tôi. Trong trường hợp tôi không tìm thấy một giá trị nhỏ hơn, bán kính của matrice được tăng lên 1, và chúng tôi chạy vòng lặp một lần nữa. Câu hỏi của tôi là: làm thế nào để lặp lại chỉ thông qua "vỏ" của khối lập phương và không gọi hàm cho các giá trị được kiểm tra trước đó?Matlab Đối với vòng lặp chỉ cho "vỏ" của ma trận

Tôi đã cố gắng minh họa nó bên dưới (trong 2d ở đây, nhưng bạn nhận được điểm) .. các dấu chấm là các giá trị được kiểm tra, "?" là những cái cần được tính toán và so sánh với min cục bộ.

enter image description here

đây là mã

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

Có vẻ như bạn đang cố gắng thực hiện một số tối ưu hóa. Bạn đã cân nhắc sử dụng chức năng 'MATLAB' có sẵn, chẳng hạn như [' fminsearch'] (http://www.mathworks.com/help/matlab/ref/fminsearch.html?requestedDomain=www.mathworks.com)? –

+0

@ Jeff Irwin Sửa tôi nếu tôi sai, nhưng với fminsearch hoặc bất kỳ phương pháp tối ưu hóa nào khác, bạn không cần phải có tất cả các biến trước khi hoạt động trên chúng? Chức năng của tôi là lồi (không hoàn hảo!, Đó là lý do tại sao tôi sử dụng biến cấp .. nếu tôi tăng bán kính 10 lần, đó là 21x21x21 và tôi không tìm thấy một biến nhỏ hơn min địa phương, tôi kết luận đó là min toàn cầu) và tôi đang thực hiện các bước nhỏ hướng tới mức tối thiểu toàn cầu mà không tính tất cả các giá trị – Mike

+1

Tôi không chắc chắn ý của bạn là "có tất cả các biến". fminsearch đánh giá chức năng của bạn khi nó đi. Bạn không cần phải đánh giá hàm trước thời hạn. Một số thuật toán tối ưu hóa cũng cần phải đánh giá độ dốc của hàm, nhưng fminsearch không cần gradient. –

Trả lời

1

Đây là một C đơn giản ++ giải pháp

Đây là một 5x5x5 khối đại diện 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 

Và đây là mã cho khối phân tích cú pháp:

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

Bạn có thể sử dụng chỉ mục hợp lý, tôi không chắc chắn tuy nhiên nếu bạn sẽ đạt được tốc độ bằng cách làm như vậy. Việc xây dựng lại vị trí của min là một chút khó xử, nhưng như thế này bạn sẽ thoát khỏi tất cả các vòng lặp.

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

Dưới đây là một cách để bạn có thể đạt được tất cả các "vỏ" các yếu tố trong một vòng lặp duy nhất:

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 

Lưu ý rằng các yếu tố góc được đạt hơn một lần. ma trận kết quả:

>> 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

Dựa trên logic này tôi đã tìm thấy giải pháp của mình, cảm ơn :) – Mike

+0

Tuyệt vời! Vui vì nó đã giúp – wdickerson

Các vấn đề liên quan