【论文阅读及复现】(1998)无网格线探索布线算法 + Python代码实现

简介: - 提出的一种高效快速的无网格线探索布线算法- 适用于焊盘外形尺寸不一,线宽及线间距离可变的印制电路板及MCM 电路布线- 精心设计的数据结构及灵活的绕障探索方式可大大地提高搜索效率- 多级多遍优化策略为改善布线结果提供了可靠的保证- 该算法已成功地应用于通用印制电路板设计系统MPCB,取得了令人满意的效果

@[toc]


论文来源:(1998)无网格线探索布线算法
作者:杨瑞元

一、摘要

  • 提出的一种高效快速的无网格线探索布线算法
  • 适用于焊盘外形尺寸不一,线宽及线间距离可变的印制电路板及MCM 电路布线
  • 精心设计的数据结构及灵活的绕障探索方式可大大地提高搜索效率
  • 多级多遍优化策略为改善布线结果提供了可靠的保证
  • 该算法已成功地应用于通用印制电路板设计系统MPCB,取得了令人满意的效果

二、单层无网格线探索算法

2.1 形式描述

2.1.1 探索线

  • 探索线是一条以当前点为起点,有预定终点和一定宽度的水平、垂直或斜向射线
  • 探索线的宽度即用来连接待连点对的连线宽度

2.1.2 探索过程

探索过程实质上是一个检查计算过程,就是按照从起点至预定终点的方向,逐一检查前面或两侧是否有焊盘、过孔或已布连线等障碍物阻碍探索线直通预定终点的过程

2.1.3 绕障偏移量

为了绕过障碍,同一方向的下一探索线必须偏离当前线探索的中心距离,称为绕障偏离量
相对每一障碍,可有正负两个绕障偏移量,其计算公式如下:
$$负偏移量I_{off}=Y_1-Y_c<0$$ $$正偏移量L_{off}=Y_2-Y_c>0$$

在这里插入图片描述

2.2 变量说明

在这里插入图片描述

变量名 含义
L 布线栈顶指针,其值为栈中探索线数+1
L1 探索方向控制变量,根据其值为0或1来决定下一步探索为横向或竖向
KC 当前探索方向
KF 上一段探索方向
KP 当前探索状态标志。KP=0表示当前方向探索成功,可以产生探索线段( 但不一定到达预定终点) ;如KP>0,表示当前探索失败,不能产生探索线段
KB 布通标志。KB=0,表示探索线抵达预定终点;KB=2,表示探索线遇阻,未抵达预定终点;KB=1,表示探索线到达目标点,或与本信号组已布连线连通
IB 上一探索线段的布通标志
(Xc,Yc) 当前点坐标
(Xs,Ys) 起点坐标
(Xt,Yt) 终点坐标

2.3 启发式规则

下面的启发式规则是根据我自己理解来的,并加入了一些改进(仅供参考)

2.3.1 I型绕障

在这里插入图片描述

2.3.2 L型绕障

暂未理解:我采用逐步试探,正常递归

在这里插入图片描述

2.3.3 U型绕障

暂未理解:我采用逐步试探,正常递归

在这里插入图片描述

2.3.4 启发式阻停

由于无网格线探索算法中,每一步的行走都是有固定步长的,如果步长过大,就会导致 线在终点来回搜索的情况出现。为了避免这个情况,特设定此规则, 在行进过程中会被终点坐标“阻停”。

在这里插入图片描述

2.4 Python代码实现

下图展示了需要设置的参数

在这里插入图片描述

下图展示了运行的示例

在这里插入图片描述

下图展示了路径可视化图:

在这里插入图片描述

# -*-coding:utf-8-*-
# Author: WSKH
# Blog: wskh0929.blog.csdn.net
# Time: 2022/10/12 14:54

# 无网格线探索模型
import time

# 线对象
class Line:
    def __init__(self, startPos, tempObstacleList):
        self.lineArr = [[startPos[0], startPos[1]]]
        self.length = 0
        self.tempObstacleList = tempObstacleList
        self.flags = [0, 0, 0, 0]

    def append(self, pos):
        lastPos = self.lineArr[len(self.lineArr) - 1]
        self.lineArr.append(pos)
        self.length += abs(lastPos[0] - pos[0]) if abs(lastPos[0] - pos[0]) else abs(lastPos[1] - pos[1])

    def getAllAttributeByLine(self, line):
        self.lineArr = line.lineArr.copy()
        self.tempObstacleList = line.tempObstacleList.copy()
        self.length = line.length
        self.L1 = line.L1
        self.Xd = line.Xd
        self.Yd = line.Yd
        self.Xc = line.Xc
        self.Yc = line.Yc
        self.KP = line.KP
        self.flags = line.flags.copy()
        self.L = line.L
        self.IB = line.IB
        self.KC = line.KC
        self.KB = line.KB
        self.exploreRange = line.exploreRange
        self.lineWidth = line.lineWidth
        self.lineItemEdge = line.lineItemEdge
        self.lineEdge = line.lineEdge
        self.obstacle = line.obstacle.copy() if line.obstacle is not None else None
        self.KF = line.KF
        self.flags = line.flags.copy()

    def resetFlags(self):
        self.flags = [0, 0, 0, 0]

# 矩形模块类(程序会将L型、T型划分为此类)
class RectItem:
    def __init__(self, left_bottom_point, w, h, name):
        self.left_bottom_point = left_bottom_point.copy()
        self.w, self.h = w, h
        self.name = name

