最短布线问题(田字布线)

1.问题描述:印刷电路板将布线区域划分成m*n个方格阵列,如图(1)所示。精确的电路布线问题要求确定连接方格a的中点到方格b的中点的最短布线方案。

在布线时,电路只能沿直线或直角布线,如图(2)所示。为了避免线路相交,已布了线的方格做了封锁标记,其他线路不允许穿过被封锁的方格。

                                图1                                                                                      图2

在本问题当中,其他条件不变,但要求在布线时,电路只能沿斜线布线(田字布线),如下图所示:

2.求解思路:虽要求有所改变,但解题思路仍然相似,同样可以使用队列式分支界限法来解决问题。从起始位置a开始,将a作为第一个扩展节点,并且将a周围斜线可达方格看作可行节点并放入队列当中,同时这些节点记作1,再从队列中取出首个节点,将该节点周围可达方格当作可行节点放入队列,同时将其记作2,不断循环此步骤,直到队列为空。

3.算法具体代码如下:

# 田字布线问题
length = 6
m = length
n = length
grid = [[0 for _ in range(length + 2)] for _ in range(length + 2)]

def print_grid():
    for i in range(1, length + 1):
        for j in range(1, length + 1):
            print(f'{grid[i][j]:>3}', end='')
        print()
    print()

def find_path(start, finish): # 寻找路径
    # 找到每个相邻节点的斜边节点,并且遍历
    next_step = [(1, 1), (-1, 1), (1, -1), (-1, -1)] 
    here = start
    grid[start[0]][start[1]] = 1
    q = []
    while True:
        for dx, dy in next_step:
            next_pos = (here[0] + dx, here[1] + dy)
            if 1 <= next_pos[0] <= length + 1 and 1 <= next_pos[1] <= length + 1 and grid[next_pos[0]][next_pos[1]] == 0:
                grid[next_pos[0]][next_pos[1]] = grid[here[0]][here[1]] + 1
                if next_pos == finish:
                    break
                q.append(next_pos)
        if next_pos == finish:
            break
        if not q:
            return False
        here = q.pop(0)
    path_len = grid[finish[0]][finish[1]]
    path = []
    here = finish
    for j in range(path_len - 1, -1, -1):
        path.append(here)
        for dx, dy in next_step:
            next_pos = (here[0] + dx, here[1] + dy)
            if 1 <= next_pos[0] <= length + 1 and 1 <= next_pos[1] <= length + 1 and grid[next_pos[0]][next_pos[1]] == j:
                break
        here = next_pos
    return path_len, path

# 将已经布线的方格设置为 -1
grid[2][3] = grid[3][4] = grid[3][5] = grid[4][2] = -1

start = (1, 1) # 布线起始点
print(f'#起始点: {start[0]:>3}{start[1]:>3}')

finish = (4, 4) # 布线终点
print(f'#终点:  {finish[0]:>3}{finish[1]:>3}')

path_len_and_path = find_path(start, finish)
if path_len_and_path is False:
    print("No path found.")
else:
    path_len, path = path_len_and_path
    print('\n#最终结果: ')
    print_grid()
    print(f'#最短路径长度: {path_len - 1}')
    for i, pos in enumerate(path):
        if i > 0:
            print(f'->({pos[0]},{pos[1]})', end='')
    print()

将起始点设置为(1,1),终点设置为(4,4)时,运行结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值