2014-09-01 5 views
0

선생님 나는 프로젝트에서 일하고 있으며 그 문제와 관련하여 여기에 질문을 게시 할 때가 있습니다. 거북이 (로봇)가 공간에서 움직이는 시뮬레이션 시나리오를 만들었고 각 로봇이 방문한 패치를 추적합니다. 이동시에 patch-ahead 1 패치를 방문하면 로봇을 45도 왼쪽으로 돌리고 patch-ahead을 다시 확인해야합니다. 8 명이 하나라도 유엔 방문하면 8 이웃을 모두 확인한 다음 그 패치로 이동해야합니다. 탐구. 그러나 8 명이 모두 방문하면 방문한 모든 8 명의 이웃을 확인한 후 현재 제목 앞에있는 패치로 이동해야합니다. 여기에 제가 사용하고있는 코드 조각이 있습니다. 방문한 패치 피하기 netlogo

breed [robots robot ] 
robots-own[ state memory ] 
patches-own [ is-obstacle? ] 

to setup 

__clear-all-and-reset-ticks 
create-robots num [ 
set memory (list patch-here) 
] 
draw-obstacles 
    ask patches [if pxcor = 0 and pycor = 0 [ set pcolor black ]] 
end 

to draw-obstacles 
    ask patches with [ pxcor mod 6 = 0 and pycor mod 6 = 0 ] [set pcolor red set is-obstacle? true] 
    ; set pcolor red 
    ask patches [ ifelse pcolor = red [ set is-obstacle? true ][ set is-obstacle? false ] ] 
    ask patches with [ count neighbors != 8 ] [ set pcolor red set is-obstacle? true ] 
end 


to make-obstacle 
if mouse-down? 
[ ask-concurrent patches 
    [ if ((abs (pxcor - mouse-xcor)) < 1) and ((abs (pycor - mouse-ycor)) < 1) 
    [set pcolor red]] 
] 
end 
to remove-obs 
if mouse-down? 
[ ask-concurrent patches 
    [ if ((abs (pxcor - mouse-xcor)) < 1) and ((abs (pycor - mouse-ycor)) < 1) 
    [set pcolor black]] 
] 
end 

to go 
    ask patches [if (pcolor = red)[set is-obstacle? true]] 
    ask patches [if (pcolor = black)[set is-obstacle? false]] 
    ask-concurrent robots ; wanderers instructions 
    [ 
    rt random-float rate-of-random-turn 
    lt (rate-of-random-turn/2) 
    set-state 
    move-robots 
    ] 
    tick 
end 

to move-robots ;;turtle proc 
if (not member? state ["disperse" "explore"]) [ 
    error "Unknown state" 
    ] 
    if (state = "disperse") [ 
    disperse 
    ] 
    if (state = "explore") [ 
    explore 
    ] 
end 

to set-state ;;turtle proc 
    ifelse (any? other turtles in-radius 1) [ 
    set state "disperse" 
    ] [ 
    set state "explore" 
    ] 
end 
to disperse ;;turtle proc 
avoid-obstacle 
move1 

; move-to one-of patch-set [neighbors] of neighbors 
end 

to explore 
    move 
    ;search-open-room 
    avoid-obstacle 
    ;move-to one-of neighbors 
end 

to move 
fd speed 
set memory lput patch-here memory 
if ((member? patch-ahead 1 memory) or ([is-obstacle?] of patch-ahead 1)) 
    [ lt random 45 

    ] 

end 

to move1 
fd speed 
end 

to avoid-obstacle 
    set memory lput patch-here memory 
     if ([is-obstacle?] of patch-ahead 1) 
    [ 
     ifelse [is-obstacle?] of patch-at-heading-and-distance (heading - 5) 1 
     [ 
      ifelse [is-obstacle?] of patch-at-heading-and-distance (heading + 5) 1 
      [ 
       ifelse random 1 = 0 
       [ rt 40 ] 
       [ lt 40 ] 
      ] 
      [ rt 60 ] 
     ] 
     [lt 60] 
    ] 

end 
to search-open-room 
    ask robots[ 
    ifelse ([is-obstacle?] of patches in-cone 2 150) 
     [ rt 45 ] [ move ] 

    ] 

end 

그러나 move 절차

은 내가 lt random 45 단지 수 있어요. 위에서 언급 한 시나리오에 따라 변경하는 방법. 나는 while 루프와 repeat 문장으로 많은 시도를했지만 코드가 작동하지 않는 것 같습니다.

+0

패치가 방문되었는지 정확히 어떻게 알 수 있습니까? –

+0

David Merinos : "메모리"라는 목록을 사용하여 방문한 위치를 저장하고 있습니다. – Ashfaq