# 模块类
class Item:
    def __init__(self, name, boundary):
        self.name = name

        self.standardBoundary = boundary.copy()
        min_x = min_y = None
        for p in self.standardBoundary:
            if min_x is None or min_x > p[0]:
                min_x = p[0]
            if min_y is None or min_y > p[1]:
                min_y = p[1]
        self.standardBoundary = [[p[0] - min_x, p[1] - min_y] for p in self.standardBoundary]

        self.left_bottom_point = [min_x, min_y]
        self.boundary = boundary
        self.init_item()

    def to_string(self):
        return 'Item', {
            'name': self.name,
            'boundary': self.boundary,
        }

    def init_item(self):
        # 计算其包络矩形的宽和高
        self.w, self.h = calc_envelope_rectangle_w_h(self.standardBoundary)
        # 计算所有竖着线段(x,y,l)
        self.vertical_line_list = calc_vertical_line_list(self.standardBoundary)
        # 计算所有水平线段(x,y,l)
        self.horizontal_line_list = calc_horizontal_line_list(self.standardBoundary)
        # 获取着地水平线段(x,y,l)
        for horizontal_line in self.horizontal_line_list:
            if horizontal_line[1] == 0:
                self.floor_horizontal_line = horizontal_line
                break
        # 计算放入当前模块将会新增的天际线(x,y,l)
        self.add_sky_line_list = calc_add_sky_line_list(self.horizontal_line_list)
        # 找到第二高度
        self.sec_y = None
        for x, y in self.standardBoundary:
            if y != 0 and (self.sec_y is None or self.sec_y > y):
                self.sec_y = y
        # 计算对标点
        self.aim_point_list = calc_aim_point_list(self.standardBoundary)
        # 获取当前模块type
        if len(self.standardBoundary) == 4:
            self.rect_list = [[0, 0, self.w, self.h]]
        elif len(self.standardBoundary) == 6:
            # L型
            if len(self.add_sky_line_list) == 1:
                if len(self.aim_point_list) == 2:
                    self.type = '180'
                    self.w2 = self.floor_horizontal_line[2]
                    self.w1 = self.w - self.w2
                    self.h2 = self.sec_y
                    self.h1 = self.h - self.h2
                    self.rect_list = [[0, self.h2, self.w1, self.h1], [self.w1, 0, self.w2, self.h]]
                elif len(self.aim_point_list) == 1:
                    self.type = '90'
                    self.w1 = self.floor_horizontal_line[2]
                    self.w2 = self.w - self.w1
                    self.h1 = self.sec_y
                    self.h2 = self.h - self.h1
                    self.rect_list = [[0, 0, self.w1, self.h], [self.w1, self.h1, self.w2, self.h2]]
            elif len(self.add_sky_line_list) == 2:
                # 找到(0,0)这个点,通过判断其两边的情况,判断是0度还是270度
                i = 0
                while i < 6:
                    if self.standardBoundary[i][0] == 0 and self.standardBoundary[i][1] == 0:
                        i_f = i - 1 if i - 1 >= 0 else 5
                        i_b = i + 1 if i + 1 < 6 else 0
                        if self.standardBoundary[i_f][1] == self.h or self.standardBoundary[i_b][1] == self.h:
                            self.type = '0'
                            for add_sky_line in self.add_sky_line_list:
                                if add_sky_line[0] == 0:
                                    self.w1 = add_sky_line[2]
                                elif add_sky_line[0] + add_sky_line[2] == self.w:
                                    self.w2 = add_sky_line[2]
                                    self.h2 = add_sky_line[1]
                                    self.h1 = self.h - self.h2
                            self.rect_list = [[0, 0, self.w1, self.h], [self.w1, 0, self.w2, self.h2]]
                        else:
                            self.type = '270'
                            for add_sky_line in self.add_sky_line_list:
                                if add_sky_line[0] == 0:
                                    self.w1 = add_sky_line[2]
                                    self.h1 = add_sky_line[1]
                                    self.h2 = self.h - self.h1
                                elif add_sky_line[0] + add_sky_line[2] == self.w:
                                    self.w2 = add_sky_line[2]
                            self.rect_list = [[0, 0, self.w1, self.h1], [self.w1, 0, self.w2, self.h]]
                        break
                    i += 1
        elif len(self.standardBoundary) == 8:
            # T型
            if len(self.add_sky_line_list) == 1:
                self.type = '180'
                self.w2 = self.floor_horizontal_line[2]
                for horizontal_line in self.horizontal_line_list:
                    if horizontal_line[0] == 0 and horizontal_line[2] < self.w:
                        self.w1 = horizontal_line[2]
                        self.h2 = self.h - horizontal_line[1]
                        self.h1 = self.h - self.h2
                    elif horizontal_line[0] != 0 and horizontal_line[0] + horizontal_line[2] == self.w:
                        self.w3 = horizontal_line[2]
                        self.h3 = horizontal_line[1]
                        self.h4 = self.h - self.h3
                self.rect_list = [[0, self.h2, self.w1, self.h], [self.w1, 0, self.w2, self.h],
                                  [self.w1 + self.w2, self.h3, self.w3, self.h4]]
            elif len(self.add_sky_line_list) == 2:
                if len(self.aim_point_list) == 2:
                    self.type = '270'
                    self.w1 = self.floor_horizontal_line[2]
                    for add_sky_line in self.add_sky_line_list:
                        if add_sky_line[0] == 0:
                            self.w3 = add_sky_line[2]
                            self.h3 = self.h - add_sky_line[1]
                        else:
                            self.w4 = add_sky_line[2]
                    for horizontal_line in self.horizontal_line_list:
                        if horizontal_line[0] == 0 and horizontal_line[1] < self.h - self.h3:
                            self.w2 = horizontal_line[2]
                            self.h1 = horizontal_line[1]
                            self.h2 = self.h - self.h1 - self.h3
                            break
                    self.rect_list = [[self.w2, 0, self.w1, self.h1], [0, self.h1, self.w, self.h2],
                                      [self.w3, self.h1 + self.h2, self.w4, self.h3]]
                elif len(self.aim_point_list) == 1:
                    self.type = '90'
                    self.w1 = self.floor_horizontal_line[2]
                    for add_sky_line in self.add_sky_line_list:
                        if add_sky_line[0] == 0:
                            self.w4 = add_sky_line[2]
                        else:
                            self.w3 = add_sky_line[2]
                            self.h1 = self.h - add_sky_line[1]
                    for horizontal_line in self.horizontal_line_list:
                        if horizontal_line[0] + horizontal_line[2] == self.w and horizontal_line[1] < self.h - self.h1:
                            self.w2 = horizontal_line[2]
                            self.h3 = horizontal_line[1]
                            self.h2 = self.h - self.h1 - self.h3
                            break
                    self.rect_list = [[0, 0, self.w1, self.h3], [0, self.h3, self.w, self.h2],
                                      [0, self.h2 + self.h3, self.w4, self.h1]]
            elif len(self.add_sky_line_list) == 3:
                self.type = '0'
                for asl in self.add_sky_line_list:
                    if asl[0] == 0:
                        self.h1 = asl[1]
                        self.w1 = asl[2]
                        self.h2 = self.h - self.h1
                    elif asl[0] + asl[2] == self.w:
                        self.h4 = asl[1]
                        self.w3 = asl[2]
                        self.h3 = self.h - self.h4
                self.w2 = self.w - self.w1 - self.w3
                self.rect_list = [[0, 0, self.w1, self.h1], [self.w1, 0, self.w2, self.h],
                                  [self.w1 + self.w2, 0, self.w3, self.h4]]

