welch_powell.F90 Source File


This file depends on

sourcefile~~welch_powell.f90~~EfferentGraph sourcefile~welch_powell.f90 welch_powell.F90 sourcefile~multicoloring.f90 multicoloring.F90 sourcefile~welch_powell.f90->sourcefile~multicoloring.f90 sourcefile~adjacency_element.f90 adjacency_element.F90 sourcefile~multicoloring.f90->sourcefile~adjacency_element.f90 sourcefile~core.f90 core.F90 sourcefile~multicoloring.f90->sourcefile~core.f90 sourcefile~adjacency_element.f90->sourcefile~core.f90 sourcefile~element.f90 element.F90 sourcefile~adjacency_element.f90->sourcefile~element.f90 sourcefile~allocate.f90 allocate.F90 sourcefile~core.f90->sourcefile~allocate.f90 sourcefile~check_range.f90 check_range.F90 sourcefile~core.f90->sourcefile~check_range.f90 sourcefile~deallocate.f90 deallocate.F90 sourcefile~core.f90->sourcefile~deallocate.f90 sourcefile~error.f90 error.F90 sourcefile~core.f90->sourcefile~error.f90 sourcefile~fortran_utils.f90 fortran_utils.F90 sourcefile~core.f90->sourcefile~fortran_utils.f90 sourcefile~string_utils.f90 string_utils.F90 sourcefile~core.f90->sourcefile~string_utils.f90 sourcefile~types.f90 types.F90 sourcefile~core.f90->sourcefile~types.f90 sourcefile~unique.f90 unique.F90 sourcefile~core.f90->sourcefile~unique.f90 sourcefile~vtk.f90 vtk.F90 sourcefile~core.f90->sourcefile~vtk.f90 sourcefile~vtk_constants.f90 vtk_constants.F90 sourcefile~core.f90->sourcefile~vtk_constants.f90 sourcefile~allocate.f90->sourcefile~error.f90 sourcefile~deallocate.f90->sourcefile~error.f90 sourcefile~element.f90->sourcefile~core.f90 sourcefile~input.f90 input.F90 sourcefile~element.f90->sourcefile~input.f90 sourcefile~memory_stats_wrapper.f90 memory_stats_wrapper.F90 sourcefile~fortran_utils.f90->sourcefile~memory_stats_wrapper.f90 sourcefile~signal_flag_wrapper.f90 signal_flag_wrapper.F90 sourcefile~fortran_utils.f90->sourcefile~signal_flag_wrapper.f90 sourcefile~system_info_wrapper.f90 system_info_wrapper.F90 sourcefile~fortran_utils.f90->sourcefile~system_info_wrapper.f90 sourcefile~string_utils.f90->sourcefile~allocate.f90 sourcefile~array.f90 array.F90 sourcefile~types.f90->sourcefile~array.f90 sourcefile~gauss.f90 gauss.F90 sourcefile~types.f90->sourcefile~gauss.f90 sourcefile~pointer.f90 pointer.F90 sourcefile~types.f90->sourcefile~pointer.f90 sourcefile~variable.f90 variable.F90 sourcefile~types.f90->sourcefile~variable.f90 sourcefile~vector.f90 vector.F90 sourcefile~types.f90->sourcefile~vector.f90 sourcefile~unique.f90->sourcefile~allocate.f90 sourcefile~vtk.f90->sourcefile~allocate.f90 sourcefile~vtk.f90->sourcefile~deallocate.f90 sourcefile~vtk.f90->sourcefile~unique.f90 sourcefile~vtk.f90->sourcefile~vtk_constants.f90 sourcefile~vtk.f90->sourcefile~array.f90 sourcefile~vtk_wrapper.f90 vtk_wrapper.F90 sourcefile~vtk.f90->sourcefile~vtk_wrapper.f90 sourcefile~vtu_wrapper.f90 vtu_wrapper.F90 sourcefile~vtk.f90->sourcefile~vtu_wrapper.f90 sourcefile~array.f90->sourcefile~allocate.f90 sourcefile~array.f90->sourcefile~deallocate.f90 sourcefile~input_interface.f90 input_interface.F90 sourcefile~input.f90->sourcefile~input_interface.f90 sourcefile~c_utils.f90 c_utils.F90 sourcefile~memory_stats_wrapper.f90->sourcefile~c_utils.f90 sourcefile~signal_flag.f90 signal_flag.F90 sourcefile~signal_flag_wrapper.f90->sourcefile~signal_flag.f90 sourcefile~system_info_wrapper.f90->sourcefile~c_utils.f90 sourcefile~variable.f90->sourcefile~allocate.f90 sourcefile~c_utils.f90->sourcefile~signal_flag.f90 sourcefile~memory_stats.f90 memory_stats.F90 sourcefile~c_utils.f90->sourcefile~memory_stats.f90 sourcefile~system_info.f90 system_info.F90 sourcefile~c_utils.f90->sourcefile~system_info.f90 sourcefile~input_interface.f90->sourcefile~core.f90 sourcefile~project_settings.f90 project_settings.F90 sourcefile~input_interface.f90->sourcefile~project_settings.f90 sourcefile~project_settings.f90->sourcefile~core.f90

