build_graph Subroutine

recursive subroutine build_graph(node_num, i, j, idist, visited)

Arguments

Type IntentOptional Attributes Name
integer(kind=ip), intent(in) :: node_num

current node number

integer(kind=ip), intent(in) :: i

current position

integer(kind=ip), intent(in) :: j

current position

integer(kind=ip), intent(in) :: idist

current distance (number of steps)

logical, intent(in), dimension(:,:) :: visited

elements visited in this path (not counting this one)


Calls

proc~~build_graph~~CallsGraph proc~build_graph problem_23::build_graph proc~build_graph->proc~build_graph proc~add_edge~2 problem_23::add_edge proc~build_graph->proc~add_edge~2 proc~get_cell problem_23::get_cell proc~build_graph->proc~get_cell proc~node_number problem_23::node_number proc~build_graph->proc~node_number

Called by

proc~~build_graph~~CalledByGraph proc~build_graph problem_23::build_graph proc~build_graph->proc~build_graph proc~go~5 problem_23::go proc~go~5->proc~build_graph program~problem_23 problem_23 program~problem_23->proc~go~5

Source Code

    recursive subroutine build_graph(node_num,i,j,idist,visited)
        integer(ip),intent(in) :: node_num !! current node number
        integer(ip),intent(in) :: i,j   !! current position
        integer(ip),intent(in) :: idist !! current distance (number of steps)
        logical,dimension(:,:),intent(in) :: visited !! elements visited in this path (not counting this one)

        logical,dimension(:,:),allocatable :: tmp_visited
        integer(ip) :: child_node_num

        if (i<1 .or. i>nrows .or. j<1 .or. j>ncols) return
        if (visited(i,j)) return
        if (array(i,j)=='#') return ! can't continue from here

        ! go until we hit another node
        child_node_num = node_number(i,j)
        if (child_node_num>0 .and. child_node_num/=node_num) then
            ! we have reached another node
            call add_edge(node_num, child_node_num, idist)
        else
            ! continue processing this edge
            tmp_visited = visited     !make a copy and mark this one
            tmp_visited(i,j) = .true. ! we are here now
            associate (a => get_cell(i,j)) ! paths (.), forest (#), and steep slopes (^, >, v, and <).
                select case (a)
                case ('.') ! path
                    call build_graph(node_num,i-1,j  ,idist+1,tmp_visited)
                    call build_graph(node_num,i+1,j  ,idist+1,tmp_visited)
                    call build_graph(node_num,i,  j+1,idist+1,tmp_visited)
                    call build_graph(node_num,i,  j-1,idist+1,tmp_visited)
                ! these don't have a choice, must go in these directions:
                case('^'); call build_graph(node_num, i-1,j,  idist+1, tmp_visited)
                case('v'); call build_graph(node_num, i+1,j,  idist+1, tmp_visited)
                case('>'); call build_graph(node_num, i,  j+1,idist+1, tmp_visited)
                case('<'); call build_graph(node_num, i,  j-1,idist+1, tmp_visited)
                end select
            end associate
        end if
    end subroutine build_graph