class NoGridLineExploreModel:

    def __init__(self, items_list, area):
        self.items_list = items_list
        self.area = area

        self.rect_items_list = []
        for item in self.items_list:
            for rect in item.rect_list:
                self.rect_items_list.append(
                    RectItem([rect[0] + item.left_bottom_point[0], rect[1] + item.left_bottom_point[1]], rect[2],
                             rect[3], item.name))

        self.areaMinX, self.areaMaxX, self.areaMinY, self.areaMaxY = None, None, None, None
        for a in area:
            if self.areaMinX is None or self.areaMinX > a[0]:
                self.areaMinX = a[0]
            if self.areaMaxX is None or self.areaMaxX < a[0]:
                self.areaMaxX = a[0]
            if self.areaMinY is None or self.areaMinY > a[1]:
                self.areaMinY = a[1]
            if self.areaMaxY is None or self.areaMaxY < a[1]:
                self.areaMaxY = a[1]

    def solve(self, instanceArr):
        # 算法参数
        self.error = 1e-6  # 浮点数误差
        self.exploreRange = 20  # 步长(探索范围)
        self.maxLineLength = 150  # 最大递归深度
        self.lineWidth, self.lineEdge = 5, 5
        self.LIE = 0.5  # 线和模块的间距约束
        self.lineItemEdge = self.lineWidth / 2.0 + self.LIE  # 转化后的线和模块的间距约束
        self.maxTime = 15
        self.dis = self.lineWidth / 2.0 + self.lineEdge - self.LIE
        # 临时障碍物列表
        self.tempObstacleList = []
        # 所有连线的列表
        self.lineList = []
        # 开始探索
        for Xs, Ys, Xt, Yt in instanceArr:
            self.Xs, self.Ys, self.Xt, self.Yt = Xs, Ys, Xt, Yt
            self.startTime = time.time()
            self.LineToExplore(Line([self.Xs, self.Ys], self.tempObstacleList.copy()))
            print(str([self.Xs, self.Ys, self.Xt, self.Yt]) + " SUCCESS %.4f s" % (time.time() - self.startTime))
        # 返回成功布线的线列表
        return self.lineList

    # 指定起点,指定目的地,开始线探索
    def LineToExplore(self, line):
        # 开始进入探索
        self.step01(line)
        self.step02(line)
        return self.step03(line)

    def step01(self, line):
        self.counter = 1
        line.L = 1
        line.KB = 0
        line.KF = 0
        line.IB = 0
        line.Xc, line.Yc = self.Xs, self.Ys

    def step02(self, line):
        line.exploreRange = self.exploreRange
        line.lineWidth, line.lineEdge = self.lineWidth, self.lineEdge
        line.lineItemEdge = self.lineItemEdge

    def step03(self, line):
        if abs(self.Xt - self.Xs) < self.error:
            tempLine = copyLine2(line)
            tempLine.flags = [0, 0, 1, 1]
            tempLine = self.step05(tempLine)
            if tempLine is not None:
                return tempLine
            line.flags = [1, 1, 0, 0]
            return self.step04(line)
        elif abs(self.Yt - self.Ys) < self.error:
            tempLine = copyLine2(line)
            tempLine.flags = [1, 1, 0, 0]
            tempLine = self.step04(tempLine)
            if tempLine is not None:
                return tempLine
            line.flags = [0, 0, 1, 1]
            return self.step05(line)
        elif abs(self.Xt - self.Xs) >= abs(self.Yt - self.Ys):
            tempLine = copyLine2(line)
            tempLine.flags = [0, 0, 1, 1]
            tempLine = self.step05(tempLine)
            if tempLine is not None:
                return tempLine
            line.flags = [1, 1, 0, 0]
            return self.step04(line)
        else:
            tempLine = copyLine2(line)
            tempLine.flags = [1, 1, 0, 0]
            tempLine = self.step04(tempLine)
            if tempLine is not None:
                return tempLine
            line.flags = [0, 0, 1, 1]
            return self.step05(line)

    def step04(self, line):
        line.obstacle = None
        if line.flags[2] == 0 and line.flags[3] == 0:
            if self.Xt > line.Xc:
                tempLine = copyLine(line)
                self.rightExplore(tempLine)
                if self.step06(tempLine) is not None:
                    line.getAllAttributeByLine(tempLine)
                    return line
                self.leftExplore(line)
                return self.step06(line)
            else:
                tempLine = copyLine(line)
                self.leftExplore(tempLine)
                if self.step06(tempLine) is not None:
                    line.getAllAttributeByLine(tempLine)
                    return line
                self.rightExplore(line)
                return self.step06(line)
        elif line.flags[2] == 0:
            self.leftExplore(line)
            return self.step06(line)
        elif line.flags[3] == 0:
            self.rightExplore(line)
            return self.step06(line)
        return None
        # raise RuntimeError("self.Yt == line.Yc , " + str(line.flags))

    def step05(self, line):
        line.obstacle = None
        if line.flags[0] == 0 and line.flags[1] == 0:
            if self.Yt > line.Yc:
                tempLine = copyLine(line)
                self.upExplore(tempLine)
                if self.step06(tempLine) is not None:
                    line.getAllAttributeByLine(tempLine)
                    return line
                self.downExplore(line)
                return self.step06(line)
            else:
                tempLine = copyLine(line)
                self.downExplore(tempLine)
                if self.step06(tempLine) is not None:
                    line.getAllAttributeByLine(tempLine)
                    return line
                self.upExplore(line)
                return self.step06(line)
        elif line.flags[0] == 0:
            self.upExplore(line)
            return self.step06(line)
        elif line.flags[1] == 0:
            self.downExplore(line)
            return self.step06(line)
        return None
        # raise RuntimeError("self.Yt == line.Yc , " + str(line.flags))

    def step06(self, line):
        if line.KP > 0:
            # 1:横向探索遇障碍点
            # 2:竖向探索遇障碍点
            return self.step10(line)
        else:
            return self.step07(line)

    def step07(self, line):
        # 其他参数更新
        if abs(line.Xc - line.Xd) < self.error and abs(line.Yc - line.Yd) < self.error:
            return None
        else:
            # 增加临时障碍 [w,h,l_x,l_y]
            if line.KC == 1:
                line.tempObstacleList.append([line.Xd - line.Xc + 2 * self.dis, 2 * self.dis,
                                              line.Xc - self.dis,
                                              line.Yc - self.dis])
            elif line.KC == 5:
                line.tempObstacleList.append([line.Xc - line.Xd + 2 * self.dis, 2 * self.dis,
                                              line.Xd - self.dis,
                                              line.Yd - self.dis])
            elif line.KC == 3:
                line.tempObstacleList.append([2 * self.dis, line.Yd - line.Yc + 2 * self.dis,
                                              line.Xc - self.dis,
                                              line.Yc - self.dis])
            elif line.KC == 7:
                line.tempObstacleList.append([2 * self.dis, line.Yc - line.Yd + 2 * self.dis,
                                              line.Xd - self.dis,
                                              line.Yd - self.dis])
            else:
                raise RuntimeError("line.KC = " + str(line.KC))
            line.L += 1
            line.Xc, line.Yc = line.Xd, line.Yd
            if self.isArriveDestination(line.Xc, line.Yc):
                line.KB = 1
            line.append([line.Xd, line.Yd])
            line.KF = line.KC
            line.IB = line.KB
            if line.KC == 1:
                line.flags = [0, 0, 1, 0]
            elif line.KC == 3:
                line.flags = [0, 1, 0, 0]
            elif line.KC == 5:
                line.flags = [0, 0, 0, 1]
            elif line.KC == 7:
                line.flags = [1, 0, 0, 0]
            return self.step08(line)

    def step08(self, line):
        if time.time() - self.startTime > self.maxTime or len(line.lineArr) > self.maxLineLength:
            return None
        elif line.KB == 1:
            # 出口
            self.lineList.append(copyLine(line))
            self.tempObstacleList = line.tempObstacleList.copy()
            return line
        else:

            # if len(self.lineList) == 0:
            #     print("lineList:" + str([line.lineArr]) + ",")
            #     # print(str(line.flags) + " , lineList:" + str([line.lineArr]) + ",")

            # if str(line.lineArr) == "[[350, 480], [350, 487.0]]":
            #     print("e")

            # if str([self.Xs, self.Ys, self.Xt, self.Yt, self.startPointFlag,
            #         self.endPointFlag]) == "[84.5, 611.5, 123.5, 426.5, 'M2-2', 'M1-2']":
            #     print("lineList:" + str([line.lineArr]) + ",")

            # TODO:可优化,不必每次都计算,可以随着点链lineArr的更新而更新
            if len(line.lineArr) >= 2:
                # flag = vertical 或 horizontal
                lastLongestDistance, flag = self.calcLastLongestDistance(line.lineArr)
                if lastLongestDistance < line.lineWidth + line.lineEdge:
                    if flag == "vertical":
                        line.flags[2] = 1
                        line.flags[3] = 1
                    elif flag == "horizontal":
                        line.flags[0] = 1
                        line.flags[1] = 1
                    else:
                        raise RuntimeError("flag = " + flag)
            return self.step09(line)

    def step09(self, line):
        if line.KB == 2 and line.obstacle is not None and (line.KF == 3 or line.KF == 7):
            # 竖向受阻且终点在障碍物的水平维度内
            return self.horizontalPassObstacles(line)
        elif line.KB == 2 and line.obstacle is not None and (line.KF == 1 or line.KF == 5):
            # 横向受阻且终点在障碍物的竖直维度内
            return self.verticalPassObstacles(line)
        elif abs(line.Xc - self.Xt) < self.error:
            tempLine = copyLine(line)
            r = self.step05(tempLine)
            if r is None:
                return self.step04(line)
            line.getAllAttributeByLine(tempLine)
            return r
        elif abs(line.Yc - self.Yt) < self.error:
            tempLine = copyLine(line)
            r = self.step04(tempLine)
            if r is None:
                return self.step05(line)
            line.getAllAttributeByLine(tempLine)
            return r
        else:

            if line.L1 == 0:
                if line.KF == 1 and self.Xt < line.Xc:
                    line.L1 = 1
                elif line.KF == 5 and self.Xt > line.Xc:
                    line.L1 = 1
            else:
                if line.KF == 3 and self.Yt < line.Yc:
                    line.L1 = 0
                elif line.KF == 7 and self.Yt > line.Yc:
                    line.L1 = 0

            # line.L1 = 1 - line.L1

            if line.L1 == 0:
                tempLine = copyLine(line)
                r = self.step04(tempLine)
                if r is None:
                    return self.step05(line)
                line.getAllAttributeByLine(tempLine)
                return r
            else:
                tempLine = copyLine(line)
                r = self.step05(tempLine)
                if r is None:
                    return self.step04(line)
                line.getAllAttributeByLine(tempLine)
                return r

    def step10(self, line):
        line.obstacle = None
        # KP = 1:横向探索遇障碍点
        # KP = 2:竖向探索遇障碍点
        if line.KP == 1:
            if line.KF == 3:
                if line.flags[0] == 0:
                    # 上次探索为向上,则这次只能向上
                    self.upExplore(line)
                    return self.step06(line)
                return None
            elif line.KF == 7:
                if line.flags[1] == 0:
                    # 上次探索为向下,则这次只能向下
                    self.downExplore(line)
                    return self.step06(line)
                return None
            else:
                # 上次探索是横向的,则这次又可以向上也可以向下
                return self.step05(line)
        elif line.KP == 2:
            if line.KF == 1:
                if line.flags[3] == 0:
                    # 上次探索为向右,则这次只能向右
                    self.rightExplore(line)
                    return self.step06(line)
                return None
            elif line.KF == 5:
                if line.flags[2] == 0:
                    # 上次探索为向左,则这次只能向左
                    self.leftExplore(line)
                    return self.step06(line)
                return None
            else:
                # 上次探索是竖向的,则这次又可以向左也可以向右
                return self.step04(line)
        else:
            raise RuntimeError("line.KP = " + str(line.KP))

    # 横向绕障
    def horizontalPassObstacles(self, line):
        line.L1 = 0
        w, h, x, y = line.obstacle
        le = line.exploreRange
        if line.flags[2] == 0 and line.flags[3] == 0:
            if line.obstacle[
                2] < self.Xt < line.obstacle[2] + \
                    line.obstacle[0]:
                b = line.Xc - x + h + self.Xt - x <= x + w - line.Xc + h + x + w - self.Xt
            else:
                b = line.Xc >= self.Xt
            if b is True:
                tempLine = copyLine(line)
                # 首先向左绕障碍试试
                tempLine.exploreRange = tempLine.Xc - x + tempLine.lineItemEdge
                moveDis = self.leftExplore(tempLine, isSmart=False)
                if abs(moveDis - tempLine.exploreRange) < self.error:
                    tempLine.exploreRange = le
                    line.getAllAttributeByLine(tempLine)
                    return self.step06(line)
                # 向左不行 向右试试
                line.exploreRange = x + w + line.lineItemEdge - line.Xc
                self.rightExplore(line, isSmart=False)
                line.exploreRange = le
                return self.step06(line)
            else:
                tempLine = copyLine(line)
                # 首先向右绕障碍试试
                tempLine.exploreRange = x + w + tempLine.lineItemEdge - tempLine.Xc
                moveDis = self.rightExplore(tempLine, isSmart=False)
                if abs(moveDis - tempLine.exploreRange) < self.error:
                    tempLine.exploreRange = le
                    line.getAllAttributeByLine(tempLine)
                    return self.step06(line)
                # 向右不行 向左试试
                line.exploreRange = line.Xc - x + line.lineItemEdge
                self.leftExplore(line, isSmart=False)
                line.exploreRange = le
                return self.step06(line)
        elif line.flags[2] == 0:
            # 向左
            line.exploreRange = line.Xc - x + line.lineItemEdge
            self.leftExplore(line, isSmart=False)
            line.exploreRange = le
            return self.step06(line)
        elif line.flags[3] == 0:
            # 向右
            line.exploreRange = x + w + line.lineItemEdge - line.Xc
            self.rightExplore(line, isSmart=False)
            line.exploreRange = le
            return self.step06(line)
        return None

    # 竖向绕障
    def verticalPassObstacles(self, line):
        line.L1 = 1
        w, h, x, y = line.obstacle
        le = line.exploreRange
        if line.flags[0] == 0 and line.flags[1] == 0:
            if line.obstacle[
                3] < self.Yt < line.obstacle[3] + \
                    line.obstacle[1]:
                b = line.Yc - y + w + self.Yt - y <= y + h - line.Yc + w + y + h - self.Yt
            else:
                b = line.Yc >= self.Yt
            if b is True:
                tempLine = copyLine(line)
                # 首先向下绕障碍试试
                tempLine.exploreRange = tempLine.Yc - y + tempLine.lineItemEdge
                moveDis = self.downExplore(tempLine, isSmart=False)
                if abs(moveDis - tempLine.exploreRange) < self.error:
                    tempLine.exploreRange = le
                    line.getAllAttributeByLine(tempLine)
                    return self.step06(line)
                # 向下不行 向上试试
                line.exploreRange = y + h + line.lineItemEdge - line.Yc
                self.upExplore(line, isSmart=False)
                line.exploreRange = le
                return self.step06(line)
            else:
                tempLine = copyLine(line)
                # 首先向上绕障碍试试
                tempLine.exploreRange = y + h + line.lineItemEdge - line.Yc
                moveDis = self.upExplore(tempLine, isSmart=False)
                if abs(moveDis - tempLine.exploreRange) < self.error:
                    tempLine.exploreRange = le
                    line.getAllAttributeByLine(tempLine)
                    return self.step06(line)
                # 向上不行 向下试试
                line.exploreRange = line.Yc - y + line.lineItemEdge
                self.downExplore(line, isSmart=False)
                line.exploreRange = le
                return self.step06(line)
        elif line.flags[0] == 0:
            # 向上
            line.exploreRange = y + h + line.lineItemEdge - line.Yc
            self.upExplore(line, isSmart=False)
            line.exploreRange = le
            return self.step06(line)
        elif line.flags[1] == 0:
            # 向下
            line.exploreRange = line.Yc - y + line.lineItemEdge
            self.downExplore(line, isSmart=False)
            line.exploreRange = le
            return self.step06(line)
        return None

    # 向右探索
    def rightExplore(self, line, isSmart=True):
        if line.flags[3] == 1:
            raise RuntimeError
        if sum(line.flags) == 3:
            isSmart = False
        line.L1 = 0
        line.flags[3] = 1
        # 往右探索
        line.KC = 1
        step = min(line.exploreRange, self.areaMaxX - line.Xc - line.lineWidth / 2.0)
        if step < 0:
            return 0
        for item in self.rect_items_list:
            # 在当前点的右边才进行判断,且在判断范围内
            if line.Xc + line.lineItemEdge <= item.left_bottom_point[0] <= line.Xc + step + line.lineItemEdge:
                # 如果不满足安全距离
                if item.left_bottom_point[1] - line.lineItemEdge < line.Yc < item.left_bottom_point[
                    1] + item.h + line.lineItemEdge:
                    if item.left_bottom_point[0] - line.lineItemEdge - line.Xc < step:
                        line.obstacle = [item.w, item.h, item.left_bottom_point[0], item.left_bottom_point[1]]
                        step = item.left_bottom_point[0] - line.lineItemEdge - line.Xc
                    # 遇到死点
                    if step < self.error:
                        line.KP = 1
                        return 0
        for tempObstacle in line.tempObstacleList:
            # 在当前点的右边才进行判断,且在判断范围内
            if line.Xc + line.lineItemEdge <= tempObstacle[2] <= line.Xc + step + line.lineItemEdge:
                # 如果不满足安全距离
                if tempObstacle[3] - line.lineItemEdge < line.Yc < \
                        tempObstacle[3] + tempObstacle[1] + line.lineItemEdge:
                    if tempObstacle[2] - line.lineItemEdge - line.Xc < step:
                        step = tempObstacle[2] - line.lineItemEdge - line.Xc
                        line.obstacle = [tempObstacle[0], tempObstacle[1], tempObstacle[2],
                                         tempObstacle[3]]
                    # 遇到死点
                    if step < self.error:
                        line.KP = 1
                        return 0
        if isSmart is True and line.Xc <= self.Xt <= line.Xc + step:
            line.Xd = self.Xt
            line.obstacle = None
        else:
            line.Xd = line.Xc + step
        line.Yd = line.Yc
        if self.isArriveDestination(line.Xd, line.Yd):
            # line.KB = 1
            pass
        elif abs(step - line.exploreRange) < self.error:
            line.KB = 0
        else:
            line.KB = 2
        line.KP = 0
        return abs(line.Xd - line.Xc)

    # 向左探索
    def leftExplore(self, line, isSmart=True):
        if line.flags[2] == 1:
            raise RuntimeError
        if sum(line.flags) == 3:
            isSmart = False
        line.L1 = 0
        line.flags[2] = 1
        # 往左探索
        line.KC = 5
        step = min(line.exploreRange, line.Xc - self.areaMinX - line.lineWidth / 2.0)
        if step < 0:
            return 0
        for item in self.rect_items_list:
            # 在当前点的左边才进行判断,且在判断范围内
            if line.Xc - step - line.lineItemEdge <= item.left_bottom_point[
                0] + item.w <= line.Xc - line.lineItemEdge:
                # 如果不满足安全距离,则进行step限制
                if item.left_bottom_point[1] - line.lineItemEdge < line.Yc < item.left_bottom_point[
                    1] + item.h + line.lineItemEdge:
                    if line.Xc - (item.w + item.left_bottom_point[0]) - line.lineItemEdge < step:
                        step = line.Xc - (item.w + item.left_bottom_point[0]) - line.lineItemEdge
                        line.obstacle = [item.w, item.h, item.left_bottom_point[0], item.left_bottom_point[1]]
                    # 遇到死点
                    if step < self.error:
                        line.KP = 1
                        return 0
        for tempObstacle in line.tempObstacleList:
            # 在当前点的左边才进行判断,且在判断范围内
            if line.Xc - step - line.lineItemEdge <= tempObstacle[2] + tempObstacle[0] <= line.Xc - line.lineItemEdge:
                # 如果不满足安全距离,则进行step限制
                if tempObstacle[3] - line.lineItemEdge < line.Yc < \
                        tempObstacle[3] + tempObstacle[1] + line.lineItemEdge:
                    if line.Xc - (tempObstacle[0] + tempObstacle[2]) - line.lineItemEdge < step:
                        line.obstacle = [tempObstacle[0], tempObstacle[1], tempObstacle[2],
                                         tempObstacle[3]]
                        step = line.Xc - (tempObstacle[0] + tempObstacle[2]) - line.lineItemEdge
                    # 遇到死点
                    if step < self.error:
                        line.KP = 1
                        return 0
        if isSmart is True and line.Xc - step <= self.Xt <= line.Xc:
            line.Xd = self.Xt
            line.obstacle = None
        else:
            line.Xd = line.Xc - step
        line.Yd = line.Yc
        if self.isArriveDestination(line.Xd, line.Yd):
            # line.KB = 1
            pass
        elif abs(step - line.exploreRange) < self.error:
            line.KB = 0
        else:
            line.KB = 2
        line.KP = 0
        return abs(line.Xd - line.Xc)

    # 向上探索
    def upExplore(self, line, isSmart=True):
        if line.flags[0] == 1:
            raise RuntimeError
        if sum(line.flags) == 3:
            isSmart = False
        line.L1 = 1
        line.flags[0] = 1
        # 往上探索
        line.KC = 3
        step = min(line.exploreRange, self.areaMaxY - line.Yc - line.lineWidth / 2.0)
        if step < 0:
            return 0
        for item in self.rect_items_list:
            # 在当前点的上边才进行判断,且在判断范围内
            if line.Yc + line.lineItemEdge <= item.left_bottom_point[1] <= line.Yc + step + line.lineItemEdge:
                # 如果不满足安全距离,则进行step限制
                if item.left_bottom_point[0] - line.lineItemEdge < line.Xc < item.left_bottom_point[
                    0] + item.w + line.lineItemEdge:
                    if item.left_bottom_point[1] - line.lineItemEdge - line.Yc < step:
                        line.obstacle = [item.w, item.h, item.left_bottom_point[0], item.left_bottom_point[1]]
                        step = item.left_bottom_point[1] - line.lineItemEdge - line.Yc
                    # 遇到死点
                    if step < self.error:
                        line.KP = 2
                        return 0
        for tempObstacle in line.tempObstacleList:
            # 在当前点的上边才进行判断,且在判断范围内
            if line.Yc + line.lineItemEdge <= tempObstacle[3] <= line.Yc + step + line.lineItemEdge:
                # 如果不满足安全距离,则进行step限制
                if tempObstacle[2] - line.lineItemEdge < line.Xc < tempObstacle[2] + tempObstacle[
                    0] + line.lineItemEdge:
                    if tempObstacle[3] - line.lineItemEdge - line.Yc < step:
                        step = tempObstacle[3] - line.lineItemEdge - line.Yc
                        line.obstacle = [tempObstacle[0], tempObstacle[1], tempObstacle[2],
                                         tempObstacle[3]]
                    # 遇到死点
                    if step < self.error:
                        line.KP = 2
                        return 0
        if isSmart is True and line.Yc <= self.Yt <= line.Yc + step:
            line.Yd = self.Yt
            line.obstacle = None
        else:
            line.Yd = line.Yc + step
        line.Xd = line.Xc
        if self.isArriveDestination(line.Xd, line.Yd):
            # line.KB = 1
            pass
        elif abs(step - line.exploreRange) < self.error:
            line.KB = 0
        else:
            line.KB = 2
        line.KP = 0
        return abs(line.Yd - line.Yc)

    # 向下探索
    def downExplore(self, line, isSmart=True):
        if line.flags[1] == 1:
            raise RuntimeError
        if sum(line.flags) == 3:
            isSmart = False
        line.L1 = 1
        line.flags[1] = 1
        # 往下探索
        line.KC = 7
        step = min(line.exploreRange, line.Yc - self.areaMinY - line.lineWidth / 2.0)
        if step < 0:
            return 0
        for item in self.rect_items_list:
            # 在当前点的左边才进行判断,且在判断范围内
            if line.Yc - step - line.lineItemEdge <= item.left_bottom_point[
                1] + item.h <= line.Yc - line.lineItemEdge:
                # 如果不满足安全距离
                if item.left_bottom_point[0] - line.lineItemEdge < line.Xc < item.left_bottom_point[
                    0] + item.w + line.lineItemEdge:
                    if line.Yc - (item.h + item.left_bottom_point[1]) - line.lineItemEdge < step:
                        step = line.Yc - (item.h + item.left_bottom_point[1]) - line.lineItemEdge
                        line.obstacle = [item.w, item.h, item.left_bottom_point[0], item.left_bottom_point[1]]
                    # 遇到死点
                    if step < self.error:
                        line.KP = 2
                        return 0
        for tempObstacle in line.tempObstacleList:
            # 在当前点的左边才进行判断,且在判断范围内
            if line.Yc - step - line.lineItemEdge <= tempObstacle[3] + tempObstacle[1] <= line.Yc - line.lineItemEdge:
                # 如果不满足安全距离
                if tempObstacle[2] - line.lineItemEdge < line.Xc < tempObstacle[2] + tempObstacle[
                    0] + line.lineItemEdge:
                    if line.Yc - (tempObstacle[1] + tempObstacle[3]) - line.lineItemEdge < step:
                        step = line.Yc - (tempObstacle[1] + tempObstacle[3]) - line.lineItemEdge
                        line.obstacle = [tempObstacle[0], tempObstacle[1], tempObstacle[2],
                                         tempObstacle[3]]
                    # 遇到死点
                    if step < self.error:
                        line.KP = 2
                        return 0
        if isSmart is True and line.Yc - step <= self.Yt <= line.Yc:
            line.Yd = self.Yt
            line.obstacle = None
        else:
            line.Yd = line.Yc - step
        line.Xd = line.Xc
        if self.isArriveDestination(line.Xd, line.Yd):
            # line.KB = 1
            pass
        elif abs(step - line.exploreRange) < self.error:
            line.KB = 0
        else:
            line.KB = 2
        line.KP = 0
        return abs(line.Yd - line.Yc)

    # 判断点是否到达终点
    def isArriveDestination(self, x, y):
        return abs(x - self.Xt) < self.error and abs(y - self.Yt) < self.error

    # 传入点链,计算上一段水平或垂直的最长距离
    def calcLastLongestDistance(self, lineArr):
        lastLongestDistance = 0
        flag = None  # vertical   horizontal
        for i in range(len(lineArr) - 1):
            i = len(lineArr) - i - 1
            j = i - 1
            if flag is None:
                if lineArr[i][0] == lineArr[j][0]:
                    flag = "vertical"
                    lastLongestDistance += abs(lineArr[i][1] - lineArr[j][1])
                else:
                    flag = "horizontal"
                    lastLongestDistance += abs(lineArr[i][0] - lineArr[j][0])
            elif flag == "horizontal":
                if lineArr[i][0] == lineArr[j][0]:
                    break
                lastLongestDistance += abs(lineArr[i][0] - lineArr[j][0])
            elif flag == "vertical":
                if lineArr[i][1] == lineArr[j][1]:
                    break
                lastLongestDistance += abs(lineArr[i][1] - lineArr[j][1])
        return lastLongestDistance, flag

