2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 рекурсия в матлабе
Сообщение23.06.2007, 11:13 


26/05/06
44
Добрый день

что то я запутался с рекурсией в матлабе

задача такая: есть матрица из нулей допустим 10х10

часть матрицы заполнена единицами
\[\begin{pmatrix}0 & 0 & 0  & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\    
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\   
 0 &  1  &    1  &   1 & 0 & 0 & 1 & 1  & 0 & 0 \\
 0 & 1 & 1 & 1 & 1 & 1 & 1 & 1 & 1 & 0 \\
 0 & 1 & 1 & 1 & 1 & 1 & 1 & 1 & 1 & 0 \\
 0 & 1 & 1 & 1 & 1 & 1 & 1 & 1 & 1  & 0 \\
 0 & 1 & 1 & 1 & 0 & 0 & 0 & 0 & 0 & 0  \\
 0 & 1 & 1  & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
\end{pmatrix}\]
единицы образуют внутри матрицы какуе-то произвольную фигуру

мне надо с помощью рекурсии заполнить фигуру из единиц например тройками

делаю так

>>find_pattern(4,4,matrix,3)
Код:
function z=find_pattern(i,j,M,X)

M=double(M);

if( M(i,j) == 1 )

   M(i,j)= X;
 
 
if(M(i-1,j)==1 ) z=find_pattern(i-1,j,M,X); end
if(M(i+1,j)==1 ) z=find_pattern(i+1,j,M,X); end
if(M(i,j-1)==1 ) z=find_pattern(i,j-1,M,X); end
if(M(i,j+1)==1 ) z=find_pattern(i,j+1,M,X);  end


if ( M(i-1,j)==0   |  M(i+1,j)==0    |  M(i,j-1)==0   |  M(i,j+1)==0 )     

   z=M;

end


подскажите плиз
как воплотить

 Профиль  
                  
 
 
Сообщение23.06.2007, 14:04 
Экс-модератор
Аватара пользователя


23/12/05
12063
в данном, конкретном случае, я бы просто умножил матрицу на 3. Знать бы условия поподробнее: почему именно рекурсия, например.

А вообще, когда-то я делал рекурсию - нормально получалось все, если рекурсивный вызов осуществлял посредством feval()

 Профиль  
                  
 
 
Сообщение23.06.2007, 16:46 


26/05/06
44
Цитата:
я бы просто умножил матрицу на 3

не все так просто
я показал частный случай

общая задача такова:
дана матрица из нулей большого размера
в которой есть области из единиц не связанных между собой
мне надо обозначить области разными цифрами

вижу единственное решение
решить через рекурсию :roll:

 Профиль  
                  
 
 
Сообщение23.06.2007, 17:10 
Экс-модератор
Аватара пользователя


23/12/05
12063
тогда несколько моментов:
1) попробуйте, как я сказал, вызывать свою функцию через feval(), , если ругает, что с рекурсией что-то не то
2) нет необходимости сравнивать с единицей, можно в качестве условия просто писать if M(i,j)
3) я не совсем понимаю последнее условие: Вы записываете свою модифицированную матрицу в случае, если хоть один из соседей 0, может быть лучше, если ни одной единицы? Там же могут быть всякие Ваши тройки или что еще, на что Вы будете менять
4) Нужно добавить условия для элементов, расположенных на краях, иначе выскочите за край матрицы при попытке найти соседей

 Профиль  
                  
 
 
Сообщение23.06.2007, 17:33 


26/05/06
44
1)спасибо попробую
2) спасибо
3)это как бы частный случай я передаю рекурсии найденную область
и она должна заполнить ее тройками например
если все соседи нули значит что нечего заменять
4) я это учел но покамись для простоты рассматриваю более простой вариант что на границе только нули

 Профиль  
                  
 
 
Сообщение23.06.2007, 17:58 
Экс-модератор
Аватара пользователя


23/12/05
12063
Invisible писал(а):
3)это как бы частный случай я передаю рекурсии найденную область
и она должна заполнить ее тройками например
если все соседи нули значит что нечего заменять



последнее условие у Вас не "если все соседи нули" написано, а "если хотя бы один из соседей - ноль"

Я бы записал его как "если все соседи не единицы", потому что, если уже поменяли раньше, то тоже менять не надо - иначе Вы не выйдете из рекурсии:

Код:
if (M(i-1,j)-1)  &  (M(i+1,j)-1)  &  (M(i,j-1)-1)  &  (M(i,j+1)-1)

 Профиль  
                  
 
 
Сообщение23.06.2007, 18:06 


26/05/06
44
photon

сделал как вы сказали