Source Code

submodule(domain_multicoloring) multicoloring_welch_powell

contains
    !================================================================!
    !【アルゴリズム実装】Welsh-Powell法 (プライベート)
    !================================================================!
    module subroutine coloring_welsh_powell(self, graph)
        implicit none
        class(type_coloring), intent(inout) :: self
        class(type_crs_adjacency_element), intent(in) :: graph

        integer(int32) :: num_elements, i, v
        integer(int32), allocatable :: perm(:)

        num_elements = graph%get_num_elements()

        if (allocated(self%color)) call deallocate_array(self%color)
        call allocate_array(self%color, length=num_elements)
        self%color = 0

        ! ステップ1: 次数降順の処理順序(perm)を取得
        call get_welsh_powell_order(graph, perm)

        ! ステップ2: ソートされた順序で要素を着色
        do i = 1, num_elements
            v = perm(i)
            self%color(v) = find_smallest_available_color(v, graph, self%color)
        end do

        ! ステップ3: 結果を構造体に整理
        call self%populate()

        call deallocate_array(perm)
    end subroutine coloring_welsh_powell

    !================================================================!
    !【ヘルパー関数群】(プライベート)
    !================================================================!

    ! 次数降順の処理順序(perm)を取得する
    subroutine get_welsh_powell_order(graph, perm)
        implicit none
        class(type_crs_adjacency_element), intent(in) :: graph
        integer(int32), allocatable, intent(inout) :: perm(:)

        integer(int32) :: num_elements, i, temp
        integer(int32), allocatable :: degrees(:)
        integer(int32), allocatable :: local_perm(:)

        num_elements = graph%get_num_elements()
        call allocate_array(degrees, length=num_elements)
        call allocate_array(local_perm, length=num_elements)

        do i = 1, num_elements
            degrees(i) = graph%get_degree(i)
        end do

        ! stdlibのsort_indexで昇順ソートのインデックスを取得
        call sort_index(array=degrees, index=local_perm)

        ! 得られたインデックス配列を手動で逆順にし、降順のインデックスを得る
        do i = 1, num_elements / 2
            temp = local_perm(i)
            local_perm(i) = local_perm(num_elements - i + 1)
            local_perm(num_elements - i + 1) = temp
        end do

        perm = local_perm

        call deallocate_array(degrees)
        call deallocate_array(local_perm)

    end subroutine get_welsh_powell_order

    ! 指定ノードに割り当て可能な最小の色を見つける (最適化版)
    function find_smallest_available_color(v, graph, colors) result(color_id)
        implicit none
        integer(int32) :: color_id
        integer(int32), intent(in) :: v
        class(type_crs_adjacency_element), intent(in) :: graph
        integer(int32), intent(in) :: colors(:)

        logical, allocatable :: forbidden_colors(:)
        integer(int32) :: neighbor_color, max_possible_colors, i
        integer(int32), allocatable :: neighbors(:)
        integer(int32) :: neighbor_id

        max_possible_colors = graph%get_degree(v) + 1

        call allocate_array(forbidden_colors, length=max_possible_colors)
        forbidden_colors = .false.

        ! ゲッターで隣接要素リストを取得し、使用済み色をマーク
        neighbors = graph%get_neighbors(v)
        do i = 1, size(neighbors)
            neighbor_id = neighbors(i)
            neighbor_color = colors(neighbor_id)
            if (neighbor_color > 0 .and. neighbor_color <= max_possible_colors) then
                forbidden_colors(neighbor_color) = .true.
            end if
        end do
        call deallocate_array(neighbors)

        ! マークされていない最小の色を見つける
        color_id = 1
        do while (color_id <= max_possible_colors)
            if (.not. forbidden_colors(color_id)) then
                exit
            end if
            color_id = color_id + 1
        end do

        call deallocate_array(forbidden_colors)
    end function find_smallest_available_color

end submodule multicoloring_welch_powell