def copyLine(line):
    copyLine = Line(line.lineArr[0], line.tempObstacleList.copy())
    copyLine.lineArr = line.lineArr.copy()
    copyLine.length = line.length
    try:
        copyLine.L1 = line.L1
    except:
        copyLine.L1 = 0
    try:
        copyLine.Xd = line.Xd
    except:
        copyLine.Xd = line.Xc
    try:
        copyLine.Yd = line.Yd
    except:
        copyLine.Yd = line.Yc
    copyLine.Xc = line.Xc
    copyLine.Yc = line.Yc
    copyLine.flags = line.flags.copy()
    copyLine.L = line.L
    try:
        copyLine.KC = line.KC
    except:
        copyLine.KC = 0
    copyLine.KB = line.KB
    try:
        copyLine.KP = line.KP
    except:
        copyLine.KP = 0
    copyLine.IB = line.IB
    copyLine.exploreRange = line.exploreRange
    copyLine.lineWidth = line.lineWidth
    copyLine.lineItemEdge = line.lineItemEdge
    copyLine.lineEdge = line.lineEdge
    copyLine.obstacle = line.obstacle.copy() if line.obstacle is not None else None
    copyLine.KF = line.KF
    copyLine.flags = line.flags.copy()
    return copyLine

def copyLine2(line):
    copyLine = Line(line.lineArr[0], line.tempObstacleList.copy())
    copyLine.lineArr = line.lineArr.copy()
    copyLine.length = line.length
    copyLine.Xc = line.Xc
    copyLine.Yc = line.Yc
    copyLine.flags = line.flags.copy()
    copyLine.L = line.L
    copyLine.KB = line.KB
    copyLine.IB = line.IB
    copyLine.exploreRange = line.exploreRange
    copyLine.lineWidth = line.lineWidth
    copyLine.lineItemEdge = line.lineItemEdge
    copyLine.lineEdge = line.lineEdge
    copyLine.KF = line.KF
    copyLine.flags = line.flags.copy()
    return copyLine

