Python py3dbp 分发不适合空箱的物品

问题描述

在 python 上,我将项目放在类似 py3dbp 模型的框中。我有 14 个垃圾箱和 4 个项目。我在程序启动时输入项目数量。有些物品适合,有些则不适合。因此,垃圾箱保持为空。我在任何地方都找不到解决方案。你能帮助我吗?我必须分发不适合空箱的物品。

from binpack import Packer,Bin,Item
import numpy as np
packer = Packer()

def descBin(name,width,height,depth,max_weight):
    packer.add_bin(Bin(name,max_weight))

def addItem(name,weight):
    packer.add_item(Item(name,weight))

name = 'E1C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name,max_weight))

name = 'E2C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name,max_weight))

name = 'E3C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name,max_weight))


name = 'E4C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name,max_weight))

name = 'E5C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name,max_weight))

name = 'E6C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name,max_weight))

name = 'E7C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name,max_weight))


name = 'E8C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name,max_weight))

name = 'E9C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name,max_weight))

name = 'E10C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name,max_weight))

name = 'E11C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name,max_weight))


name = 'E12C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name,max_weight))

name = 'EC13C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name,max_weight))

name = 'EC14C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name,max_weight))

#ITEMS
name = 'E1C'
width = 30
height = 20
depth = 30
weight = 1
amount1 = int(input("(E1C 30 x 20 x 30) Amount: "))
for i in range(amount1):
    packer.add_item(Item(name,weight))

name = 'E2C'
width = 30
height = 40
depth = 30
weight = 1
amount2 = int(input("(E2C 30 x 40 x 30) Amount: "))
for i in range(amount2):
    packer.add_item(Item(name,weight))

name = 'E3C'
width = 20
height = 40
depth = 20
weight = 1
amount3 = int(input("(E3C 20 x 40 x 20) Amount: "))
for i in range(amount3):
    packer.add_item(Item(name,weight))

name = 'E4C'
width = 40
height = 40
depth = 40
weight = 1
amount4 = int(input("(E4C 40 x 40 x 40) Amount: "))
for i in range(amount4):
    packer.add_item(Item(name,weight))

nameBinD = {0:"E1C",1:"E2C",2:"E3C",3:"E4C",4:"E5C",5:"E6C",6:"E7C",7:"E8C",8:"E9C",9:"E10C",10:"E11C",11:"E12C"}
widthBinD = {0:200,1:200,2:200,3:200,4:200,5:200,6:200,7:200,8:200,9:200,10:200,11:200}
heightBinD = {0:200,11:200}
depthBinD = {0:200,11:200}
max_weightBinD = {0:10,1:10,2:10,3:10,4:10,5:10,6:10,7:10,8:10,9:10,10:10,11:10}

nameItemD = {0:"E1C",3:"E4C"}
widthItemD = {0:30,1:30,2:20,3:40}
heightItemD = {0:30,1:40,2:40,3:40}
depthItemD = {0:30,3:40}
weightitemD = {0:1,1:1,2:1,3:1}
amountItemD = {0:amount1,1:amount2,2:amount3,3:amount4}



def back():
    print()
    back = input('Anasayfaya Dönmek İster Misin [Y/N]: ')
    if back[0].upper() == 'Y':
        print()
        menu()
    elif back[0].upper() == 'N':
        print()
        exit()
    else:
        print('\033[92m?')
        exit(0)



def banner():
    print("""██████╗ ██╗   ██╗██████╗ ██████╗ ██████╗ ██████╗ 
██╔══██╗╚██╗ ██╔╝╚════██╗██╔══██╗██╔══██╗██╔══██╗
██████╔╝ ╚████╔╝  █████╔╝██║  ██║██████╔╝██████╔╝
██╔═══╝   ╚██╔╝   ╚═══██╗██║  ██║██╔══██╗██╔═══╝ 
██║        ██║   ██████╔╝██████╔╝██████╔╝██║     
╚═╝        ╚═╝   ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝     
                                                 
                                     
                                           """)

banner()



