我想为非表格数据构建数据结构。我不确定在(现代)Fortran中执行此操作的正确方法是什么。
我有一套房屋数据,包括其位置(纬度,经度)和价格。我还有工厂的其他数据,包括其位置(纬度,经度)和所产生的污染量。对于每座房屋,我需要创建一个位于房屋半径5公里以内的工厂清单。不仅这些工厂的数量,而且这些工厂的整体(纬度,经度,污染)向量。每个房屋附近都有不同数量的工厂,从零到八十不等。
MODULE someDefinitions
IMPLICIT NONE
INTEGER, PARAMETER :: N_houses=82390, N_factories=4215
TYPE house
REAL :: lat,lon,price
! a few more fields which are not important here
END TYPE
TYPE factory
REAL :: lat,lon,pollution
! a few more fields which are not important here
END TYPE
Contains
PURE FUNCTION haversine(deglat1,deglon1,deglat2,deglon2) RESULT (dist)
! Some code for computing haversine distance in meters
END FUNCTION haversine
END MODULE someDefinitions
PROGRAM createStructure
USE someDefinitions
IMPLICIT NONE
TYPE(factory), DIMENSION(N_factories) :: factories
TYPE(house), DIMENSION(N_houses) :: houses
INTEGER :: i,j
! more variables definitions as needed
! code to read houses data from the disk
! code to read factories data from the disk
DO i=1,N_houses
DO j=1,N_factories
!here I compute the distance between houses(i) and factories(j)
! If this distance<=5000 I want to add the index j to the list of indices
! associated with house i. How? What is the right data structure to do
! that? some houses have zero factories within 5000 meters from them.
! Some houses have about 80 factories around them. It's unbalanced.
END DO !j
END DO !i
END PROGRAM createStructure
创建的结构将用于进一步的计算。 N_houses x N_factories的矩阵太大,无法保存在内存中。 注意:我知道Fortran 2008是否对您有帮助。
答案 0 :(得分:0)
使用太多的嵌套派生类型可能会变得乏味。这是一个使用2D数组存储所有数据的示例,所需列表除外。这类似于天真的实现的K最近邻居(KNN)算法。当然,可能会有更好的算法,但是以下可能是一个好的开始。
program NoStrucyures
implicit none
type listi
real, allocatable :: item(:,:)
end type
integer, parameter :: N_houses=82390, N_factories=4215
real :: houses(N_houses,3)
real :: factories(N_factories,3)
real :: distance(N_factories)
type(listi) :: list(N_houses)
integer :: i, j, k, within5k
! Generating dummy data
call random_number(houses)
call random_number(factories)
houses = houses * 500000
factories = factories * 500000
do i = 1, N_houses
distance = sqrt((houses(i,1)-factories(:,1))**2 + (houses(i,2)-factories(:,2))**2)
within5k = count( distance <= 5000 )
if (within5k > 0) then
allocate(list(i)%item(within5k,3))
k = 0
do j = 1, N_factories
if (distance(j) <= 5000) then
k = k + 1
list(i)%item(k,:) = factories(j,:)
end if
end do
else
list(i)%item = reshape([-1, -1, -1],[1,3])
end if
end do
do i=1,10
print *, list(i)%item
end do
end program NoStrucyures