# 计算包络矩形的宽和高
def calc_envelope_rectangle_w_h(boundary):
    min_x = None
    max_x = None
    min_y = None
    max_y = None
    for x, y in boundary:
        if min_x is None:
            min_x = x
            max_x = x
            min_y = y
            max_y = y
        else:
            min_x = min(min_x, x)
            max_x = max(max_x, x)
            min_y = min(min_y, y)
            max_y = max(max_y, y)
    return max_x - min_x, max_y - min_y

# 传入多边形顶点列表,返回该多边形所有垂直线段(x,y,l)(只适用于正交多边形)
def calc_vertical_line_list(boundary):
    vertical_line_list = []
    l = len(boundary)
    for index in range(l):
        x, y = boundary[index]
        x_f, y_f = boundary[index - 1 if index - 1 >= 0 else l - 1]
        if x_f == x:
            if y < y_f:
                vertical_line_list.append((x, y, y_f - y))
                continue
        x_b, y_b = boundary[index + 1 if index + 1 < l else 0]
        if x_b == x:
            if y < y_b:
                vertical_line_list.append((x, y, y_b - y))
    return vertical_line_list

# 传入多边形顶点列表,返回该多边形所有水平线段(x,y,l)(只适用于正交多边形)
def calc_horizontal_line_list(boundary):
    horizontal_line_list = []
    l = len(boundary)
    for index in range(l):
        x, y = boundary[index]
        x_f, y_f = boundary[index - 1 if index - 1 >= 0 else l - 1]
        if y_f == y:
            if x < x_f:
                horizontal_line_list.append((x, y, x_f - x))
                continue
        x_b, y_b = boundary[index + 1 if index + 1 < l else 0]
        if y_b == y:
            if x < x_b:
                horizontal_line_list.append((x, y, x_b - x))
    return horizontal_line_list

