Помоги сделать код на 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を共有