Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Prolog] Змейка на прологе, Минимальный путь от входы к выходу 
V
    Опции темы
ditya666
Дата 19.9.2007, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 9.4.2007

Репутация: 1
Всего: 1



Задан лабиринт, по которому ползет змейка. Найти минимальный путь от входа к выходу, при условии, что змейка может одновременно преломляться N раз.

Помогите плиз с задаче smile) Сама никак не разберусь!
PM MAIL   Вверх
cg_ck
Дата 22.9.2007, 04:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 22.9.2007

Репутация: нет
Всего: нет



Есть наработки уже? Думал на счёт алгоритма? Начал писать движёк? Писал вообще на Prolog когда-нибудь? 
PM MAIL   Вверх
ditya666
Дата 22.9.2007, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 9.4.2007

Репутация: 1
Всего: 1



Я дико извиняюсь, но я не ОН, а ОНА smile Писали на прологи маршрутизацию, но вообще у меня с этим очень-очень туго! Если у тебя есть возможность написать что-либо, то оч прошу. Помоги мне smile
PM MAIL   Вверх
ditya666
Дата 28.5.2008, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 9.4.2007

Репутация: 1
Всего: 1



Код

domains
    list = integer*
    megalist = list*

predicates
    
    %по индексу ячейки определяет её координаты
%1 параметр - индекс, 2- координата по Х в лабиринте, 3- коодината по У
    nondeterm ячейка(integer,integer,integer).
    %факты с координатами центров точек
    %1 параметр - номер точки,2 - её координаты
    nondeterm координаты(integer,integer).
    %прорисовка трассы прохождения змеи
    %1 параметр - в каком окне будем рисовать, 2 - список клеток, по которым проходим
    nondeterm трасса(window,list).
    %отрисовка лабиринта
    %параметр - в каком окне будем рисовать
    nondeterm лабиринт(window).
    %набор фактов, показывающих из какой клетки в какую можно переходить
    %1 параметр - название строки или столбца, 2 - список возможных переходов
    %список этот состоит из пар индексов клеток, из первой в паре возможен переход во вторую и обратно
    nondeterm линия(integer,list).
    %проверка на принадлежность двух подряд идущих элементов списку
    %1 и 2 параметры - элементы, 3 - список
    nondeterm принадлежит(integer,integer,list).
    %проверка на входимость элемента в список
    nondeterm входит(integer,list).
    %проверка на возможность перехода из одной клетки в другую
    %1 b 2 параметры - индексы проверяемых клеток, 3 - индекс лини, на которй возможен переход
    nondeterm проход(integer,integer,integer).
    %первичный предикат для поиска пути
    %1пар-р - индекс клетки откуда идти, 2 - куда идти, 3 - список с найденным путем
    nondeterm маршрут(integer,integer,list).
    %вторичный предикат для поиска пути
    %1 пар-р - начальный пункт, 2 - вспомогательный список, 3 - список с найденным путем
    nondeterm маршрут1(integer,list,list).
    %предикат для определения пройденны линий лабиринта
    %1 пар-р - пройденный пкть в лабиринте, 2- вспомогательный список, 3- найденный список пройденных линий
    nondeterm пройденные(list,list,list).
    %считает сколько раз переходили с линии на линию при прохождении пути. т.е. совершали поворот
    %1 пар-р пройденный список линий, 2 - вспомогательный, 3 - количество поворотов
    nondeterm повороты(list,integer,integer).
    %обработка ВСЕХ найденных маршрутов из одной точки в другую, проверяет на соответсвие количеству поворотов
    % 1 пар-р - список списков переходов, 2- нужное количество поворотов, 3 - найденный путь
    nondeterm обработать(megalist,integer,list).
    %основной предикат для получения интересующего пути
    %1 пар - исходная точка, 2 - конечная точка, 3 - нужное количество поворотов, 4 - найденный путь 
    nondeterm найтипуть(integer,integer,integer,list).
    
    nondeterm базточки(integer,integer).
    
    nondeterm списокпроходов(integer,list,list,list).
    
    nondeterm удалить(integer,list,list).
    
    nondeterm вычитаниесписков(list,list,list).
    
    nondeterm отрисовкалинии(window,integer,integer,integer).
    
    nondeterm палочки(window,integer,list).
    
    nondeterm всебазточки(list).
    
    nondeterm run(window,integer).
    
  win_cross_eh : EHANDLER
  

