Beispiel #1
0
    def getPredictionRelative(self):
        model = load_model("/Users/sean/Documents/Projects/Packing-Algorithm/model/lstm_num_5_layer_128_56_2_epochs_70.h5")
        pre_train = pd.read_csv("/Users/sean/Documents/Projects/Data/pre_train.csv") # 读取形状
        _input = pd.read_csv("/Users/sean/Documents/Projects/Data/input_seq.csv") # 读取输入
        _output = pd.read_csv("/Users/sean/Documents/Projects/Data/output_relative_position.csv") # 读取输入
        
        
        # index=random.randint(4000,5000)
        index=4500

        polys=json.loads(pre_train["polys"][index]) # 形状
        X = np.array([json.loads(_input["x_256"][index])]) # 输入
        predicted_Y = model.predict(X, verbose=0)[0]*1500
        print(predicted_Y)
        Y=np.array(json.loads(_output["y"][index]))*1500
        print(Y)

        old_centroid=[0,0]
        for i,poly in enumerate(polys):
            # 获得初始的中心和预测的位置
            centroid_origin=GeoFunc.getPt(Polygon(poly).centroid)
            centroid_predicted=[Y[i][0]+old_centroid[0],Y[i][1]+old_centroid[1]] 

            # 获得新的形状并更新
            new_poly=GeoFunc.getSlide(poly,centroid_predicted[0]-centroid_origin[0],centroid_predicted[1]-centroid_origin[1])
            old_centroid=GeoFunc.getPt(Polygon(new_poly).centroid)

            PltFunc.addPolygon(poly)
            PltFunc.addPolygonColor(new_poly)

        PltFunc.showPlt()
Beispiel #2
0
 def slideToOrigin(self, poly):
     bottom_pt, min_y = [], 999999999
     for pt in poly:
         if pt[1] < min_y:
             min_y = pt[1]
             bottom_pt = [pt[0], pt[1]]
     GeoFunc.slidePoly(poly, -bottom_pt[0], -bottom_pt[1])
Beispiel #3
0
    def placePoly(self, index):
        adjoin = self.polygons[index]
        # 是否垂直
        if self.vertical == True:
            ifr = packing.PackingUtil.getInnerFitRectangle(
                self.polygons[index], self.width, self.length)
        else:
            ifr = packing.PackingUtil.getInnerFitRectangle(
                self.polygons[index], self.length, self.width)
        differ_region = Polygon(ifr)

        for main_index in range(0, index):
            main = self.polygons[main_index]
            if self.NFPAssistant == None:
                nfp = NFP(main, adjoin, rectangle=self.rectangle).nfp
            else:
                nfp = self.NFPAssistant.getDirectNFP(main, adjoin)
            nfp_poly = Polygon(nfp)
            try:
                differ_region = differ_region.difference(nfp_poly)
            except:
                print('NFP failure, polys and nfp are:')
                print([main, adjoin])
                print(nfp)
                self.showAll()
                self.showPolys([main] + [adjoin] + [nfp])
                print('NFP loaded from: ', self.NFPAssistant.history_path)

        differ = GeoFunc.polyToArr(differ_region)
        differ_index = self.getBottomLeft(differ)
        refer_pt_index = GeoFunc.checkTop(adjoin)
        GeoFunc.slideToPoint(self.polygons[index], adjoin[refer_pt_index],
                             differ[differ_index])
 def slideToContainer(self):
     # 平移部分形状
     for index, poly in enumerate(self.polys):
         right_pt = LPAssistant.getRightPoint(poly)
         if right_pt[0] > self.cur_length:
             delta_x = self.cur_length - right_pt[0]
             GeoFunc.slidePoly(poly, delta_x, 0)
             top_pt = self.poly_status[index][1]
             self.poly_status[index][1] = [top_pt[0] + delta_x, top_pt[1]]