взял матрицу
>>find_pattern(4,4,matrix,3)
Код:

     0     0     0     0     0     0     0     0     0     0
     0     1     1     1     0     0     0     0     0     0
     0     1     1     1     1     1     1     1     1     0
     0     1     1     1     1     1     1     1     1     0
     0     1     1     1     1     1     1     1     1     0
     0     1     1     1     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0


получилось

Код:
 
     0     0     0     0     0     0     0     0     0     0
     0     1     1     1     0     0     0     0     0     0
     0     1     1     1     1     1     1     1     1     0
     0     1     1     3     3     3     3     3     3     0
     0     3     3     3     3     3     3     3     3     0
     0     3     3     3     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0

почему не полностью заполнилась?

 Профиль  
                  
 
 
Сообщение23.06.2007, 18:47 
Экс-модератор
Аватара пользователя


23/12/05
12063
А я сделал :)

1) Заберу свои слова насчет if обратно - заходит в if, если там не 0, т.е. если, скажем 5, то тоже заходит
2) Заменило не все, потому что Вы меняли локальную переменную, надо объявить М глобальной и тогда все срабатывает
Код:
function z=find_pattern(i,j,M,X)
global M

if M(i,j)==1
   M(i,j)= X;
end

if M(i-1,j)==1 z=feval('find_pattern',i-1,j,M,X); end
if M(i+1,j)==1 z=feval('find_pattern',i+1,j,M,X); end
if M(i,j-1)==1 z=feval('find_pattern',i,j-1,M,X); end
if M(i,j+1)==1 z=feval('find_pattern',i,j+1,M,X); end


if (M(i-1,j)-1)  &  (M(i+1,j)-1)  &  (M(i,j-1)-1)  &  (M(i,j+1)-1)     

   z=M;

end

 Профиль  
                  
 
 
Сообщение23.06.2007, 18:57 


26/05/06
44
у меня после этой функции матлаб в цикл вошел

Код:
Error in ==> find_pattern at 9
if M(i+1,j)==1 z=feval('find_pattern',i+1,j,M,X); end

Error in ==> find_pattern at 8
if M(i-1,j)==1 z=feval('find_pattern',i-1,j,M,X); end

Error in ==> find_pattern at 8
if M(i-1,j)==1 z=feval('find_pattern',i-1,j,M,X); end


пару минут ошибки эти крутил)))

из за чего может быть?

Добавлено спустя 2 минуты 54 секунды:

мне кажется это его из за global M
так глючит
может быть?

еще вопрос, если я объявляю матрицу глобальной
я могу не передовать ее каждый раз через функцию рекурсии?

так как если матрица будет очень большая матлаб просто заклинит :roll:

 Профиль  
                  
 
 
Сообщение23.06.2007, 19:05 
Экс-модератор
Аватара пользователя


23/12/05
12063
Invisible писал(а):
у меня после этой функции матлаб в цикл вошел

Код:
Error in ==> find_pattern at 9


так как если матрица будет очень большая матлаб просто заклинит :roll:


Не знаю :( - у меня-то все нормально отработало, только выдает предупреждения о том, что значение локальной переменной меняется на значение глобальной, но это можно отключить... Кстати, раз уж объявили как глобальную, то можно не передавать ее как аргумент...

 Профиль  
                  
 
 
Сообщение23.06.2007, 19:24 


26/05/06
44
вроде перезагрузил стал нормально
вашу фугкцию исполнять

я пытаюсь сделать чтоб матрица была глобальной
Код:
function z=find_pattern(i,j,X)


M= logical([ ...
         0     0     0     0     0     0     0     0     0     0
     0     1     1     1     0     0     0     0     0     0
     0     1     1     1     1     1     1     1     1     0
     0     1     1     1     1     1     1     1     1     0
     0     1     1     1     1     1     1     1     1     0
     0     1     1     1     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
]);

  global M
 

if( M(i,j) == 1 )

   M(i,j)= X;


     if M(i-1,j)==1 z=feval('find_pattern',i-1,j,X); end
   if M(i+1,j)==1 z=feval('find_pattern',i+1,j,X); end
   if M(i,j-1)==1 z=feval('find_pattern',i,j-1,X); end
   if M(i,j+1)==1 z=feval('find_pattern',i,j+1,X); end

if (M(i-1,j)-1)  &  (M(i+1,j)-1)  &  (M(i,j-1)-1)  &  (M(i,j+1)-1)     
     
   z=M;

end

end


выдает:

>> find_pattern(4,4,3)
Warning: The value of local variables may have been changed to match the
globals. Future versions of MATLAB will require that you declare
a variable to be global before you use that variable.
> In find_pattern at 18

 Профиль  
                  
 
 
Сообщение23.06.2007, 19:40 
Экс-модератор
Аватара пользователя


23/12/05
12063
Ну это не ошибка, а предупреждение

напишите global M вне функции, там же ее инициализируйте, а внутри функции оставить только global M.

 Профиль  
                  
 
 
Сообщение29.06.2007, 17:08 


26/05/06
44
я все еще мучаюсь :)





