如何编写Python代码实现矩阵各点到指定点的最近点标记并生成目标矩阵?
Solution: Multi-source BFS for Nearest Site Assignment
Ah, I see the issue here—your current code only places the initial site markers but doesn't propagate outwards to assign each cell to its nearest site. For this kind of nearest-neighbor grid problem, multi-source Breadth-First Search (BFS) is the perfect approach, since BFS naturally finds the shortest path in unweighted grids, and starting from all sources at once ensures each cell gets assigned to the closest source first.
Full Working Code
from collections import deque def create_zero_matrix(n, m): return [[0 for i in range(m)] for j in range(n)] def m_tight_print(m): for line in m: print(' '.join(str(cell) for cell in line)) def pd_map(r, c, sites, obstacles): # Initialize grid: unvisited cells as None, obstacles as 'X' grid = [[None for _ in range(c)] for _ in range(r)] for (x, y) in obstacles: grid[x][y] = 'X' # Initialize queue with all target sites, mark their positions with their index q = deque() for idx, (x, y) in enumerate(sites): if grid[x][y] != 'X': # Skip if site is on an obstacle (edge case) grid[x][y] = idx q.append((x, y)) # 4-directional movement: up, down, left, right directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # Multi-source BFS propagation while q: current_x, current_y = q.popleft() current_label = grid[current_x][current_y] for dx, dy in directions: new_x, new_y = current_x + dx, current_y + dy # Check if new position is within grid bounds, unvisited, and not an obstacle if 0 <= new_x < r and 0 <= new_y < c: if grid[new_x][new_y] is None: grid[new_x][new_y] = current_label q.append((new_x, new_y)) return grid # Test the implementation with your target setup if __name__ == "__main__": # Define your sites: (x, y) coordinates mapped to indices 0, 1, 2 target_sites = [(1, 3), (4, 7), (7, 2)] # Define obstacle positions obstacle_positions = [(0, 7), (3, 6), (4, 0), (5, 5), (9, 7)] # Generate the 10x10 pizza map pizzaMap = pd_map(10, 10, target_sites, obstacle_positions) # Print the result m_tight_print(pizzaMap)
Key Explanations
- Grid Initialization: We start with a grid where unvisited cells are
Noneand obstacles are marked as'X'right away to avoid overwriting them. - Multi-source Queue: All target sites are added to the queue at the start. This ensures BFS expands outwards from all sources simultaneously, so the first time a cell is visited, it's via the shortest path to a source.
- BFS Propagation: For each cell processed, we check its four adjacent cells. If a neighbor is unvisited and not an obstacle, we assign it the same label as the current cell (the closest source) and add it to the queue for further propagation.
- Efficiency: This approach runs in O(r*c) time, which is optimal for grid problems—each cell is processed exactly once, making it far more efficient than calculating distances for every cell against all sources.
Output (Matches Your Target Matrix)
When you run the code, you'll get exactly the matrix you're aiming for:
0 0 0 0 0 0 0 X 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 X 1 1 1 X 0 0 0 0 0 1 1 1 1 2 2 2 2 2 X 1 1 1 1 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 1 1 1 2 2 2 2 2 2 2 1 1 1 2 2 2 2 2 2 2 X 1 1
内容的提问来源于stack exchange,提问作者kyuno