clauses

    линия(1,[101,201,201,301,401,501,501,601,701,801]).
    линия(2,[202,302,302,402,402,502,602,702]).    
    линия(3,[103,203,203,303,403,503,503,603,603,703,703,803]).
    линия(4,[104,204,304,404,504,604,604,704,704,804]).
    линия(5,[205,305,305,405,505,605,605,705,705,805]).
    линия(6,[106,206,406,506,506,606,706,806]).
    линия(7,[107,207,207,307,307,407,507,607,607,707,707,807]).
    линия(8,[108,208,208,308,308,408,408,508,508,608,708,808]).
    
    линия(100,[101,102,102,103,105,106,107,108]).
    линия(200,[202,203,204,205,205,206,206,207]).
    линия(300,[301,302,303,304,305,306,306,307]).
    линия(400,[401,402,403,404,404,405,405,406,407,408]).
    линия(500,[502,503,503,504,505,506,507,508]).
    линия(600,[601,602,604,605,606,607,607,608]).
    линия(700,[701,702,702,703,703,704,706,707,707,708]).
    линия(800,[801,802,804,805,805,806,807,808]).
    
    
    координаты(X,P):-
        P=(X-1)*50+35.
    
    базточки(X,P):-
        P=(X-1)*50+10.

    всебазточки([1,2,3,4,5,6,7]).
    
    удалить(P,[P|Ost],Ost).
        удалить(P,[P1|Ost],[P1|Ost1]):-
               удалить(P,Ost,Ost1).

    вычитаниесписков([],L,L).
    вычитаниесписков([P|Ost],L1,L):-
        удалить(P,L1,L2),
        вычитаниесписков(Ost,L2,L).

    принадлежит(X,Y,[X,Y|_]).
    принадлежит(X,Y,[_,_|Остаток]):-
        принадлежит(X,Y,Остаток).
    
    входит(X,[X|_]).
    входит(X,[_|Остаток]):-
        входит(X,Остаток).
    
    проход(X,Y,N):-
        линия(N,M),принадлежит(X,Y,M);
        линия(N,M),принадлежит(Y,X,M).
    
    маршрут(A,Z,Путь):-
        маршрут1(A,[Z],Путь).
        
    маршрут1(A,[A|Путь],[A|Путь]).
    маршрут1(A,[Y|Путь1],Путь):-
        проход(X,Y,_),
        not(входит(Y,Путь1)),
        маршрут1(A,[X,Y|Путь1],Путь).
    
    пройденные([_],L,L).
    пройденные([X,Y|Ost],L1,L):-
        линия(N,M),принадлежит(X,Y,M),L2=[N|L1],пройденные([Y|Ost],L2,L);
        линия(N,M),принадлежит(Y,X,M),L2=[N|L1],пройденные([Y|Ost],L2,L).
    
    повороты([_],P,P).
    повороты([X,Y|Ost],P1,P):-
        X<>Y,P2=P1+1,повороты([Y|Ost],P2,P);
        X=Y,повороты([Y|Ost],P1,P).
        
    обработать([],0,[]).
    обработать([Path|Ost],Z,P):-
        пройденные(Path,[],S), повороты(S,0,Pov),Pov=Z,P=Path,!;
        обработать(Ost,Z,P).
    
    найтипуть(P1,P2,Pov,RealPath):-
        findall(Path,маршрут(P1,P2,Path),AllPath),
        обработать(AllPath,Pov,RealPath).
    
    списокпроходов(_,[],L,L).
    списокпроходов(N,[P1,P2|Ost],L1,L):-
        P3=P2-P1,
        P3=100,
        P4=trunc((P1-N)/P3),
        L2=[P4|L1],
        списокпроходов(N,Ost,L2,L);
        P3=P2-P1,
        P3=1,
        P4=trunc((P1-N)/P3),
        L2=[P4|L1],
        списокпроходов(N,Ost,L2,L).
            
    палочки(_Win,N,[P|Ost]):-
        N<100,
        отрисовкалинии(_Win,1,N,P),
        палочки(_Win,N,Ost);
        N>=100,
        отрисовкалинии(_Win,0,N,P),
        палочки(_Win,N,Ost).
    
    отрисовкалинии(_Win,Type,N,P) :-
        Type=0, %на горизонтальных линиях
        P1=trunc(N/100),
        P2=P+1,
        базточки(P2,X),
        базточки(P1,Y1),
        Y2=Y1+50,
        draw_Line(_Win,pnt(X,Y1),pnt(X,Y2));
        Type=1, %на вертикальных линиях
        P1=P+1,
        базточки(N,X1),
        базточки(P1,Y),
        X2=X1+50,
        draw_Line(_Win,pnt(X1,Y),pnt(X2,Y)).
        
    ячейка(Number,X,Y):-
        Y = trunc(Number / 100),
        X = Number - (Y * 100).
    
    трасса(_,[_]).    
    трасса(_Win,[P1,P2|Ost]):-
        ячейка(P1,X1,Y1),
        координаты(X1,Xk1),
        координаты(Y1,Yk1),
        ячейка(P2,X2,Y2),
        координаты(X2,Xk2),
        координаты(Y2,Yk2),
        PenWidth = 2,
        Pen = pen(PenWidth , ps_Solid, color_Red),
        win_SetPen(_Win, Pen),
        draw_Line(_Win,pnt(Xk1,Yk1),pnt(Xk2,Yk2)),
        трасса(_Win,[P2|Ost]).
    
    лабиринт(_Win) :-
        Pen = pen(2,ps_Solid,color_Black),
        win_SetPen(_Win,Pen),
        draw_Rect(_Win,rct(10,10,410,410)),
        CurrentBrush = win_GetBrush(_Win),
        Brush = brush(pat_Solid, color_Blue),
        win_SetBrush(_Win, Brush),
        draw_Rect(_Win,rct(10,10,60,60)),
        Brush1 = brush(pat_Solid, color_Green),
        win_SetBrush(_Win, Brush1),
        draw_Rect(_Win,rct(360,360,410,410)),
        win_SetBrush(_Win, CurrentBrush),
          линия(N,P),
          списокпроходов(N,P,[],L),
          всебазточки(BT),
          вычитаниесписков(L,BT,L1),
          палочки(_Win,N,L1).
           
       run(_Win,Pov):-
           лабиринт(_Win);
           найтипуть(101,808,Pov,Path),
           трасса(_Win,Path).

       
  win_cross_Create(_Parent):-
    win_Create(win_cross_WinType,win_cross_RCT,win_cross_Title,
           win_cross_Menu,_Parent,win_cross_Flags,win_cross_eh,0). 


  win_cross_eh(_Win,e_Update(_UpdateRct),0):-!,
    run(_Win,18),
    !.

  win_cross_eh(Win,e_Menu(ID,CAS),0):-!,
    PARENT = win_GetParent(Win),
    win_SendEvent(PARENT,e_Menu(ID,CAS)),
    !.

  win_cross_eh(_Win,e_Create(_),0):-!,
    !.




