2014 dxdy logo

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

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




Начать новую тему Ответить на тему На страницу Пред.  1, 2
 
 
Сообщение30.06.2007, 02:04 
Экс-модератор
Аватара пользователя


23/12/05
12063
То, что выдало, - не самое страшное: по умолчанию стоит глубина рекурсии максимум 500 вложений. Я попрововал сделать больше, но после этого на определенном этапе у меня просто выбивает MatLAB, т.е. никаких сообщений об ошибках, а просто раз и все закрывает :(.

Значит, надо что-то думать над алгоритмом, чтобы избежать столь глубокой рекурсии

 Профиль  
                  
 
 
Сообщение30.06.2007, 11:43 


26/05/06
44
Цитата:
Я попрововал сделать больше, но после этого на определенном этапе у меня просто выбивает MatLAB, т.е. никаких сообщений об ошибках, а просто раз и все закрывает

при увеличении у меня тоже выбивает
я думал это у меня только

Цитата:
Значит, надо что-то думать над алгоритмом, чтобы избежать столь глубокой рекурсии

спасибо за помощь

буду думать

Добавлено спустя 2 часа 26 минут 56 секунд:

нашел нужный алгоритм

помогите воплотить

на матлабе или с++

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


23/12/05
12063
Я немножко лентяй и не захотел разбираться с новым алгоритмом, но постарался модифицировать старый. Для этого я после каждого перекрашивания точки стал выводить матрицу в виде рисунка и смотреть, как наш алгоритм закрашивает матрицу. Посмотрел, и мне это не понравилось: из-за того, что у нас вполне определенное направление обхода соседних точек, закрашивание выстраивается в линию, и большая область единиц может обходиться таким образом, что каждая следуюшая точка будет новым вложением рекурсии, значит, подумал я, надо искусственно задать обход точек по такому направлению, чтобы рекурсия почаще замыкалась и глубина вложения была поменьше. Как это сделать? А давайте запустим закраску маленькими закручивающимися спиралями, тогда по окончанию этого "закручивания" для всех внутренних точек этой спирали рекурсионная цепочка будет обрываться... Конечно, нет гарантий, что для большой области, мы не превысим отведенный нам максимум вложений, но, во всяком случае, мы сможем работать со значительно бОльшими областями. Вот, что у меня получилось:

Код:
function sol=es()
set(0,'RecursionLimit',2000)
global M;
global count
count=1;
X=2;

M=imread('Ttext1.tif');
M=double(M);
[a b]=size(M);
for v=1:a
    for w=1:b
       
if ( M(v,w) == 1 )

M;


find_pattern(v,w,X);
contourf(M,X,'EdgeColor','none')
pause(0.1);
X=X+1;

end
    end
end

sol=M;


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

global M count

if( M(i,j) == 1 )
count=mod(count,30)+1;


   M(i,j)= X;
%   contourf(M,X,'EdgeColor','none')
%   pause(0.0001);
   switch count
       case {1,2,3,4,5,6,7,8,9}
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+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

      case {10,11,12,13,14,15,16,17}
if M(i,j+1)==1 z=feval('find_pattern',i,j+1,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-1,j)==1 z=feval('find_pattern',i-1,j,X); end

     case {18,19,20,21,22,23,24}

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

     case {25,26,27,28,29,30}

if M(i,j-1)==1 z=feval('find_pattern',i,j-1,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+1,j)==1 z=feval('find_pattern',i+1,j,X); end
   end
   

    z=M;
   
end

 Профиль  
                  
 
 
Сообщение16.07.2007, 18:56 


10/11/06
64
Вместо глобальных переменных лучше использовать локальные переменные с вложенными функциями. (у меня пустые области обозначены нулями)

Код:
function regions

A = [...
    -1    -1     0    -1    -1    -1    -1    -1    -1    -1
     0    -1     0     0     0    -1     0     0     0     0
     0    -1     0     0     0    -1     0     0     0    -1
     0    -1     0     0     0    -1     0     0     0    -1
     0    -1     0     0     0     0    -1    -1    -1    -1
     0    -1    -1    -1    -1     0     0     0     0    -1
     0     0     0     0     0     0     0     0     0    -1
     0     0     0     0     0     0     0     0     0    -1
     0     0     0     0     0     0     0     0     0    -1
     0     0     0     0     0     0     0     0    -1     0];

[m, n] = size(A);
count = 0;
while 1
    [i, j] = find(A == 0, 1);
    if isempty(i)
        break
    end
    count = count + 1
    find_adj(i, j);
end

    function find_adj(i, j)
        if i >= 1 && j >= 1 && i <= m && j <= n && A(i, j) == 0
            % (i, j) --- допустимая не занятая клетка
            A(i, j) = count;
            find_adj(i, j + 1);
            find_adj(i, j - 1);
            find_adj(i + 1, j);
            find_adj(i - 1, j);
        end
    end
end


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

Аммераал в одной из своих книжек для уменьшения возможной глубины рекурсивных спусков советует сделать примерно так (естественно, у него все на C):

Код:
function regions

A = [...
    -1    -1     0    -1    -1    -1    -1    -1    -1    -1
    0    -1     0     0     0    -1     0     0     0     0
    0    -1     0     0     0    -1     0     0     0    -1
    0    -1     0     0     0    -1     0     0     0    -1
    0    -1     0     0     0     0    -1    -1    -1    -1
    0    -1    -1    -1    -1     0     0     0     0    -1
    0     0     0     0     0     0     0     0     0    -1
    0     0     0     0     0     0     0     0     0    -1
    0     0     0     0     0     0     0     0     0    -1
    0     0     0     0     0     0     0     0    -1     0];

[m, n] = size(A);
count = 0;
while 1
    [i, j] = find(A == 0, 1);
    if isempty(i)
        break
    end
    count = count + 1
    find_adj(i, j);
end

    function find_adj(i, j)
        if A(i, j) == 0 % Не занятая клетка
            A(i, j) = count;
            jmax = 0;
            for jj = (j + 1):n % Сканируем строку вправо
                if A(i, jj) == 0 % Не занятая клетка
                    A(i, jj) = count;
                    % A
                    % pause
                else
                    jmax = jj - 1;
                    break
                end
            end
            if jmax == 0
                jmax = n;
            end
            jmin = n + 1;
            for jj = (j - 1):-1:1 % Сканируем строку влево
                if A(i, jj) == 0 % Не занятая клетка
                    A(i, jj) = count;
                    % A
                    % pause
                else
                    jmin = jj + 1;
                    break
                end
            end
            if jmin == n + 1
                jmin = 1;
            end
            if i < m
                for jj = jmin:jmax
                    find_adj(i + 1, jj);
                end
            end
            if i > 1
                for jj = jmin:jmax
                    find_adj(i - 1, jj);
                end
            end
        end
    end
end

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

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



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

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


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

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