You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何编写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 None and 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

火山引擎 最新活动