Код:
function sol=es()

X=2;

M = [ ...
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0
    0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0
    0 0 0 1 1 1 0 0 0 0 1 1 0 0 0 1 0 1 1 1 1 1 1 0 0 0 0 0
    0 0 0 1 1 1 0 0 0 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    ];

global M;

[a b]=size(M);
for v=1:a
    for w=1:b
       
if ( M(v,w) == 1 )

M

find_pattern(v,w,X);
X=X+1;

end
    end
end


Код:

function z=find_pattern(i,j,X)

global M;

if( M(i,j) == 1 )

   M(i,j)= X

   if M(i-1,j)==1 z=feval('find_pattern',i-1,j,X); end
   if M(i+1,j)==1 z=feval('find_pattern',i+1,j,X); end
   if M(i,j-1)==1 z=feval('find_pattern',i,j-1,X); end
   if M(i,j+1)==1 z=feval('find_pattern',i,j+1,X); end

if (M(i-1,j)-1)  &  (M(i+1,j)-1)  &  (M(i,j-1)-1)  &  (M(i,j+1)-1)     
     
   z=M;

end
   z=M

end


матлаб ругается
??? One or more output arguments not assigned during call to 'C:\MATLAB7\work\EX3\es.m (es)'.

что делать как быть?
вроде функции правильные ....

 Профиль  
                  
 
 
Сообщение29.06.2007, 17:58 
Экс-модератор
Аватара пользователя


23/12/05
12063
Invisible писал(а):
что делать как быть?
вроде функции правильные ....


:( Я один-в-один копирую Ваши функции и все нормально отрабатывает

И еще, я бы сначала объявлял global M, а уже потом инициализировал, либо делал clear М по выходу, иначе, при повторном запуске функция не отработает: Вы зададите M локально, а потом перетрете его глобальным - тем, что был после предыдущего запуска

 Профиль  
                  
 
 
Сообщение29.06.2007, 18:37 


26/05/06
44
Цитата:
я бы сначала объявлял global M, а уже потом инициализировал,

спасибо за совет так и сделал

попробуйте запустить функцию используя это изображение:


Код:
function sol=es()

global M;

X=2;

M=imread('Ttext1.tif');

[a b]=size(M);
for v=1:a
    for w=1:b
       
if ( M(v,w) == 1 )

M;

%[x y]=find(M==1);

%[xn yn]=max([x y]);


find_pattern(v,w,X);
X=X+1;

end
    end
end

sol=M;



Код:
function z=find_pattern(i,j,X)

global M;

if( M(i,j) == 1 )

   M(i,j)= X;

   if M(i-1,j)==1 z=feval('find_pattern',i-1,j,X); end
   if M(i+1,j)==1 z=feval('find_pattern',i+1,j,X); end
   if M(i,j-1)==1 z=feval('find_pattern',i,j-1,X); end
   if M(i,j+1)==1 z=feval('find_pattern',i,j+1,X); end

if (M(i-1,j)-1)  &  (M(i+1,j)-1)  &  (M(i,j-1)-1)  &  (M(i,j+1)-1)     
     
   z=M;

end
   z=M;

end


у меня выдает в конце:

Код:
  In find_pattern at 18
  In find_pattern at 17
  In find_pattern at 18
  In find_pattern at 17
  In find_pattern at 18
  In find_pattern at 17
  In find_pattern at 18
  In find_pattern at 17
  In find_pattern at 18
  In find_pattern at 17
  In find_pattern at 18
  In find_pattern at 17
  In find_pattern at 18
  In find_pattern at 17
  In find_pattern at 18
  In find_pattern at 17
  In find_pattern at 18
  In find_pattern at 17
  In find_pattern at 18
  In find_pattern at 17
  In find_pattern at 18
  In find_pattern at 17
  In find_pattern at 18
  In find_pattern at 17
  In find_pattern at 18
  In es at 43
??? Maximum recursion limit of 500 reached. Use set(0,'RecursionLimit',N)
to change the limit.  Be aware that exceeding your available stack space can
crash MATLAB and/or your computer.

Error in ==> find_pattern at 18
   if M(i+1,j)==1 z=feval('find_pattern',i+1,j,X); end

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 19 ]  На страницу 1, 2  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: Andrei P


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group