Beispiel #5
0
    def run(self):
        self.cur_polys.append(GeoFunc.getSlide(self.polys[0], 1000,
                                               1000))  # 加入第一个形状
        self.border_left, self.border_right, self.border_bottom, self.border_top = 0, 0, 0, 0  # 初始化包络长方形
        self.border_height, self.border_width = 0, 0
        for i in range(1, len(self.polys)):
            # 更新所有的边界情况
            self.updateBound()

            # 计算NFP的合并情况
            feasible_border = Polygon(self.cur_polys[0])
            for fixed_poly in self.cur_polys:
                nfp = self.NFPAssistant.getDirectNFP(fixed_poly, self.polys[i])
                feasible_border = feasible_border.union(Polygon(nfp))

            # 获得所有可行的点
            feasible_point = self.chooseFeasiblePoint(feasible_border)

            # 获得形状的左右侧宽度
            poly_left_pt, poly_bottom_pt, poly_right_pt, poly_top_pt = GeoFunc.checkBoundPt(
                self.polys[i])
            poly_left_width, poly_right_width = poly_top_pt[0] - poly_left_pt[
                0], poly_right_pt[0] - poly_top_pt[0]

            # 逐一遍历NFP上的点,选择可行且宽度变化最小的位置
            min_change = 999999999999
            target_position = []
            for pt in feasible_point:
                change = min_change
                if pt[0] - poly_left_width >= self.border_left and pt[
                        0] + poly_right_width <= self.border_right:
                    # 形状没有超出边界,此时min_change为负
                    change = min(self.border_left - pt[0],
                                 self.border_left - pt[0])
                elif min_change > 0:
                    # 形状超出了左侧或右侧边界,若变化大于0,则需要选择左右侧变化更大的值
                    change = max(self.border_left - pt[0] + poly_left_width,
                                 pt[0] + poly_right_width - self.border_right)
                else:
                    # 有超出且min_change<=0的时候不需要改变
                    pass

                if change < min_change:
                    min_change = change
                    target_position = pt

            # 平移到最终的位置
            reference_point = self.polys[i][GeoFunc.checkTop(self.polys[i])]
            self.cur_polys.append(
                GeoFunc.getSlide(self.polys[i],
                                 target_position[0] - reference_point[0],
                                 target_position[1] - reference_point[1]))

        self.slideToBottomLeft()
        self.showResult()
Beispiel #6
0
    def __init__(self, polys, **kw):
        self.polys = PolyListProcessor.deleteRedundancy(copy.deepcopy(polys))
        self.area_list, self.first_vec_list, self.centroid_list = [], [], [
        ]  # 作为参考
        for poly in self.polys:
            P = Polygon(poly)
            self.centroid_list.append(GeoFunc.getPt(P.centroid))
            self.area_list.append(int(P.area))
            self.first_vec_list.append(
                [poly[1][0] - poly[0][0], poly[1][1] - poly[0][1]])
        self.nfp_list = [[0] * len(self.polys) for i in range(len(self.polys))]
        self.load_history = False
        self.history_path = None
        self.history = None
        if 'history_path' in kw:
            self.history_path = kw['history_path']

        if 'load_history' in kw:
            if kw['load_history'] == True:
                # 从内存中加载history 直接传递pandas的df对象 缩短I/O时间
                if 'history' in kw:
                    self.history = kw['history']
                self.load_history = True
                self.loadHistory()

        self.store_nfp = False
        if 'store_nfp' in kw:
            if kw['store_nfp'] == True:
                self.store_nfp = True

        self.store_path = None
        if 'store_path' in kw:
            self.store_path = kw['store_path']

        if 'get_all_nfp' in kw:
            if kw['get_all_nfp'] == True and self.load_history == False:
                self.getAllNFP()

        if 'fast' in kw:  # 为BLF进行多进程优化
            if kw['fast'] == True:
                self.res = [[0] * len(self.polys)
                            for i in range(len(self.polys))]
                #pool=Pool()
                for i in range(1, len(self.polys)):
                    for j in range(0, i):
                        # 计算nfp(j,i)
                        #self.res[j][i]=pool.apply_async(getNFP,args=(self.polys[j],self.polys[i]))
                        self.nfp_list[j][i] = GeoFunc.getSlide(
                            getNFP(self.polys[j],
                                   self.polys[i]), -self.centroid_list[j][0],
                            -self.centroid_list[j][1])
