bfs Subroutine

public subroutine bfs(graph, source, level, prev, err)

Breadth-first search, ignoring edge weights.

level(v) is the least number of edges from source to v, zero at the source and GRAPH_UNREACHABLE for a vertex that cannot be reached. prev(v) is the predecessor on that shortest hop path, or GRAPH_NO_PREDECESSOR. Because CSR rows are sorted ascending and the queue is FIFO, prev is deterministic here too: among equal-hop predecessors the one reached first in that order wins.

Edge weights are not read at all, so negative weights are accepted. Reports ERROR_VALIDATION for a malformed or non-square graph or an out-of-range source.

Arguments

Type IntentOptional Attributes Name
type(csr_t), intent(in) :: graph

Square adjacency matrix of the graph; values are ignored

integer(kind=default_int), intent(in) :: source

Source vertex, in 1:n

integer(kind=default_int), intent(out), allocatable :: level(:)

Hop count to each vertex

integer(kind=default_int), intent(out), allocatable :: prev(:)

Predecessor of each vertex on its shortest hop path

type(error_t), intent(out), optional :: err

Calls

proc~~bfs~~CallsGraph proc~bfs bfs proc~check_graph check_graph proc~bfs->proc~check_graph proc~csr_n_rows csr_t%csr_n_rows proc~bfs->proc~csr_n_rows proc~check_graph->proc~csr_n_rows proc~csr_is_valid csr_t%csr_is_valid proc~check_graph->proc~csr_is_valid proc~csr_n_cols csr_t%csr_n_cols proc~check_graph->proc~csr_n_cols proc~fail fail proc~check_graph->proc~fail proc~fail~3 fail proc~csr_is_valid->proc~fail~3 proc~error_set error_t%error_set proc~fail->proc~error_set proc~fail~3->proc~error_set

Variables

Type Visibility Attributes Name Initial
integer(kind=default_int), private :: head
integer(kind=default_int), private :: k
integer(kind=default_int), private :: n
integer(kind=default_int), private, allocatable :: queue(:)
integer(kind=default_int), private :: tail
integer(kind=default_int), private :: u
integer(kind=default_int), private :: v

Source Code

   subroutine bfs(graph, source, level, prev, err)
      !! Breadth-first search, ignoring edge weights.
      !!
      !! `level(v)` is the least number of edges from `source` to `v`, zero at
      !! the source and `GRAPH_UNREACHABLE` for a vertex that cannot be
      !! reached. `prev(v)` is the predecessor on that shortest hop path, or
      !! `GRAPH_NO_PREDECESSOR`. Because CSR rows are sorted ascending and the
      !! queue is FIFO, `prev` is deterministic here too: among equal-hop
      !! predecessors the one reached first in that order wins.
      !!
      !! Edge weights are not read at all, so negative weights are accepted.
      !! Reports `ERROR_VALIDATION` for a malformed or non-square graph or an
      !! out-of-range `source`.
      type(csr_t), intent(in) :: graph
         !! Square adjacency matrix of the graph; values are ignored
      integer(default_int), intent(in) :: source
         !! Source vertex, in `1:n`
      integer(default_int), allocatable, intent(out) :: level(:)
         !! Hop count to each vertex
      integer(default_int), allocatable, intent(out) :: prev(:)
         !! Predecessor of each vertex on its shortest hop path
      type(error_t), intent(out), optional :: err

      integer(default_int), allocatable :: queue(:)
      integer(default_int) :: n, head, tail, u, v, k

      if (.not. check_graph(graph, source, err)) then
         allocate (level(0))
         allocate (prev(0))
         return
      end if

      n = graph%n_rows()
      allocate (level(n))
      allocate (prev(n))
      allocate (queue(n))
      level = GRAPH_UNREACHABLE
      prev = GRAPH_NO_PREDECESSOR

      level(source) = 0
      queue(1) = source
      head = 1
      tail = 1
      do while (head <= tail)
         u = queue(head)
         head = head + 1
         do k = graph%row_ptr(u), graph%row_ptr(u + 1) - 1
            v = graph%col_idx(k)
            if (level(v) /= GRAPH_UNREACHABLE) cycle
            level(v) = level(u) + 1
            prev(v) = u
            tail = tail + 1
            queue(tail) = v
         end do
      end do
   end subroutine bfs