def can_hold_box(box, space, direction): """ 判断space的hold_surface是否满足supporting constraints cf. Huawei: constraints.py/can_hold_box() :param box: AlgorithmBox class :param space: Space class :param direction: 0 or 1 """ # 如果支撑平面为空则该空间为从地面起始的空间 support_area = 0 if not space.hold_surface: return True lx, ly, _ = utils.choose_box_direction_len(box.length, box.width, box.height, direction) min_coord = [space.min_coord[0], space.min_coord[1]] # box的底面最小坐标 max_coord = [min_coord[0] + lx, min_coord[1] + ly] # box的底面最大坐标 for area in space.hold_surface: # space.hold_surface是list,包含Area类型的元素 if area.max_coord[0] != area.min_coord[0] + area.lx or area.max_coord[1] != area.min_coord[1] + area.ly: area.max_coord[0] = area.min_coord[0] + area.lx area.max_coord[1] = area.min_coord[1] + area.ly # 底面一样 if area.min_coord == min_coord and area.max_coord == max_coord: return True if not utils.is_overlap(min_coord, max_coord, area.min_coord, area.max_coord): # 若box与空间的支撑平面没有重合区域,那么检查下一个area continue # 计算重合区域面积 support_area += overlap_area( min_coord, max_coord, area.min_coord, area.max_coord) box_bottom_area = lx * ly if support_area / box_bottom_area >= 1: return True else: return False
def __init__(self, box, coord, direction=None): self.box = box self.min_coord = coord if type(box) == AlgorithmBox: size = utils.choose_box_direction_len(box.length, box.width, box.height, direction) else: size = [box.lx, box.ly, box.lz] self.max_coord = [ coord[0] + size[0], coord[1] + size[1], coord[2] + size[2] ]
def gen_box_size_map(self): box_size_map = {} for ind, item in enumerate(self.box_list): sizes = set() for direction in item.all_directions: sizes.add( utils.choose_box_direction_len(item.length, item.width, item.height, direction)) for size in sizes: box_size_map.setdefault(size, []).append(ind) for value in box_size_map.values(): value.sort(key=lambda x: self.box_list[x].weight, reverse=True) return box_size_map
def can_in_space(box, bin_obj, space, box_direction): """ 判断box是否能装到space中 :param box: AlgorithmBox类 :param bin_obj: PackedBin类 :param space: ExtremePointSpace类 :param box_direction: 0 or 1 """ # 根据方向确定box在x y z轴上的长度 lx, ly, lz = utils.choose_box_direction_len( box.length, box.width, box.height, box_direction) if lx + space.min_coord[0] > bin_obj.length - config.distance_to_door: if lz + space.min_coord[2] > bin_obj.door_height: return False box_size = [lx, ly, lz] space_size = [space.lx, space.ly, space.lz] for i in range(len(box_size)): if box_size[i] > space_size[i]: return False return True
def can_hold_box(box, space, direction): """ 判断空间是否可以支撑当前盒子 :param box: 被放入的盒子 :param space: 用来放盒子的空间 :param direction: 箱子的摆放方向 """ # 如果支撑平面为空或者None则该空间为从地面起始的空间 if not space.hold_surface: return True lx, ly, _ = utils.choose_box_direction_len(box.length, box.width, box.height, direction) min_coord = [space.min_coord[0], space.min_coord[1]] max_coord = [min_coord[0] + lx, min_coord[1] + ly] for area in space.hold_surface: # 底面一样 if area.min_coord == min_coord and area.max_coord == max_coord \ and area.max_layer >= 1: return True if utils.is_overlap(min_coord, max_coord, area.min_coord, area.max_coord) and area.max_weight < box.weight: return False return False
def update_box_size_and_avail_map(box_size_map, box_list, avail, block): """ 更新box_size_map和avail两个字典 :param box_size_map: 箱子尺寸(某一个方向)与该箱子在box_list中下标的映射 :param box_list: 箱子集合 :param avail: 箱子尺寸(某一个方向)与对应箱子数量的映射 :param block: 此次装载的块 """ block_size = block.item_size sizes = [] for i in range(6): temp_size = utils.choose_box_direction_len(*block_size, i) sizes.append(temp_size) for size in sizes: if size in box_size_map.keys(): temp_ind = [] total_num = 0 for ind in box_size_map[size]: if box_list[ind].box_num > 0: temp_ind.append(ind) total_num += box_list[ind].box_num box_size_map[size] = temp_ind avail[size] = total_num
def assign_box_2_bin(box, space, packed_bin, box_direction): """ 将箱子放置到容器中 :param box: the box that has been packed :param space: the space packs the box :param packed_bin: the bin packs the box :param box_direction: 箱子的摆放方向 """ packed_bin.order += 1 lx, ly, lz = utils.choose_box_direction_len(box.length, box.width, box.height, box_direction) packed_box = PackedBox(*space.min_coord, lx, ly, lz, box, packed_bin.order, box_direction, 0) copy_box = AlgorithmBox.copy_algorithm_box(box, 1) if packed_bin.packed_box_list: packed_bin.packed_box_list.append(packed_box) packed_bin.box_list.append(copy_box) else: packed_bin.packed_box_list = [packed_box] packed_bin.box_list = [copy_box] packed_bin.load_volume += lx * ly * lz packed_bin.load_weight += box.weight packed_bin.load_amount += box.amount