Beispiel #1
0
    def getLengthRanked(self):
        length_results = []
        self.fitness_sum = 0

        if self.ga_multi == True:
            tasks = [[pop] for pop in self.pop]
            pool = multiprocessing.Pool()
            results = pool.starmap(self.getLength, tasks)
            for i in range(0, len(self.pop)):
                # print("length:",results[i])
                self.fitness_sum += 1000 / results[i]
                length_results.append([
                    i, results[i], 1000 / results[i],
                    PolyListProcessor.getPolyListIndex(self.pop[i])
                ])
        else:
            for i in range(0, len(self.pop)):
                length = self.getLength(self.pop[i])
                self.fitness_sum += 1000 / length
                length_results.append([
                    i, length, 1000 / length,
                    PolyListProcessor.getPolyListIndex(self.pop[i])
                ])

        self.fitness_ranked = sorted(length_results,
                                     key=operator.itemgetter(1))  # 排序,包含index
Beispiel #2
0
 def newPolyList(self):
     choose_id = int(random.random() * len(self.new_poly_list))
     '''进行交换和旋转的操作,暂时不允许旋转'''
     if random.random()<=1:
         self.new_poly_list=PolyListProcessor.randomSwap(self.cur_poly_list,choose_id)
     else:
         self.new_poly_list=PolyListProcessor.randomRotate(self.cur_poly_list,self.min_angle,choose_id)
Beispiel #3
0
 def mutate(self,individual):
     for swapped in range(len(individual)):
         if(random.random() < self.mutate_rate):
             # 首先是交换位置
             if random.random()<=0.5:
                 individual=PolyListProcessor.randomSwap(individual,swapped)
             else:
                 individual=PolyListProcessor.randomRotate(individual,self.minimal_rotation,swapped)
     return individual
Beispiel #4
0
    def breed(self,parent1, parent2):
        geneA,geneB = random.randint(0,len(parent1)-1), random.randint(0,len(parent1)-1)
        start_gene,end_gene = min(geneA, geneB),max(geneA, geneB)
        
        parent1_index = PolyListProcessor.getPolyListIndex(parent1)
        parent2_index = PolyListProcessor.getPolyListIndex(parent2)

        child1_index = parent1_index[start_gene:end_gene] # 截取一部分
        child2_index = [item for item in parent2_index if item not in child1_index] # 截取剩余部分

        return PolyListProcessor.getPolysByIndex(child1_index,self.poly_list) + PolyListProcessor.getPolysByIndex(child2_index,self.poly_list)
Beispiel #5
0
    def geneticAlgorithm(self):
        self.pop = [] # 种群记录
        self.length_record = [] # 记录高度
        self.lowest_length_record = [] # 记录全局高度
        self.global_best_sequence = [] # 全局最优序列
        self.global_lowest_length = 9999999999 # 全局最低高度
        
        # 初步的随机数组
        for i in range(0, self.pop_size):
            _list=copy.deepcopy(self.poly_list)
            random.shuffle(_list)
            self.pop.append(_list)

        # 持续获得下一代
        for i in range(0, self.generations):
            print("############################ Compute the ",i+1,"th generation #######################################")
            self.getLengthRanked() # 高度排列
            self.getNextGeneration() # 获得下一代

            # 高度记录与最低高度处理
            self.length_record.append(self.fitness_ranked[0][1])
            if self.fitness_ranked[0][1]<self.global_lowest_length:
                self.global_lowest_length=self.fitness_ranked[0][1]
                self.global_best_sequence=self.pop[self.fitness_ranked[0][0]]
            self.lowest_length_record.append(self.global_lowest_length)
            # print(self.global_lowest_length)

        # print("Final length: " + str(self.global_lowest_length))

        blf=BottomLeftFill(self.width,PolyListProcessor.getPolysVertices(self.global_best_sequence),NFPAssistant=self.NFPAssistant)
        blf.showAll()
Beispiel #6
0
    def __init__(self,width,poly_list,nfp_asst=None,generations=10,pop_size=20):
        self.width=width
        self.minimal_rotation=360 # 最小的旋转角度
        self.poly_list=poly_list

        self.ga_multi=False # 开了多进程反而更慢
        if self.ga_multi:
            multiprocessing.set_start_method('spawn',True) 

        self.elite_size=10 # 每一代选择个数
        self.mutate_rate=0.1 # 变异概率
        self.generations=generations # 代数
        self.pop_size=pop_size # 每一代的个数

        self.history_index_list=[]
        self.history_length_list=[]
        
        if nfp_asst:
            self.NFPAssistant=nfp_asst
        else:
            self.NFPAssistant=NFPAssistant(PolyListProcessor.getPolysVertices(poly_list),get_all_nfp=True)

        self.geneticAlgorithm()

        self.plotRecord()