Beispiel #7
0
 def getLength(self):
     _max = 0
     for i in range(0, len(self.polygons)):
         if self.vertical == True:
             extreme_index = GeoFunc.checkTop(self.polygons[i])
             extreme = self.polygons[i][extreme_index][1]
         else:
             extreme_index = GeoFunc.checkRight(self.polygons[i])
             extreme = self.polygons[i][extreme_index][0]
         if extreme > _max:
             _max = extreme
     self.contain_length = _max
     # PltFunc.addLine([[0,self.contain_length],[self.width,self.contain_length]],color="blue")
     return _max
Beispiel #8
0
    def getInnerFitRectangle(poly, x, y):
        left_index, bottom_index, right_index, top_index = GeoFunc.checkBound(
            poly)  # 获得边界
        new_poly = GeoFunc.getSlide(poly, -poly[left_index][0],
                                    -poly[bottom_index][1])  # 获得平移后的结果

        refer_pt = [new_poly[top_index][0], new_poly[top_index][1]]
        ifr_width = x - new_poly[right_index][0]
        ifr_height = y - new_poly[top_index][1]

        IFR = [
            refer_pt, [refer_pt[0] + ifr_width, refer_pt[1]],
            [refer_pt[0] + ifr_width, refer_pt[1] + ifr_height],
            [refer_pt[0], refer_pt[1] + ifr_height]
        ]
        return IFR
Beispiel #9
0
 def getDrease(self, criteria):
     poly_list = []
     for poly in self.polys:
         if criteria == 'length':
             left, bottom, right, top = GeoFunc.checkBoundValue(poly)
             poly_list.append([poly, right - left])
         elif criteria == 'height':
             left, bottom, right, top = GeoFunc.checkBoundValue(poly)
             poly_list.append([poly, top - bottom])
         else:
             poly_list.append([poly, Polygon(poly).area])
     poly_list = sorted(poly_list, key=lambda item: item[1],
                        reverse=True)  # 排序,包含index
     dec_polys = []
     for item in poly_list:
         dec_polys.append(item)
     return dec_polys
 def getNFP(self, j, i):
     # j是固定位置,i是移动位置
     row = j * 192 + i * 16 + self.poly_status[j][2] * 4 + self.poly_status[
         i][2]
     bottom_pt = LPAssistant.getBottomPoint(self.polys[j])
     delta_x, delta_y = bottom_pt[0], bottom_pt[1]
     nfp = GeoFunc.getSlide(json.loads(self.fu_pre["nfp"][row]), delta_x,
                            delta_y)
     return nfp
Beispiel #11
0
    def getPredictionAbsolute(self):
        model = load_model("/Users/sean/Documents/Projects/Packing-Algorithm/model/absolute_lstm_num_8_layer_128_56_2_epochs_200.h5")
        
        file= pd.read_csv("/Users/sean/Documents/Projects/Data/8_lstm_test.csv") # 读取输入
        
        index=random.randint(3700,4700)
        index=3000

        polys=json.loads(file["polys"][index]) # 形状
        X = np.array([json.loads(file["x_256"][index])]) # 输入
        predicted_Y = model.predict(X, verbose=0)[0]*4000

        for i,poly in enumerate(polys):
            centroid_origin=GeoFunc.getPt(Polygon(poly).centroid)
            PltFunc.addPolygon(poly)

            new_poly=GeoFunc.getSlide(poly,predicted_Y[i][0]-centroid_origin[0],predicted_Y[i][1]-centroid_origin[1])
            PltFunc.addPolygonColor(new_poly)

        PltFunc.showPlt()
Beispiel #12
0
 def getAllNFP(self):
     nfp_multi = False
     if nfp_multi == True:
         tasks = [(main, adjoin) for main in self.polys
                  for adjoin in self.polys]
         res = pool.starmap(NFP, tasks)
         for k, item in enumerate(res):
             i = k // len(self.polys)
             j = k % len(self.polys)
             self.nfp_list[i][j] = GeoFunc.getSlide(
                 item.nfp, -self.centroid_list[i][0],
                 -self.centroid_list[i][1])
     else:
         for i, poly1 in enumerate(self.polys):
             for j, poly2 in enumerate(self.polys):
                 nfp = NFP(poly1, poly2).nfp
                 #NFP(poly1,poly2).showResult()
                 self.nfp_list[i][j] = GeoFunc.getSlide(
                     nfp, -self.centroid_list[i][0],
                     -self.centroid_list[i][1])
     if self.store_nfp == True:
         self.storeNFP()
