궁금한 사람은 PySAL의 region.Maxp 알고리즘을 사용하여 자체 솔루션을 고안했습니다 . 본질적으로 Max-p를 사용하면 첫 번째 기준 (지역 당 최소 고용주 수)을 충족하는 지역 집합을 생성 할 수 있으며이를 while 루프 안에 넣습니다. 두 번째 기준 (지역에서 가장 큰 고용주가 기여한 고용 비율)을 충족합니다. ArcGIS 도구로 구현했습니다.
이전에 블록 / 블록 그룹 / 트랙에 플래그를 지정하기 위해 이전에 수행 한 작업을 폐기하기로 결정하고 대신 블록에서 Max-p를 실행하기로 결정했습니다 (입력 다각형의 수가 약간 증가함에 따라 트랙에서 모든 테스트를 수행했지만) 처리 시간에 대한 극적인 영향). 내 코드의 관련 부분은 다음과 같습니다. generate_regions()
함수에 대한 입력으로 필요한 "shapefile"(shapefile 의 전체 경로를 포함하는 문자열로 전달됨)은 고용주 수, 단일 고용주의 최대 직원 수와 함께 고용주가 이미 공간적으로 결합 된 기능을 고용주에게 제공 한 기능입니다. 및 각 입력 기능에 대한 속성으로 저장된 총 직원 수
import arcpy, math, pysal, random
import numpy as np
# Suppression criteria:
MIN_EMP_CT = 3 # Minimum number of employers per polygon feature
MAX_EMP_FRAC = 0.8 # Maximum ratio of employees working for a single employer per polygon feature
def generate_regions(shapefile, min_emp_ct=MIN_EMP_CT, max_emp_frac=MAX_EMP_FRAC):
'''Use pysal's region.Maxp method to generate regions that meet suppression criteria.'''
w = pysal.rook_from_shapefile(shapefile, idVariable='GEOID10')
dbf = pysal.open(shapefile[:-4] + '.dbf')
ids = np.array((dbf.by_col['GEOID10']))
vars = np.array((dbf.by_col[employer_count_fieldname],dbf.by_col[max_employees_fieldname],dbf.by_col[total_employees_fieldname]))
employers = vars[0]
vars = vars.transpose()
vars_dict = {}
for i in range(len(ids)):
vars_dict[ids[i]] = [int(vars[i][0]),float(vars[i][1]),float(vars[i][2])]
random.seed(100) # Using non-random seeds ensures repeatability of results
np.random.seed(100) # Using non-random seeds ensures repeatability of results
bump_iter = int(arcpy.GetParameterAsText(3)) # Number of failed iterations after which to increment the minimum number of employers per region (otherwise we could be stuck in the loop literally forever).
iteration = 0
tests_failed = 1
while tests_failed:
floor = int(min_emp_ct + math.floor(iteration / bump_iter))
solution = pysal.region.Maxp(w,vars,floor,employers)
regions_failed = 0
for region in solution.regions:
SUM_emp10sum = 0
MAX_emp10max = 0
for geo in region:
emp10max = vars_dict[geo][1]
emp10sum = vars_dict[geo][2]
SUM_emp10sum += emp10sum
MAX_emp10max = max(MAX_emp10max, emp10max)
if SUM_emp10sum > 0:
ratio = MAX_emp10max / SUM_emp10sum
else:
ratio = 1
if ratio >= max_emp_frac:
regions_failed += 1
iteration += 1
if regions_failed == 0:
arcpy.AddMessage('Iteration ' + str(iteration) + ' (MIN_EMP_CT = ' + str(floor) +') - PASSED!')
tests_failed = 0
else:
arcpy.AddMessage('Iteration ' + str(iteration) + ' (MIN_EMP_CT = ' + str(floor) +') - failed...')
return solution
solution = generate_regions(spatially_joined_shapefile)
regions = solution.regions
### Write input-to-region conversion table to a CSV file.
csv = open(conversion_table,'w')
csv.write('"GEOID10","REGION_ID"\n')
for i in range(len(regions)):
for geo in regions[i]:
csv.write('"' + geo + '","' + str(i+1) + '"\n')
csv.close()