Beispiel #7
0
 def getLength(self, poly_list):
     length = PolyListProcessor.packingLength(
         poly_list,
         self.history_index_list,
         self.history_length_list,
         self.width,
         NFPAssistant=self.NFPAssistant)
     return length
Beispiel #8
0
def getGA(width, poly, nfp_asst, generations=10):
    polys_GA = PolyListProcessor.getPolyObjectList(poly, [0])
    ga = GA(width,
            polys_GA,
            nfp_asst=nfp_asst,
            generations=generations,
            pop_size=10)
    origin = ga.length_record[0]
    best = ga.global_lowest_length
    return origin - best
Beispiel #9
0
def packingLength(poly_list,history_index_list,history_length_list,width,**kw):
    polys=PolyListProcessor.getPolysVertices(poly_list)
    index_list=PolyListProcessor.getPolyListIndex(poly_list)
    length=0
    check_index=PolyListProcessor.getIndex(index_list,history_index_list)
    if check_index>=0:
        length=history_length_list[check_index]
    else:
        try:
            if 'NFPAssistant' in kw:
                blf=BottomLeftFill(width,polys,NFPAssistant=kw['NFPAssistant'])
                # blf.showAll()
                length=blf.contain_length
            else:
                length=BottomLeftFill(width,polys).contain_length
        except:
            print('出现Self-intersection')
            length=99999
        history_index_list.append(index_list)
        history_length_list.append(length)
    return length
Beispiel #10
0
    def __init__(self,poly_list):
        self.min_angle=360 # 允许旋转的最小角度
        self.width=1500 # 排列的宽度

        self.temp_now=200  # 起始温度 2000
        self.temp_end=1e-5 # 结束温度 1e-20
        self.dec_rate=0.7 # 降温速率 0.995
        self.loop_times=5 # 内循环次数
        
        self.cur_poly_list=poly_list # 当前的序列
        self.new_poly_list=poly_list # 生成新的序列

        self.history_index_list=[] # 运行过的index序列
        self.history_length_list=[] # 运行结果
        
        self.NFPAssistant=NFPAssistant(PolyListProcessor.getPolysVertices(poly_list),get_all_nfp=True)

        self.run()
    def __init__(self,poly_list):
        # 初始设置
        self.width=1500

        # 初始化数据,NFP辅助函数
        polys=PolyListProcessor.getPolysVertices(poly_list)
        self.NFPAssistant=NFPAssistant(polys,get_all_nfp=False)

        # 获得最优解
        blf=BottomLeftFill(self.width,polys,NFPAssistant=self.NFPAssistant)
        self.best_height=blf.contain_height
        self.cur_height=blf.contain_height

        # 当前的poly_list均为已经排样的情况
        self.best_poly_list=copy.deepcopy(poly_list)
        self.cur_poly_list=copy.deepcopy(poly_list)

        self.run()
Beispiel #12
0
def BLFwithSequence(test_path, width, seq_path=None, GA_algo=False):
    if seq_path != None:
        f = open(seq_path, 'r')
        seqs = f.readlines()
    data = np.load(test_path, allow_pickle=True)
    test_name = test_path.split('_xy')[0]
    height = []
    if GA_algo: p = Pool()
    multi_res = []
    for i, line in enumerate(tqdm(data)):
        polys_final = []
        if seq_path != None:  # 指定序列
            seq = seqs[i].split(' ')
        else:  # 随机序列
            seq = np.array(range(len(line)))
            np.random.shuffle(seq)
        for j in range(len(line)):
            if seq_path != None:
                index = int(seq[j])
            else:
                index = seq[j]
            polys_final.append(line[index])
        nfp_asst = NFPAssistant(polys_final,
                                load_history=True,
                                history_path='record/{}/{}.csv'.format(
                                    test_name, i))
        #nfp_asst=None
        if GA_algo == True:  # 遗传算法
            polys_GA = PolyListProcessor.getPolyObjectList(polys_final, [0])
            multi_res.append(
                p.apply_async(GA, args=(width, polys_GA, nfp_asst)))
        else:
            blf = BottomLeftFill(width, polys_final, NFPAssistant=nfp_asst)
            #blf.showAll()
            height.append(blf.getLength())
    if GA_algo:
        p.close()
        p.join()
        for res in multi_res:
            height.append(res.get().global_lowest_length)
    return height