Beispiel #13
0
 def getDirectNFP(self, poly1, poly2, **kw):
     if 'index' in kw:
         i = kw['index'][0]
         j = kw['index'][1]
         centroid = GeoFunc.getPt(Polygon(self.polys[i]).centroid)
     else:
         # 首先获得poly1和poly2的ID
         i = self.getPolyIndex(poly1)
         j = self.getPolyIndex(poly2)
         centroid = GeoFunc.getPt(Polygon(poly1).centroid)
     # 判断是否计算过并计算nfp
     if self.nfp_list[i][j] == 0:
         nfp = NFP(poly1, poly2).nfp
         #self.nfp_list[i][j]=GeoFunc.getSlide(nfp,-centroid[0],-centroid[1])
         if self.store_nfp == True:
             with open(
                     "/Users/sean/Documents/Projects/Packing-Algorithm/record/nfp.csv",
                     "a+") as csvfile:
                 writer = csv.writer(csvfile)
                 writer.writerows([[poly1, poly2, nfp]])
         return nfp
     else:
         return GeoFunc.getSlide(self.nfp_list[i][j], centroid[0],
                                 centroid[1])
Beispiel #14
0
 def updateBound(self):
     '''
     更新包络长方形
     '''
     border_left, border_bottom, border_right, border_top = GeoFunc.checkBoundValue(
         self.cur_polys[-1])
     if border_left < self.border_left:
         self.border_left = border_left
     if border_bottom < self.border_bottom:
         self.border_bottom = border_bottom
     if border_right > self.border_right:
         self.border_right = border_right
     if border_top > self.border_top:
         self.border_top = border_top
     self.border_height = self.border_top - self.border_bottom
     self.border_width = self.border_right - self.border_left
    def getPrerequisite(self, i, orientation, **kw):
        # 获得全部NFP以及拆分情况
        self.all_nfps,self.all_points_target,self.all_edges_target = [],[],[]
        offline = kw['offline']
        for j, item in enumerate(self.polys):
            # 两个相等的情况,跳过否则会计算错误
            if j == i:
                self.all_nfps.append([])
                self.all_points_target.append([])
                self.all_edges_target.append([])
                continue
            # 预处理的情况
            points_target, edges_target, nfp = [], [], []
            if offline == True:
                row = j * 192 + i * 16 + self.poly_status[j][
                    2] * 4 + orientation
                bottom_pt = LPAssistant.getBottomPoint(self.polys[j])
                delta_x, delta_y = bottom_pt[0], bottom_pt[1]
                nfp = GeoFunc.getSlide(json.loads(self.fu_pre["nfp"][row]),
                                       delta_x, delta_y)
            else:
                nfp = LPAssistant.deleteOnline(
                    self.NFPAssistant.getDirectNFP(
                        self.polys[j], self.polys[i]))  # NFP可能有同一直线上的点
            # 计算对应目标函数
            for pt_index in range(len(nfp)):
                edges_target.append(
                    LPAssistant.getTargetFunction(
                        [nfp[pt_index - 1], nfp[pt_index]]))
                points_target.append([nfp[pt_index][0], nfp[pt_index][1]])
            # 添加上去
            self.all_nfps.append(nfp)
            self.all_edges_target.append(edges_target)
            self.all_points_target.append(points_target)

        # 获取IFR
        self.target_poly = self.all_polygons[i][orientation]
        self.ifr = PackingUtil.getInnerFitRectangle(self.target_poly,
                                                    self.cur_length,
                                                    self.width)
        self.IFR = Polygon(self.ifr)
        self.final_IFR = Polygon(self.ifr)
    def minimizeOverlap(self):
        start_time = time.time()

        # 记录引导检索的相关内容
        self.miu = [[1] * len(self.polys) for _ in range(len(self.polys))]
        self.initialOverlap()

        # 记录重叠变化情况
        self.overlap_reocrd = []

        # 检索次数限制/超出倍数退出
        it, N = 0, 50
        minimal_overlap = self.getTotalOverlap()
        cur_overlap = minimal_overlap
        print("初始重叠:", cur_overlap)

        # 限定计算次数
        print("开始一次检索")
        while it < N:
            print("it:", it)
            # 获得随机序列并逐一检索
            permutation = np.arange(len(self.polys))
            np.random.shuffle(permutation)
            for i in range(len(self.polys)):
                # 选择特定形状
                choose_index = permutation[i]

                # 通过重叠判断是否需要计算
                with_overlap = False
                for item in self.pair_overlap[choose_index]:
                    if item > 0:
                        with_overlap = True
                        break
                if with_overlap == False:
                    continue

                # 获得当前的最小的深度(调整后),如果没有重叠,直接下一个
                self.getPrerequisite(choose_index,
                                     self.poly_status[choose_index][2],
                                     offline=True)
                cur_min_depth = self.getPolyDepeth(choose_index)

                # 记录最优情况,默认是当前情况
                original_position = self.poly_status[choose_index][1]
                best_position, best_orientation, best_depth = self.poly_status[
                    choose_index][1], self.poly_status[choose_index][
                        2], cur_min_depth
                # print("当前最低高度:",best_depth)

                print("测试第", i, "个形状")
                # 遍历四个角度的最优值
                for orientation in [0, 1, 2, 3]:
                    # print("测试角度:",90*orientation,"度")
                    self.getPrerequisite(choose_index,
                                         orientation,
                                         offline=True)
                    self.getProblemLP()
                    new_position, new_depth = self.searchBestPosition(
                        choose_index)  # 获得最优位置
                    if new_depth < best_depth:
                        best_position, best_orientation, best_depth = copy.deepcopy(
                            new_position), orientation, new_depth

                # 如果有变化状态则需要更新overlap以及移动形状
                if best_position != original_position:
                    print("本次检索最低深度:", best_depth)
                    # 更新记录的位置
                    self.poly_status[choose_index][1] = copy.deepcopy(
                        best_position)
                    self.poly_status[choose_index][2] = best_orientation
                    # 获取形状顶部位置并平移过去
                    new_poly = copy.deepcopy(
                        self.all_polygons[choose_index][best_orientation])
                    top_point = LPAssistant.getTopPoint(new_poly)
                    GeoFunc.slidePoly(new_poly,
                                      best_position[0] - top_point[0],
                                      best_position[1] - top_point[1])
                    # 更新形状与重叠情况
                    self.polys[choose_index] = new_poly
                    self.updateOverlap(choose_index)
                    # self.showPolys()

            # 计算新方案的重叠情况
            cur_overlap = self.getTotalOverlap()
            self.overlap_reocrd.append(cur_overlap)
            if cur_overlap < bias:
                print("没有重叠,本次检索结束")
                break
            elif cur_overlap < minimal_overlap:
                minimal_overlap = cur_overlap
                it = 0
            print("\n当前重叠:", cur_overlap, "\n")
            it = it + 1
            self.updateMiu()

        # 超出检索次数
        if it == N:
            print("超出更新次数/超出倍数")
            # self.showPolys()

        end_time = time.time()
        print("本轮耗时:", end_time - start_time)
        print("最终结果:", self.polys)
        print("当前状态:", self.poly_status)

        with open(
                "/Users/sean/Documents/Projects/Packing-Algorithm/record/fu_result.csv",
                "a+") as csvfile:
            writer = csv.writer(csvfile)
            writer.writerows([[
                time.asctime(time.localtime(time.time())),
                end_time - start_time, self.cur_length,
                self.total_area / (self.cur_length * self.width), cur_overlap,
                self.poly_status, self.polys
            ]])

        self.showPolys()
        self.plotRecord("Overlap Record:", self.overlap_reocrd)
Beispiel #17
0
 def slideToBottomLeft(self):
     '''移到最左下角位置'''
     for poly in self.cur_polys:
         GeoFunc.slidePoly(poly, -self.border_left, -self.border_bottom)
Beispiel #18
0
 def placeFirstPoly(self):
     poly = self.polygons[0]
     left_index, bottom_index, right_index, top_index = GeoFunc.checkBound(
         poly)  # 获得边界
     GeoFunc.slidePoly(poly, -poly[left_index][0],
                       -poly[bottom_index][1])  # 平移到左下角