def menu():
    try:
        print("\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n ")
        banner()
        print()
        print("""E
    1. Add Bin             
    2. Add Items      
    3. Calculate
    """)

        choice = input(' (1-3): ')
        if choice == '1':
            name = input('[+] Name : ')
            width = input('[+] Width : ')
            height = input('[+] Height : ')
            depth = input('[+] Depth : ')
            max_weight = input('[+] Max Weight : ')
            descBin(name,max_weight)
            back()

        elif choice == "2":
            name = input('[+] Name : ')
            width = input('[+] Width : ')
            height = input('[+] Height : ')
            depth = input('[+] Depth : ')
            weight = input('[+] Weight : ')
            amount = int(input("[+] Amount : "))
            for i in range(amount):
                packer.add_item(Item(name,weight))
            back()
        
        elif choice == '3':
            packer.pack()
            for b in packer.bins:
                print("| |",b.string())

            print("FITTED ITEMS:")
            for item in b.items:
                print("====> ",item.string())
                
            print("YOU CAN'T LOAD THESE ITEMS ON THIS PALLET:")
            for item in b.unfitted_items:
                print("====> ",item.string())
            back()



    except():
        print("x")


        
menu()```

还有我的模型文件

from decimal import Decimal

DEFAULT_NUMBER_OF_DECIMALS = 3
START_POSITION = [0,0]

def rect_intersect(item1,item2,x,y):
    d1 = item1.get_dimension()
    d2 = item2.get_dimension()

    cx1 = item1.position[x] + d1[x]/2
    cy1 = item1.position[y] + d1[y]/2
    cx2 = item2.position[x] + d2[x]/2
    cy2 = item2.position[y] + d2[y]/2

    ix = max(cx1,cx2) - min(cx1,cx2)
    iy = max(cy1,cy2) - min(cy1,cy2)

    return ix < (d1[x]+d2[x])/2 and iy < (d1[y]+d2[y])/2


def intersect(item1,item2):
    return (
        rect_intersect(item1,Axis.WIDTH,Axis.HEIGHT) and
        rect_intersect(item1,Axis.HEIGHT,Axis.DEPTH) and
        rect_intersect(item1,Axis.DEPTH)
    )


def get_limit_number_of_decimals(number_of_decimals):
    return Decimal('1.{}'.format('0' * number_of_decimals))


def set_to_decimal(value,number_of_decimals):
    number_of_decimals = get_limit_number_of_decimals(number_of_decimals)

    return Decimal(value).quantize(number_of_decimals)

class RotationType:
    RT_WHD = 0
    RT_HWD = 1
    RT_HDW = 2
    RT_DHW = 3
    RT_DWH = 4
    RT_WDH = 5

    ALL = [RT_WHD,RT_HWD,RT_HDW,RT_DHW,RT_DWH,RT_WDH]


class Axis:
    WIDTH = 0
    HEIGHT = 1
    DEPTH = 2

    ALL = [WIDTH,HEIGHT,DEPTH]

class Item:
    def __init__(self,name,weight):
        self.name = name
        self.width = width
        self.height = height
        self.depth = depth
        self.weight = weight
        self.rotation_type = 0
        self.position = START_POSITION
        self.number_of_decimals = DEFAULT_NUMBER_OF_DECIMALS

    def format_numbers(self,number_of_decimals):
        self.width = set_to_decimal(self.width,number_of_decimals)
        self.height = set_to_decimal(self.height,number_of_decimals)
        self.depth = set_to_decimal(self.depth,number_of_decimals)
        self.weight = set_to_decimal(self.weight,number_of_decimals)
        self.number_of_decimals = number_of_decimals

    def string(self):
        return "%s(%sx%sx%s,weight: %s) pos(%s) rt(%s) vol(%s)" % (
            self.name,self.width,self.height,self.depth,self.weight,self.position,self.rotation_type,self.get_volume()
        )

    def get_volume(self):
        return set_to_decimal(
            self.width * self.height * self.depth,self.number_of_decimals
        )

    def get_dimension(self):
        if self.rotation_type == RotationType.RT_WHD:
            dimension = [self.width,self.depth]
        elif self.rotation_type == RotationType.RT_HWD:
            dimension = [self.height,self.depth]
        elif self.rotation_type == RotationType.RT_HDW:
            dimension = [self.height,self.width]
        elif self.rotation_type == RotationType.RT_DHW:
            dimension = [self.depth,self.width]
        elif self.rotation_type == RotationType.RT_DWH:
            dimension = [self.depth,self.height]
        elif self.rotation_type == RotationType.RT_WDH:
            dimension = [self.width,self.height]
        else:
            dimension = []

        return dimension


class Bin:
    def __init__(self,max_weight):
        self.name = name
        self.width = width
        self.height = height
        self.depth = depth
        self.max_weight = max_weight
        self.items = []
        self.unfitted_items = []
        self.number_of_decimals = DEFAULT_NUMBER_OF_DECIMALS

    def format_numbers(self,number_of_decimals)
        self.max_weight = set_to_decimal(self.max_weight,max_weight:%s) vol(%s)" % (
            self.name,self.max_weight,self.number_of_decimals
        )

    def get_total_weight(self):
        total_weight = 0

        for item in self.items:
            total_weight += item.weight

        return set_to_decimal(total_weight,self.number_of_decimals)

    def put_item(self,item,pivot):
        fit = False
        valid_item_position = item.position
        item.position = pivot

        for i in range(0,len(RotationType.ALL)):
            item.rotation_type = i
            dimension = item.get_dimension()
            if (
                self.width < pivot[0] + dimension[0] or
                self.height < pivot[1] + dimension[1] or
                self.depth < pivot[2] + dimension[2]
            ):
                continue

            fit = True

            for current_item_in_bin in self.items:
                if intersect(current_item_in_bin,item):
                    fit = False
                    break

            if fit:
                if self.get_total_weight() + item.weight > self.max_weight:
                    fit = False
                    return fit

                self.items.append(item)

            if not fit:
                item.position = valid_item_position

            return fit

        if not fit:
            item.position = valid_item_position

        return fit


class Packer:
    def __init__(self):
        self.bins = []
        self.items = []
        self.unfit_items = []
        self.total_items = 0

    def add_bin(self,bin):
        return self.bins.append(bin)

    def remove_bin(self,bin):
        return self.bins.remove(bin)

    def add_item(self,item):
        self.total_items = len(self.items) + 1

        return self.items.append(item)

    def pack_to_bin(self,bin,item):
        fitted = False

        if not bin.items:
            response = bin.put_item(item,START_POSITION)

            if not response:
                bin.unfitted_items.append(item)

            return

        for axis in range(0,3):
            items_in_bin = bin.items

            for ib in items_in_bin:
                pivot = [0,0]
                w,h,d = ib.get_dimension()
                if axis == Axis.WIDTH:
                    pivot = [
                        ib.position[0] + w,ib.position[1],ib.position[2]
                    ]
                elif axis == Axis.HEIGHT:
                    pivot = [
                        ib.position[0],ib.position[1] + h,ib.position[2]
                    ]
                elif axis == Axis.DEPTH:
                    pivot = [
                        ib.position[0],ib.position[2] + d
                    ]

                if bin.put_item(item,pivot):
                    fitted = True
                    break
            if fitted:
                break

        if not fitted:
            bin.unfitted_items.append(item)

    def pack(
        self,bigger_first=False,distribute_items=False,number_of_decimals=DEFAULT_NUMBER_OF_DECIMALS
    ):
        for bin in self.bins:
            bin.format_numbers(number_of_decimals)

        for item in self.items:
            item.format_numbers(number_of_decimals)

        self.bins.sort(
            key=lambda bin: bin.get_volume(),reverse=bigger_first
        )
        self.items.sort(
            key=lambda item: item.get_volume(),reverse=bigger_first
        )

        for bin in self.bins:
            for item in self.items:
                self.pack_to_bin(bin,item)

            if distribute_items:
                for item in bin.items:
                    self.items.remove(item)


解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)