# 传入多边形所有水平线段,返回放入当前多边形将会新增的天际线(x,y,l)
def calc_add_sky_line_list(horizontal_line_list):
    add_sky_line_list = []
    for i in range(len(horizontal_line_list)):
        x_i, y_i, l_i = horizontal_line_list[i]
        b = True
        for j in range(len(horizontal_line_list)):
            x_j, y_j, l_j = horizontal_line_list[j]
            if i != j and y_j > y_i and line_is_intersect((x_i, x_i + l_i), (x_j, x_j + l_j)):
                b = False
                break
        if b:
            add_sky_line_list.append((x_i, y_i, l_i))
    return add_sky_line_list

# 传入两条线段,返回两条线段是否相交,线段格式:(线段左端点坐标,线段右端点坐标)
def line_is_intersect(line1, line2):
    real_len = max(line1[0], line1[1], line2[0], line2[1]) - min(line1[0], line1[1], line2[0], line2[1])
    ideal_len = line1[1] - line1[0] + line2[1] - line2[0]
    return real_len < ideal_len

# 传入多边形顶点列表,计算可能的放置对标点
def calc_aim_point_list(boundary):
    aim_point_list = [(0, 0)]
    min_x = None
    for x, y in boundary:
        if y == 0:
            if min_x is None or min_x > x:
                min_x = x
    if min_x != 0:
        aim_point_list.append((min_x, 0))
    return aim_point_list