Beispiel #13
0
    def run(self):
        initial_length = packingLength(self.cur_poly_list,
                                       self.history_index_list,
                                       self.history_length_list, self.width)

        global_lowest_length_list = []  # 记录每个温度下最最低高度,理论上会下降
        temp_lowest_length_list = []  # 每个温度下的平衡高度

        global_best_list = copy.deepcopy(self.cur_poly_list)  # 用于记录历史上最好蓄力
        global_lowest_length = initial_length  # 全局最低高度

        temp_best_list = copy.deepcopy(self.cur_poly_list)  # 局部温度下的最低
        temp_lowest_length = initial_length  # 局部温度下的最低

        unchange_times = 0

        # 开始循环寻找
        while self.temp_now > self.temp_end:
            print("当前温度:", self.temp_now)
            old_lowest_length = global_lowest_length  # 统计未更改次数

            cur_length = packingLength(self.cur_poly_list,
                                       self.history_index_list,
                                       self.history_length_list,
                                       self.width,
                                       NFPAssistant=self.NFPAssistant)

            # 在某个温度下进行一定次数的寻找
            for i in range(self.loop_times):
                self.newPolyList()

                new_length = packingLength(self.new_poly_list,
                                           self.history_index_list,
                                           self.history_length_list,
                                           self.width,
                                           NFPAssistant=self.NFPAssistant)
                delta_length = new_length - cur_length

                if delta_length < 0:  # 当前温度下如果高度更低则接受
                    temp_best_list = self.cur_poly_list = copy.deepcopy(
                        self.new_poly_list)
                    temp_lowest_length = new_length  # 修改为新的高度
                    cur_length = new_length

                    if new_length < global_lowest_length:  # 如果新的高度小于最低的高度则修改最低高度
                        global_lowest_length = new_length
                        global_best_list = copy.deepcopy(self.new_poly_list)

                elif np.random.random() < np.exp(
                        -delta_length / self.temp_now):  # 按照一定概率修改,并作为下一次检索基础
                    self.poly_list = copy.deepcopy(self.new_poly_list)
                    cur_length = new_length
                else:
                    pass  # 否则不进行修改

            print("当前温度最低长度:", temp_lowest_length)
            print("最低长度:", global_lowest_length)

            if old_lowest_length == global_lowest_length:
                unchange_times += 1
                if unchange_times > 15:
                    break
            else:
                unchange_times = 0

            self.cur_poly_list = copy.deepcopy(
                temp_best_list)  # 某温度下检索结束后取该温度下最优值
            self.temp_now *= self.dec_rate  #退火
            global_lowest_length_list.append(
                global_lowest_length)  # 全局的在每个温度下的最低高度,理论上一直在降低
            temp_lowest_length_list.append(temp_lowest_length)  # 每个温度下的最低高度

        # print('结束温度的局部最优的序列:',temp_best_list)
        print('结束温度的局部最优高度:', temp_lowest_length)
        # print('最好序列:',global_best_list)
        print('最好序列高度:', global_lowest_length)

        PolyListProcessor.showPolyList(self.width, global_best_list)

        self.showBestResult(temp_lowest_length_list, global_lowest_length_list)
Beispiel #14
0
        # print('结束温度的局部最优的序列:',temp_best_list)
        print('结束温度的局部最优高度:', temp_lowest_length)
        # print('最好序列:',global_best_list)
        print('最好序列高度:', global_lowest_length)

        PolyListProcessor.showPolyList(self.width, global_best_list)

        self.showBestResult(temp_lowest_length_list, global_lowest_length_list)

    def showBestResult(self, list1, list2):
        plt.figure(1)
        plt.subplot(311)
        plt.plot(list1)  #每个温度下平衡路径长度
        plt.subplot(312)
        plt.plot(list2)  #每个温度下最好路径长度
        plt.grid()
        plt.show()


