Помоги сделать код на Python который искал бы крат...

생성일: 2025년 11월 21일

답변에 사용된 모델 GPT-5.1 Thinking by Chat01

질문

Помоги сделать код на Python который искал бы кратчайший путь от левого верхнего угла изображения до правого нижнего угла обходя препятствия

사고

from collections import deque

def bfs_shortest_path(grid): h = len(grid) w = len(grid[0]) if h>0 else 0 start = (0,0) goal = (h-1,w-1) if h == 0 or w == 0: return None if grid[start[0]][start[1]] == 0 or grid[goal[0]][goal[1]] == 0: return None

text
q = deque([start]) prev = {start: None} while q: y,x = q.popleft() if (y,x) == goal: break for dy,dx in [(-1,0),(1,0),(0,-1),(0,1)]: ny,nx = y+dy, x+dx if 0 <= ny < h and 0 <= nx < w and grid[ny][nx] == 1 and (ny,nx) not in prev: prev[(ny,nx)] = (y,x) q.append((ny,nx)) if goal not in prev: return None path = [] cur = goal while cur is not None: path.append(cur) cur = prev[cur] path.reverse() return path

g = [ [1,1,1], [0,0,1], [1,1,1] ] print(bfs_shortest_path(g))

Thought for 34s

답변

Сделаем так:

  1. читаем картинку,
  2. превращаем её в сетку «проходимо / стена»,
  3. по сетке ищем кратчайший путь BFS’ом,
  4. рисуем путь на изображении.

Ниже готовый рабочий пример.

Требуется библиотека Pillow:
pip install pillow

python
from collections import deque from PIL import Image, ImageDraw def load_grid_from_image(path, threshold=128): """ Загружаем картинку и переводим её в сетку 0/1. 1 – можно пройти, 0 – препятствие. Предполагаем, что фон светлый (проходимый), а препятствия тёмные (чёрные, тёмно-серые). """ img = Image.open(path).convert('L') # оттенки серого w, h = img.size pixels = img.load() # grid[y][x] (y – строка, x – столбец) grid = [ [1 if pixels[x, y] > threshold else 0 for x in range(w)] for y in range(h) ] return grid, img def bfs_shortest_path(grid): """ Находим кратчайший путь по сетке из (0,0) в (h-1,w-1) с помощью поиска в ширину (BFS). 1 – проходимо, 0 – препятствие. Возвращаем список координат [(y,x), ...] или None, если пути нет. """ h = len(grid) if h == 0: return None w = len(grid[0]) start = (0, 0) goal = (h - 1, w - 1) # проверка: старт или финиш заблокированы if grid[start[0]][start[1]] == 0 or grid[goal[0]][goal[1]] == 0: return None q = deque([start]) prev = {start: None} # для восстановления пути # 4-соседей (вверх, вниз, влево, вправо) directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] while q: y, x = q.popleft() if (y, x) == goal: break for dy, dx in directions: ny, nx = y + dy, x + dx if ( 0 <= ny < h and 0 <= nx < w and grid[ny][nx] == 1 and (ny, nx) not in prev ): prev[(ny, nx)] = (y, x) q.append((ny, nx)) if goal not in prev: return None # пути нет # восстанавливаем путь от goal к start path = [] cur = goal while cur is not None: path.append(cur) cur = prev[cur] path.reverse() return path def draw_path_on_image(img, path, out_path="result.png"): """ Рисуем путь на картинке (красные точки по пикселям пути) и сохраняем в out_path. """ img = img.convert('RGB') draw = ImageDraw.Draw(img) for (y, x) in path: # В Image координаты (x, y), в пути у нас (y, x) draw.point((x, y), fill=(255, 0, 0)) img.save(out_path) print(f"Путь нарисован и сохранён в {out_path}") def find_shortest_path_on_image(path_to_image, threshold=128, out_path="result.png"): grid, img = load_grid_from_image(path_to_image, threshold) path = bfs_shortest_path(grid) if path is None: print("Кратчайший путь не найден (нет прохода).") else: print(f"Длина пути: {len(path)} пикселей") draw_path_on_image(img, path, out_path) if __name__ == "__main__": # ЗАМЕНИТЕ путь к картинке на свой find_shortest_path_on_image("input.png", threshold=128, out_path="result.png")

Как использовать:

  1. Подготовьте изображение input.png, где:
    • верхний левый пиксель — старт,
    • правый нижний — финиш,
    • тёмные области — препятствия, светлые — свободные.
  2. Запустите скрипт.
  3. Получите result.png с отмеченным красным кратчайшим путём.

Если хочешь, могу адаптировать код под:

  • уже готовую матрицу 0/1 вместо картинки,
  • диагональные ходы,
  • другой критерий препятствий (например, по цвету, а не яркости).

이 Q&A 공유하기