英文:
Fortran sorting/ordering
问题
我正在寻找执行排名操作的Fortran例程。也就是说,给定一个一维数组,我想要一个例程,返回该数组中(降序)排序值的索引。我找到的所有例程都只执行排序操作,没有找到执行排名操作的例程。另外,如果有一个例程可以执行部分排序操作,那就更好了。也就是说,对于给定的数字M,返回M个最大值的索引,其余索引可以以任何顺序返回。我找到了dlasrt,但它只执行排序操作...
英文:
I am looking for fortran routines that perform ranking. That is given a one dimensional array I would like a routine that returns the indices in that array of the (descending) sorted values. All I could fined are routines that perform sorting. Additionally it would be nice to have a routine that performs partial ordering. That is returning for a given number M the indices of the M biggest values - and others in any order. I found dlasrt but it only does sorting...
答案1
得分: 1
对于部分排序,您可以选择像选择排序这样的排序算法,并在获得所需数量的元素后终止,而不是对所有元素进行排序。请确保(部分)排序一个索引的并行数组,而不是数组本身。
C++标准库中内置了partial_sort算法,但Fortran中没有。也许您可以查看它的实现方式。
module sorting
implicit none
contains
subroutine swap( a, b )
integer, intent(inout) :: a, b
integer temp
temp = a
a = b
b = temp
end subroutine swap
function best_n( A, nfirst ) result( indices )
integer, intent(in) :: A(:)
integer, intent(in) :: nfirst
integer, allocatable :: indices(:)
integer n
integer i, j, jmin
n = size( A )
indices = [ ( i, i = 1, n ) ]
do i = 1, nfirst
jmin = i
do j = i + 1, n
if ( A(indices(j)) > A(indices(jmin)) ) jmin = j
end do
if ( jmin /= i ) call swap( indices(i), indices(jmin) )
end do
end function best_n
end module sorting
!======================================================================
program main
use sorting
implicit none
integer, allocatable :: A(:), indices(:)
integer n
character(len=*), parameter :: fmt = "( a, *(i3,1x) )"
A = [ 1, -1, 2, -2, 3, -3 ]
n = 3
indices = best_n( A, n )
write( *, fmt ) "Original array: ", A
write( *, fmt ) "Best indices: ", indices(1:n)
write( *, fmt ) "Best values: ", A(indices(1:n))
end program main
原始数组:1 -1 2 -2 3 -3
最佳索引:5 3 1
最佳值:3 2 1
英文:
Well, for partial-sorting you just can just choose a sorting algorithm like selection sort and terminate after the first required number of elements rather than all of them. Make sure that you (partial-)sort a parallel array of indices rather than the array itself.
There's a partial_sort algorithm built into the standard library of C++, but not Fortran. Maybe you could check out how that is implemented.
module sorting
implicit none
contains
subroutine swap( a, b )
integer, intent(inout) :: a, b
integer temp
temp = a
a = b
b = temp
end subroutine swap
function best_n( A, nfirst ) result( indices )
integer, intent(in) :: A(:)
integer, intent(in) :: nfirst
integer, allocatable :: indices(:)
integer n
integer i, j, jmin
n = size( A )
indices = [ ( i, i = 1, n ) ]
do i = 1, nfirst
jmin = i
do j = i + 1, n
if ( A(indices(j)) > A(indices(jmin)) ) jmin = j
end do
if ( jmin /= i ) call swap( indices(i), indices(jmin) )
end do
end function best_n
end module sorting
!======================================================================
program main
use sorting
implicit none
integer, allocatable :: A(:), indices(:)
integer n
character(len=*), parameter :: fmt = "( a, *(i3,1x) )"
A = [ 1, -1, 2, -2, 3, -3 ]
n = 3
indices = best_n( A, n )
write( *, fmt ) "Original array: ", A
write( *, fmt ) "Best indices: ", indices(1:n)
write( *, fmt ) "Best values: ", A(indices(1:n))
end program main
Original array: 1 -1 2 -2 3 -3
Best indices: 5 3 1
Best values: 3 2 1
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论