if __name__ == '__main__':

    # 构建边界顶点坐标(只支持矩形边界)
    area = [[-20.0, -20.0], [524.0, -20.0], [524.0, 742.0], [-20.0, 742.0]]

    # 构建模块(障碍物) 模块支持矩形、L型、T型
    item_boundary_list = [
        [[294.0, 20.0], [423.5, 20.0], [423.5, 60.5], [475.0, 60.5], [475.0, 155.0], [294.0, 155.0]],
        [[98.0, 231.0], [98.0, 307.0], [90.0, 307.0], [90.0, 322.0], [30.0, 322.0], [30.0, 231.0]],
        [[212.0, 372.0], [212.0, 465.5], [202.0, 465.5], [202.0, 481.0], [20.0, 481.0], [20.0, 372.0]],
        [[254.0, 20.0], [254.0, 131.5], [242.0, 131.5], [242.0, 147.0], [151.0, 147.0], [151.0, 20.0]],
        [[134.0, 521.0], [134.0, 596.5], [76.1, 596.5], [76.1, 702.0], [20.0, 702.0], [20.0, 521.0]],
        [[466.0, 205.0], [466.0, 280.5], [394.2, 280.5], [394.2, 440.0], [279.0, 440.0], [279.0, 205.0]],
        [[339.0, 490.0], [468.5, 490.0], [468.5, 504.0], [484.0, 504.0], [484.0, 680.0], [339.0, 680.0]],
        [[20.0, 20.0], [96.0, 20.0], [96.0, 28.0], [111.0, 28.0], [111.0, 181.0], [20.0, 181.0]],
        [[299.0, 521.0], [299.0, 650.5], [285.0, 650.5], [285.0, 666.0], [174.0, 666.0], [174.0, 521.0]],
        [[229.0, 187.0], [229.0, 316.5], [215.0, 316.5], [215.0, 332.0], [151.0, 332.0], [151.0, 187.0]],
    ]
    # 构建每个模型(障碍物)的名字
    item_name_list = ["M" + str(i+1) for i in range(len(item_boundary_list))]

    # 求解对象声明
    model = NoGridLineExploreModel(
        [Item(item_name_list[index], boundary) for
         index, boundary in
         enumerate(item_boundary_list)], area)

    # 构建实例 [起点x,起点y,终点x,终点y] 注意起点和终点不能在模块(障碍物)内部,否则会出现重叠问题、无法到达终点问题等
    instanceArr = [
        [350, 470, 40, 710],
        [120, 100, 330, 580],
    ]

    # 求解
    print("=" * 50 + " 程序开始运行 " + "=" * 50)
    startTime = time.time()
    lineList = model.solve(instanceArr)
    print("=" * 50 + " 程序结束,共用时:" + str(time.time() - startTime) + " s " + "=" * 50)

    # 输出
    totalLen = 0
    for line in lineList:
        totalLen += line.length
        print("lineLength: " + str(line.length) + " , lineList:" + str([line.lineArr]))
    print("成功布线数: ", len(lineList))
    lineArrList = [line.lineArr for line in lineList]
    lineListStr = "lineList:" + str(lineArrList) + ","
    print("总线长:", totalLen)
    print(lineListStr)

