Python’da, eşyaları kutulara py3dbp benzeri bir modül ile yerleştiriyorum. İnşaat alanında kullanılıyor eşyalar dikdörtgen prizması şeklinde. 14 kutum ve 4 eşyam var. Program başlarken eşyaların miktarını giriyorum mesela a eşyasından 10 tane gibi 4 eşyanın amount değerlerini giriyorum. Bazı eşyalar kutuya sığıyor, bazıları uymuyor. Ve buna göre, diğer 13 kutu boş kalır. Çözümü hiçbir yerde bulamadım. Bana yardımcı olabilir misiniz? Modül sadece tüm eşyaları 1. kutuya yüklüyor ve sığmayanları boş kutulara dağıtmıyor.
Sadece bu fonksiyonu yapamadım.
Modül Dosyam
from decimal import Decimal
DEFAULT_NUMBER_OF_DECIMALS = 3
START_POSITION = [0, 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, item2, Axis.WIDTH, Axis.HEIGHT) and
rect_intersect(item1, item2, Axis.HEIGHT, Axis.DEPTH) and
rect_intersect(item1, item2, Axis.WIDTH, 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, width, height, depth, 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.height, self.depth]
elif self.rotation_type == RotationType.RT_HWD:
dimension = [self.height, self.width, self.depth]
elif self.rotation_type == RotationType.RT_HDW:
dimension = [self.height, self.depth, self.width]
elif self.rotation_type == RotationType.RT_DHW:
dimension = [self.depth, self.height, self.width]
elif self.rotation_type == RotationType.RT_DWH:
dimension = [self.depth, self.width, self.height]
elif self.rotation_type == RotationType.RT_WDH:
dimension = [self.width, self.depth, self.height]
else:
dimension = []
return dimension
class Bin:
def __init__(self, name, width, height, depth, 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.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.max_weight = set_to_decimal(self.max_weight, number_of_decimals)
self.number_of_decimals = number_of_decimals
def string(self):
return "%s(%sx%sx%s, max_weight:%s) vol(%s)" % (
self.name, self.width, self.height, self.depth, self.max_weight,
self.get_volume()
)
def get_volume(self):
return set_to_decimal(
self.width * self.height * self.depth, 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, 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[1],
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)
Main Dosyam
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, width, height, depth, max_weight))
def addItem(name, width, height, depth, weight):
packer.add_item(Item(name, width, height, depth, weight))
name = 'E1C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name, width, height, depth, max_weight))
name = 'E2C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name, width, height, depth, max_weight))
name = 'E3C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name, width, height, depth, max_weight))
name = 'E4C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name, width, height, depth, max_weight))
name = 'E5C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name, width, height, depth, max_weight))
name = 'E6C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name, width, height, depth, max_weight))
name = 'E7C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name, width, height, depth, max_weight))
name = 'E8C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name, width, height, depth, max_weight))
name = 'E9C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name, width, height, depth, max_weight))
name = 'E10C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name, width, height, depth, max_weight))
name = 'E11C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name, width, height, depth, max_weight))
name = 'E12C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name, width, height, depth, max_weight))
name = 'EC13C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name, width, height, depth, max_weight))
name = 'EC14C'
width = 200
height = 200
depth = 200
max_weight = 10
packer.add_bin(Bin(name, width, height, depth, 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, width, height, depth, 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, width, height, depth, 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, width, height, depth, 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, width, height, depth, 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, 1:200, 2:200, 3:200, 4:200, 5:200, 6:200, 7:200, 8:200, 9:200, 10:200, 11:200}
depthBinD = {0:200, 1:200, 2:200, 3:200, 4:200, 5:200, 6:200, 7:200, 8:200, 9:200, 10: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", 1:"E2C", 2:"E3C", 3:"E4C"}
widthItemD = {0:30, 1:30, 2:20, 3:40}
heightItemD = {0:30, 1:40, 2:40, 3:40}
depthItemD = {0:30, 1:30, 2:20, 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, width, height, depth, 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, width, height, depth, 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()