PM MAIL   Вверх
ditya666
Дата 28.5.2008, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 9.4.2007

Репутация: 1
Всего: 1



Код

domains
    list = integer*
    megalist = list*

predicates
    
    %по индексу ячейки определяет её координаты
%1 параметр - индекс, 2- координата по Х в лабиринте, 3- коодината по У
    nondeterm ячейка(integer,integer,integer).
    %факты с координатами центров точек
    %1 параметр - номер точки,2 - её координаты
    nondeterm координаты(integer,integer).
    %прорисовка трассы прохождения змеи
    %1 параметр - в каком окне будем рисовать, 2 - список клеток, по которым проходим
    nondeterm трасса(window,list).
    %отрисовка лабиринта
    %параметр - в каком окне будем рисовать
    nondeterm лабиринт(window).
    %набор фактов, показывающих из какой клетки в какую можно переходить
    %1 параметр - название строки или столбца, 2 - список возможных переходов
    %список этот состоит из пар индексов клеток, из первой в паре возможен переход во вторую и обратно
    nondeterm линия(integer,list).
    %проверка на принадлежность двух подряд идущих элементов списку
    %1 и 2 параметры - элементы, 3 - список
    nondeterm принадлежит(integer,integer,list).
    %проверка на входимость элемента в список
    nondeterm входит(integer,list).
    %проверка на возможность перехода из одной клетки в другую
    %1 b 2 параметры - индексы проверяемых клеток, 3 - индекс лини, на которй возможен переход
    nondeterm проход(integer,integer,integer).
    %первичный предикат для поиска пути
    %1пар-р - индекс клетки откуда идти, 2 - куда идти, 3 - список с найденным путем
    nondeterm маршрут(integer,integer,list).
    %вторичный предикат для поиска пути
    %1 пар-р - начальный пункт, 2 - вспомогательный список, 3 - список с найденным путем
    nondeterm маршрут1(integer,list,list).
    %предикат для определения пройденны линий лабиринта
    %1 пар-р - пройденный пкть в лабиринте, 2- вспомогательный список, 3- найденный список пройденных линий
    nondeterm пройденные(list,list,list).
    %считает сколько раз переходили с линии на линию при прохождении пути. т.е. совершали поворот
    %1 пар-р пройденный список линий, 2 - вспомогательный, 3 - количество поворотов
    nondeterm повороты(list,integer,integer).
    %обработка ВСЕХ найденных маршрутов из одной точки в другую, проверяет на соответсвие количеству поворотов
    % 1 пар-р - список списков переходов, 2- нужное количество поворотов, 3 - найденный путь
    nondeterm обработать(megalist,integer,list).
    %основной предикат для получения интересующего пути
    %1 пар - исходная точка, 2 - конечная точка, 3 - нужное количество поворотов, 4 - найденный путь 
    nondeterm найтипуть(integer,integer,integer,list).
    
    nondeterm базточки(integer,integer).
    
    nondeterm списокпроходов(integer,list,list,list).
    
    nondeterm удалить(integer,list,list).
    
    nondeterm вычитаниесписков(list,list,list).
    
    nondeterm отрисовкалинии(window,integer,integer,integer).
    
    nondeterm палочки(window,integer,list).
    
    nondeterm всебазточки(list).
    
    nondeterm run(window,integer).
    
  win_cross_eh : EHANDLER
  

