Я работаю над проектом, который требует, чтобы я визуализировал, насколько данный бюджет может достичь на карте с различными ценовыми зонами. < /p>
Пример с 3 ценовыми зонами, водой, сельской местностью и городом, каждая из которых имеет разные расходы на метр: < /p>
Красная точка - это происхождение, зеленая точка - это просто образцовая точка, она не имеет подшипника на результат. Градиент переходит от желтого (дешевого) к фиолетовому (максимальному бюджету)
проблема
Сложность времени в настоящее время очень плохо, что приводит время на время Расти очень быстро, когда я увеличиваю разрешение (уменьшение размера в метрах каждой клетки). Скорее всего, это связано с итеративным созданием scipy.sparse.lil_array при создании графика смежности массива. Мои текущие процессы для достижения этого являются следующими 6 основными шагами (время добавлено, чтобы показать узкие места): < /p>
- Создайте список Python Shapely.geometry. Point , который представляет все точки в 2D -сетке, которую мы будем выбрать цены из геометрии Geopandas. Список инициализируется с пустыми значениями перед модификациями. Я итеративно устанавливаю каждый индекс (по одному) в точку, созданную в зависимости от размера ячейки сетки. И, наконец, я преобразовываю список Python в DataFrame Pandas, чтобы позже пересечь с регионами геопанд. (13.6s)
- Я теперь использую DataFrame с точками и конвертируйте его в GeoDataFrame и используйте GPD .sjoin против моих различных ценовых областей для получения в данном случае 3 Geodataframe, каждый из которых содержит только точки, которые пересекались с данной ценовой областью. (0,7S)
- После отображения каждой точки с их ценой я хочу объединить его в 2D Массив со значением является цена для этого, я использую список 2D Python и индекс и заменяю значения, используя преобразование из координат точек в координаты индекса. (14.9s)
- Теперь у нас есть 2D -массив, который содержит стоимость/вес для каждой ячейки. Теперь я хочу преобразовать его в график (график смежности матрицы). Для этого я использую итеративные проходы и вводит каждое преимущество в scipy.sparse.lil_array , а затем после подключения каждого элемента преобразовать массив в scipy.sparse.csr_array (136.77 s)
- Я теперь называю scipy.sparse.csgraph.dijkstra и использовать созданный массив расстояний. (0.4s)
- из -за фиксированной цены, необходимой для каждого узла, я еще раз итеративно перейти через массив Добавление фиксированной стоимости. (0,2S)
Это связано с иным образом квадратным результатом: < /em> < /p>
Дополнительная информация о шаге 4:
Чтобы создать ребра I Список для каждого узла < /p>
Код: Выделить всё
adjecency_offsets= [
(-3, -2, 3.60), (-3, -1, 3.16), (-3, 1, 3.16), (-3, 2, 3.60),
(-2,-3, 3.60), (-2, -1, 2.24), (-2, 1, 2.24), (-2, 3, 3.60),
(-1,-3, 3.16), (-1, -2, 2.24), (-1, -1, 1.42), (-1, 0, 1), (-1, 1, 1.42), (-1, 2, 2.24), (-1, 3, 3.16),
( 0, -1, 1 ), ( 0, 1, 1 ),
( 1,-3, 3.16), ( 1, -2, 2.24), ( 1, -1, 1.42), ( 1, 0, 1), ( 1, 1, 1.42), ( 1, 2, 2.24), ( 1, 3, 3.16),
( 2,-3, 3.60), ( 2, -1, 2.24), ( 2, 1, 2.24), ( 2, 3, 3.60),
(-3, -2, 3.60), (-3, -1, 3.16), (-3, 1, 3.16), (-3, 2, 3.60)
]
Затем, используя следующий код, мы создаем график и заполняем массив смежности < /p>
def Step_4(arr: list[list[int]]):
# arr is a 2d-array of cost for each point (the index)
height = len(arr)
width = len(arr[0])
num_nodes = width*height
tmp_array = scipy.sparse.lil_array((num_nodes, num_nodes), dtype=np.float32) # we dont need more precision than this
# For every row and column in 2d array
for row in range(height):
for col in range(width):
# Create a src vertex
src = row * width + col
# and find all edges
for (r_off, c_off, w_mul) in adjecency_offsets:
# ignore invalid destinations
if (row + r_off < 0 or col + c_off < 0):
continue
if (row + r_off >= height or col + c_off >= width):
continue
# valid destination
dst = (row + r_off) * width + col + c_off
# Multiply cost of cell with distance to cell
float_w = w_mul * arr[row + r_off][col + c_off]
# Set weight in adjacency array
tmp_array[src, dst] = float_w
# return crs version due to faster pathfinding
return tmp_array.tocsr()
< /code>
Вопрос < /h2>
Это хороший подход к этой проблеме? (Даже если он имеет блочные неестественные края из -за него, используя график с ограниченным количеством ребра для каждого узла)
, если да, то как я могу более эффективно создать свой смежный график (сократить время, проведенное на шаге 4)? < /p>
Что я попробовал < /h2>
- Я пробовал линии рисования из происхождения в круге и сохранив, как долго может Добавиться до того, как бюджет закончится. Это дало мне плохое время выполнения (вероятно, проблема кодирования), но также не может справиться с поиском более дешевого маршрута, пройдя дальше через более дешевые области. В то время как это сокращение времени создания на многое, оно также увеличило время поиска пути с большим отрывом (необходимого для использования самостоятельной версии Dijkstra на основе Википедии с использованием кучи и раннего выхода с использованием бюджета) В общем времени создания и пути Нахождение составляет около 2 раза замедление по сравнению с методом матрицы смежности, упомянутым выше.
Подробнее здесь: https://stackoverflow.com/questions/794 ... gird-dista