+0

그런데 이미 방문한 패치를 계속 추가하면 '메모리'가 잠재적으로 영원히 커질 수 있다는 것을 알고 계셨습니까? 이것은 문제가되지는 않지만, 하나가된다면 목록에서 ['patch-set'] (http://ccl.northwestern.edu/netlogo/docs/dictionary.html#)로 바꾸는 것이 좋습니다. 패치 세트) 또는 적어도''remove-duplicates' (http://ccl.northwestern.edu/netlogo/docs/dictionary.html#remove-duplicates)를 목록에서 잠시 동안 호출하십시오 ... –

답변

2

while 또는 repeat을 사용하여 수행 할 수 있지만이 경우는 recursion이 잘 작동한다고 생각합니다.

아이디어는 원하는 상태에 도달 할 때까지 자신을 호출에 유지하는 절차를 가질 경우 : n 매개 변수는 우리가 이미 절차를했습니다 호출의 수를 나타냅니다

to turn-until-free [ n ] 
    let target ifelse-value (patch-ahead 1 = patch-here) 
    [ patch-ahead 2 ] 
    [ patch-ahead 1 ] 
    let seen? member? target memory 
    let obstacle? [ is-obstacle? ] of target 
    if-else n < 8 
    [ if seen? or obstacle? [ lt 45 turn-until-free n + 1 ] ] 
    [ if obstacle? [ lt 45 turn-until-free n + 1 ] ] 
end 

(또는, 즉, 지금까지 확인한 이웃 수입니다. 당신이 처음으로 프로 시저를 호출 할 때 n = 0 시작 :

to move 
    turn-until-free 0 
    fd 1 
    set memory lput patch-here memory 
    ask patch-here [ set pcolor black + 2 ] ; just to show what's visited 
end 

원래 사양의 일부가 아닌 몇 가지 :

  • patch-ahead 1가 동일 함을 발생할 수 로봇이 이미 켜져있는 패치. 패치는 길이가 1 인면을 가지고 있지만 대각선은 약간 길다 (√2). 예를 들어 로봇이 왼쪽 하단 모서리에 있고 오른쪽 상단을 향하고있는 경우 patch-ahead 1 = patch-here이 true가됩니다. 이 경우 조금 더 살펴보고 대상을 patch-ahead 2으로 설정합니다.

  • 8 개의 이웃을 모두 확인한 후에 장애물이 마주 칠 수 있습니다. 그렇다면 장애물이 없어 질 때까지 계속 회전해야합니다. 사실 문제를 해결하는 데 장애물 회피가 잘 처리되므로 코드에서 avoid-obstacle 프로 시저를 제거 할 수 있습니다.

편집 : 여기

가 완전히 작업 (예를 들어, 위의 두 절차 외에) 필요한 코드 :

breed [ robots robot ] 
robots-own [ memory ] 
patches-own [ is-obstacle? ] 

to setup 
    ca 
    ask patches [ set is-obstacle? false ] 
    ask patches with [ pxcor mod 6 = 0 and pycor mod 6 = 0 ] [ 
    set is-obstacle? true 
    set pcolor red 
    ] 
    ask n-of 5 patches with [ not is-obstacle? ] [ 
    sprout-robots 1 [ set memory [] ] 
    ] 
    reset-ticks 
end 

to go 
    ask robots [ move ] 
    tick 
end 

당신이 런타임 오류에 문제가있는 경우 또는 기타 원하지 않는 동작이 발생하면이 작업부터 시작하여 시뮬레이션에서 한 번에 한 개씩 추가 한 것을 다시 추가하는 것이 좋습니다. 그러면 문제가 어디서 발생했는지 정확히 알 수 있습니다.

위의 turn-until-free 절차에서 if-else n < 8에 대해 if-else n < 7을 변경했습니다.이렇게하면 모든 이웃을 조금만 돌아 보는 대신 로봇이 원래 표제로 돌아옵니다. 이렇게하면 전체 영토를 탐험하면 서클에 들어갈 필요가 없습니다.

+0

Sir 이 두 함수를 내 코드에 추가했지만 런타임 오류가 발생하고 시뮬레이션이 중지됩니다. – Ashfaq

+0

이전에 직면했던 동일한 문제가 발생합니다. 모두 8 명의 이웃이 방문하면 로봇은 같은 패치에서 회전을 시작합니다. – Ashfaq

+0

코드 자체는 오류없이 실행됩니다. 문제는 시뮬레이션을 위해 어떻게 나머지 부분과 통합했는지에 달려 있습니다. 디버깅 제안은 위의 편집을 참조하십시오. –

관련 문제