三、多层无网格线探索算法

无网格线探索法同样可以推广至多层印制电路板布线。
为改善布线结果,对连线路径进行的优化分别在三个层次上进行:
(1) 对单层无网格探索的局部路径优化;
(2) 对多层布线路径的全局优化;
(3) 整板布线完成后,对各线网路径的整体优化.

目录
相关文章
|
11天前
|
机器学习/深度学习 人工智能 算法
猫狗宠物识别系统Python+TensorFlow+人工智能+深度学习+卷积网络算法
宠物识别系统使用Python和TensorFlow搭建卷积神经网络,基于37种常见猫狗数据集训练高精度模型,并保存为h5格式。通过Django框架搭建Web平台,用户上传宠物图片即可识别其名称,提供便捷的宠物识别服务。
143 55
|
27天前
|
搜索推荐 Python
利用Python内置函数实现的冒泡排序算法
在上述代码中,`bubble_sort` 函数接受一个列表 `arr` 作为输入。通过两层循环,外层循环控制排序的轮数,内层循环用于比较相邻的元素并进行交换。如果前一个元素大于后一个元素,就将它们交换位置。
126 67
|
27天前
|
存储 搜索推荐 Python
用 Python 实现快速排序算法。
快速排序的平均时间复杂度为$O(nlogn)$,空间复杂度为$O(logn)$。它在大多数情况下表现良好,但在某些特殊情况下可能会退化为最坏情况,时间复杂度为$O(n^2)$。你可以根据实际需求对代码进行调整和修改,或者尝试使用其他优化策略来提高快速排序的性能
118 61
|
28天前
|
算法 数据安全/隐私保护 开发者
马特赛特旋转算法:Python的随机模块背后的力量
马特赛特旋转算法是Python `random`模块的核心,由松本真和西村拓士于1997年提出。它基于线性反馈移位寄存器,具有超长周期和高维均匀性,适用于模拟、密码学等领域。Python中通过设置种子值初始化状态数组,经状态更新和输出提取生成随机数,代码简单高效。
105 63
|
21天前
|
机器学习/深度学习 人工智能 算法
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
宠物识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了37种常见的猫狗宠物种类数据集【'阿比西尼亚猫(Abyssinian)', '孟加拉猫(Bengal)', '暹罗猫(Birman)', '孟买猫(Bombay)', '英国短毛猫(British Shorthair)', '埃及猫(Egyptian Mau)', '缅因猫(Maine Coon)', '波斯猫(Persian)', '布偶猫(Ragdoll)', '俄罗斯蓝猫(Russian Blue)', '暹罗猫(Siamese)', '斯芬克斯猫(Sphynx)', '美国斗牛犬
112 29
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
|
2天前
|
机器学习/深度学习 自然语言处理 算法
调研180多篇论文,这篇综述终于把大模型做算法设计理清了
《A Systematic Survey on Large Language Models for Algorithm Design》综述了过去三年大型语言模型(LLMs)在算法设计中的应用。LLMs通过自然语言处理技术,助力生成、优化和验证算法,在优化、机器学习、数学推理等领域展现出广泛应用前景。尽管存在资源需求高、结果不确定等挑战,LLMs仍为算法设计带来新机遇。论文地址:https://arxiv.org/abs/2410.14716。
27 14
|
1天前
|
存储 算法 Python
文件管理系统中基于 Python 语言的二叉树查找算法探秘
在数字化时代,文件管理系统至关重要。本文探讨了二叉树查找算法在文件管理中的应用,并通过Python代码展示了其实现过程。二叉树是一种非线性数据结构,每个节点最多有两个子节点。通过文件名的字典序构建和查找二叉树,能高效地管理和检索文件。相较于顺序查找,二叉树查找每次比较可排除一半子树,极大提升了查找效率,尤其适用于海量文件管理。Python代码示例包括定义节点类、插入和查找函数,展示了如何快速定位目标文件。二叉树查找算法为文件管理系统的优化提供了有效途径。
33 5
|
25天前
|
存储 算法 程序员
C 语言递归算法:以简洁代码驾驭复杂逻辑
C语言递归算法简介:通过简洁的代码实现复杂的逻辑处理,递归函数自我调用解决分层问题,高效而优雅。适用于树形结构遍历、数学计算等领域。
|
1天前
|
存储 缓存 算法
探索企业文件管理软件:Python中的哈希表算法应用
企业文件管理软件依赖哈希表实现高效的数据管理和安全保障。哈希表通过键值映射,提供平均O(1)时间复杂度的快速访问,适用于海量文件处理。在Python中,字典类型基于哈希表实现,可用于管理文件元数据、缓存机制、版本控制及快速搜索等功能,极大提升工作效率和数据安全性。
19 0
|
26天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
57 1