clauses

    линия(1,[101,201,201,301,401,501,501,601,701,801]).
    линия(2,[202,302,302,402,402,502,602,702]).    
    линия(3,[103,203,203,303,403,503,503,603,603,703,703,803]).
    линия(4,[104,204,304,404,504,604,604,704,704,804]).
    линия(5,[205,305,305,405,505,605,605,705,705,805]).
    линия(6,[106,206,406,506,506,606,706,806]).
    линия(7,[107,207,207,307,307,407,507,607,607,707,707,807]).
    линия(8,[108,208,208,308,308,408,408,508,508,608,708,808]).
    
    линия(100,[101,102,102,103,105,106,107,108]).
    линия(200,[202,203,204,205,205,206,206,207]).
    линия(300,[301,302,303,304,305,306,306,307]).
    линия(400,[401,402,403,404,404,405,405,406,407,408]).
    линия(500,[502,503,503,504,505,506,507,508]).
    линия(600,[601,602,604,605,606,607,607,608]).
    линия(700,[701,702,702,703,703,704,706,707,707,708]).
    линия(800,[801,802,804,805,805,806,807,808]).
    
    
    координаты(X,P):-
        P=(X-1)*50+35.
    
    базточки(X,P):-
        P=(X-1)*50+10.

    всебазточки([1,2,3,4,5,6,7]).
    
    удалить(P,[P|Ost],Ost).
        удалить(P,[P1|Ost],[P1|Ost1]):-
               удалить(P,Ost,Ost1).

    вычитаниесписков([],L,L).
    вычитаниесписков([P|Ost],L1,L):-
        удалить(P,L1,L2),
        вычитаниесписков(Ost,L2,L).

    принадлежит(X,Y,[X,Y|_]).
    принадлежит(X,Y,[_,_|Остаток]):-
        принадлежит(X,Y,Остаток).
    
    входит(X,[X|_]).
    входит(X,[_|Остаток]):-
        входит(X,Остаток).
    
    проход(X,Y,N):-
        линия(N,M),принадлежит(X,Y,M);
        линия(N,M),принадлежит(Y,X,M).
    
    маршрут(A,Z,Путь):-
        маршрут1(A,[Z],Путь).
        
    маршрут1(A,[A|Путь],[A|Путь]).
    маршрут1(A,[Y|Путь1],Путь):-
        проход(X,Y,_),
        not(входит(Y,Путь1)),
        маршрут1(A,[X,Y|Путь1],Путь).
    
    пройденные([_],L,L).
    пройденные([X,Y|Ost],L1,L):-
        линия(N,M),принадлежит(X,Y,M),L2=[N|L1],пройденные([Y|Ost],L2,L);
        линия(N,M),принадлежит(Y,X,M),L2=[N|L1],пройденные([Y|Ost],L2,L).
    
    повороты([_],P,P).
    повороты([X,Y|Ost],P1,P):-
        X<>Y,P2=P1+1,повороты([Y|Ost],P2,P);
        X=Y,повороты([Y|Ost],P1,P).
        
    обработать([],0,[]).
    обработать([Path|Ost],Z,P):-
        пройденные(Path,[],S), повороты(S,0,Pov),Pov=Z,P=Path,!;
        обработать(Ost,Z,P).
    
    найтипуть(P1,P2,Pov,RealPath):-
        findall(Path,маршрут(P1,P2,Path),AllPath),
        обработать(AllPath,Pov,RealPath).
    
    списокпроходов(_,[],L,L).
    списокпроходов(N,[P1,P2|Ost],L1,L):-
        P3=P2-P1,
        P3=100,
        P4=trunc((P1-N)/P3),
        L2=[P4|L1],
        списокпроходов(N,Ost,L2,L);
        P3=P2-P1,
        P3=1,
        P4=trunc((P1-N)/P3),
        L2=[P4|L1],
        списокпроходов(N,Ost,L2,L).
            
    палочки(_Win,N,[P|Ost]):-
        N<100,
        отрисовкалинии(_Win,1,N,P),
        палочки(_Win,N,Ost);
        N>=100,
        отрисовкалинии(_Win,0,N,P),
        палочки(_Win,N,Ost).
    
    отрисовкалинии(_Win,Type,N,P) :-
        Type=0, %на горизонтальных линиях
        P1=trunc(N/100),
        P2=P+1,
        базточки(P2,X),
        базточки(P1,Y1),
        Y2=Y1+50,
        draw_Line(_Win,pnt(X,Y1),pnt(X,Y2));
        Type=1, %на вертикальных линиях
        P1=P+1,
        базточки(N,X1),
        базточки(P1,Y),
        X2=X1+50,
        draw_Line(_Win,pnt(X1,Y),pnt(X2,Y)).
        
    ячейка(Number,X,Y):-
        Y = trunc(Number / 100),
        X = Number - (Y * 100).
    
    трасса(_,[_]).    
    трасса(_Win,[P1,P2|Ost]):-
        ячейка(P1,X1,Y1),
        координаты(X1,Xk1),
        координаты(Y1,Yk1),
        ячейка(P2,X2,Y2),
        координаты(X2,Xk2),
        координаты(Y2,Yk2),
        PenWidth = 2,
        Pen = pen(PenWidth , ps_Solid, color_Red),
        win_SetPen(_Win, Pen),
        draw_Line(_Win,pnt(Xk1,Yk1),pnt(Xk2,Yk2)),
        трасса(_Win,[P2|Ost]).
    
    лабиринт(_Win) :-
        Pen = pen(2,ps_Solid,color_Black),
        win_SetPen(_Win,Pen),
        draw_Rect(_Win,rct(10,10,410,410)),
        CurrentBrush = win_GetBrush(_Win),
        Brush = brush(pat_Solid, color_Blue),
        win_SetBrush(_Win, Brush),
        draw_Rect(_Win,rct(10,10,60,60)),
        Brush1 = brush(pat_Solid, color_Green),
        win_SetBrush(_Win, Brush1),
        draw_Rect(_Win,rct(360,360,410,410)),
        win_SetBrush(_Win, CurrentBrush),
          линия(N,P),
          списокпроходов(N,P,[],L),
          всебазточки(BT),
          вычитаниесписков(L,BT,L1),
          палочки(_Win,N,L1).
           
       run(_Win,Pov):-
           лабиринт(_Win);
           найтипуть(101,808,Pov,Path),
           трасса(_Win,Path).

       
  win_cross_Create(_Parent):-
    win_Create(win_cross_WinType,win_cross_RCT,win_cross_Title,
           win_cross_Menu,_Parent,win_cross_Flags,win_cross_eh,0). 


  win_cross_eh(_Win,e_Update(_UpdateRct),0):-!,
    run(_Win,18),
    !.

  win_cross_eh(Win,e_Menu(ID,CAS),0):-!,
    PARENT = win_GetParent(Win),
    win_SendEvent(PARENT,e_Menu(ID,CAS)),
    !.

  win_cross_eh(_Win,e_Create(_),0):-!,
    !.




PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0837 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.