if __name__ == '__main__':
    starttime = datetime.datetime.now()

    polys = getData(6)
    all_rotation = [0]  # 禁止旋转
    poly_list = PolyListProcessor.getPolyObjectList(polys, all_rotation)

    SA(poly_list)

    endtime = datetime.datetime.now()
    print(endtime - starttime)
    def getProblemLP(self):
        # 获得目标区域
        self.ifr_points = []
        self.target_areas = [[], [], [], [], [], [], [], [], []]
        self.last_index = [[], [], [], [], [], [], [], [], []]

        # 获得两个NFP在IFR中重叠的情况
        self.nfp_overlap_pair = [[i] for i in range(len(self.all_nfps))]
        for i in range(len(self.all_nfps) - 1):
            for j in range(i + 1, len(self.all_nfps)):
                overlap, overlap_poly = self.polysOverlapIFR(
                    self.all_nfps[i], self.all_nfps[j])
                if overlap == True:
                    self.nfp_overlap_pair[i].append(j)
                    self.nfp_overlap_pair[j].append(i)
                    self.target_areas[1].append([overlap_poly, i, j])
                    self.last_index[1].append([i, j])  # 分别添加i,j

        # 切去一维重叠情况
        for i, nfp in enumerate(self.all_nfps):
            # 删除与IFR重叠区域
            new_region = Polygon(nfp).intersection(self.IFR)
            self.final_IFR = self.final_IFR.difference(Polygon(nfp))
            # 删除与其他NFP拆分的重叠
            for j in self.nfp_overlap_pair[i][1:]:
                P = Polygon(self.all_nfps[j])
                new_region = new_region.difference(P)
            # 在目标区域增加情况,首先排除点和直线,以及面积过小
            if new_region.is_empty != True and new_region.geom_type != "Point" and new_region.geom_type != "LineString" and new_region.area > bias:
                self.target_areas[0].append(
                    [LPAssistant.processRegion(new_region), i])  # 删除直线/顶点情况
            else:
                self.target_areas[0].append([])
            self.last_index[0].append([])

        # 增加IFR的计算
        if self.final_IFR.is_empty != True and self.final_IFR.geom_type != "Point" and self.final_IFR.geom_type != "LineString" and self.final_IFR.area > bias:
            self.ifr_points = LPAssistant.processRegion(self.final_IFR)

        # 获得后续的重叠
        for i in range(2, len(self.target_areas)):
            # 遍历上一阶段计算的结果
            for j, target_area in enumerate(self.target_areas[i - 1]):
                area, P1 = target_area[0], Polygon(target_area[0])  # 获得当前目标可行解

                all_possible_target = []
                # 如果大于三个,只需要计算最后加入的,否则是第一个
                if i >= 3:
                    all_possible_target = self.nfp_overlap_pair[
                        target_area[-1]]
                else:
                    all_possible_target = self.nfp_overlap_pair[
                        target_area[1]] + self.nfp_overlap_pair[target_area[2]]

                all_possible_target = PolyListProcessor.deleteRedundancy(
                    all_possible_target)

                # 删除所有更小的,保证正序,获得判断这些形状是否会重叠,若有则添加并求解目标区域
                all_possible_target_larger = LPAssistant.deleteTarget(
                    all_possible_target, [
                        i for i in range(
                            0,
                            max(item for item in target_area[1:]) + 1)
                    ])
                for possible_target in all_possible_target_larger:
                    P2 = Polygon(self.all_nfps[possible_target])
                    # 只有相交才进一步计算
                    if P1.intersects(P2):
                        inter = P1.intersection(P2)
                        if inter.area > bias:
                            self.last_index[i].append([j])
                            self.target_areas[i].append(
                                [LPAssistant.processRegion(inter)] +
                                target_area[1:] + [possible_target])

                # 删除已经有的,遍历计算重叠
                all_possible_target_difference = LPAssistant.deleteTarget(
                    all_possible_target, [item for item in target_area[1:]])
                new_region = self.cutFrontRegion(
                    all_possible_target_difference, P1)

                if new_region.is_empty != True and new_region.geom_type != "Point" and new_region.geom_type != "LineString" and new_region.area > bias:
                    target_area[0] = LPAssistant.processRegion(new_region)
                else:
                    self.target_areas[i - 1][j] = []

            # 如果该轮没有计算出重叠则停止
            if self.target_areas[i] == []:
                self.max_overlap = i
                # print("至多",i,"个形状重叠,计算完成")
                break
Beispiel #16
0
        self.showBestResult(temp_lowest_length_list, global_lowest_length_list)

    def showBestResult(self, list1, list2):
        plt.figure(1)
        plt.subplot(311)
        plt.plot(list1)  #每个温度下平衡路径长度
        plt.subplot(312)
        plt.plot(list2)  #每个温度下最好路径长度
        plt.grid()
        plt.show()


if __name__ == '__main__':
    starttime = datetime.datetime.now()
    # polys=getConvex(num=5)
    polys = getData()
    print(len(polys))
    poly_list = PolyListProcessor.getPolyObjectList(polys + polys + polys, [0])
    # TOPOS(polys,1500)
    nfp_assistant = NFPAssistant(polys,
                                 store_nfp=False,
                                 get_all_nfp=True,
                                 load_history=True)
    GA(760, poly_list, nfp_asst=nfp_assistant)
    # SA(poly_list)

    # GetBestSeq(1000,getConvex(num=5),"decrease")
    endtime = datetime.datetime.now()
    print(endtime - starttime)
    bfl.showAll()