packer.pack() returns only 1 item for the final bin
gamesguru opened this issue · 9 comments
As you can see, i have 5 Item
objects.
They were all properly fit into a reasonable Bin
<py3dbp.main.Packer object at 0x7fbdbda04b00>
bins:[ ... ]
items:[]
total_items:5
unfit_items:[]
But when accessing the bin (the only one with contents)..
it says it contains just 1 item? Where are the other 4?
3:<py3dbp.main.Bin object at 0x7fbdbd772c18>
depth:5.5
height:8.5
items:[<py3dbp.main.Item ob...dbcb39198>]
0:<py3dbp.main.Item object at 0x7fbdbcb39198>
__len__:1
max_weight:70.0
name:'medium-box'
width:11.0
Can provide sample data if needed.
Thanks,
for providing such a wonderful library,
gg
@gamesguru, can you provide me the data that you are using please.
thanks
I've made a temporary fork please run example2.py
. You will see it outputs only one bin as having items, and only 1 item in that bin. But i think all the items are being packed?
I have an example in which a single large bin can hold 2 items, but if another smaller bin is added, then the large bin is ignored:
from py3dbp.main import Packer, Bin, Item\
packer = Packer()
packer.add_bin(Bin("Large Bin", 150, 150, 150, 100))
packer.add_item(Item("Item 1", 75, 15, 10, 0))
packer.add_item(Item("Item 2", 9, 10, 15, 20))
for _ in packer.items:
print(_.__dict__)
packer.pack()
for b in packer.bins:
print(b.string())
for i in b.items:
print("====> ", i.string())
Returns
Large Bin(150x150x150, max_weight:100)
====> Item 2(9x10x15, weight: 20) pos([0, 0, 0]) rt(0)
====> Item 1(75x15x10, weight: 0) pos([9, 0, 0]) rt(0)
If I add a second bin, then the only the small items is assigned to the small bin, the large bin is ignored:
from py3dbp.main import Packer, Bin, Item
packer = Packer()
packer.add_bin(Bin("Large Bin", 150, 150, 150, 100))
packer.add_bin(Bin("Small Bin", 15, 15, 15, 20))
packer.add_item(Item("Item 1", 75, 15, 10, 0))
packer.add_item(Item("Item 2", 9, 10, 15, 20))
packer.pack()
for b in packer.bins:
print(b.string())
for i in b.items:
print("====> ", i.string())
returns
Small Bin(15x15x15, max_weight:20)
====> Item 2(9x10x15, weight: 20) pos([0, 0, 0]) rt(0)
Large Bin(150x150x150, max_weight:100)
It might be a limitation of the algorithm is based on, as it mentions that all bins are identical.
Actually I was wrong, I made a fix on my fork and created a pull request. Hope it helps!
Tested with the following example:
packer.add_bin(Bin("Small Bin 1", 15, 15, 15, 100))
packer.add_bin(Bin("Small Bin 2", 15, 15, 15, 100))
packer.add_item(Item("Item 1", 8, 15, 10, 20))
packer.add_item(Item("Item 2", 9, 10, 15, 20))
packer.pack()
for b in packer.bins:
print(b.string())
for i in b.items:
print("====> ", i.string())
if packer.unfit_items:
print('Unfit items')
for b in packer.unfit_items:
print("====> ", b.string())
Thanks for looking into this, however it's not fixed yet. Please use example2.py
as it included the real code which caused me to open this issue. Thanks.
Additionally, you move example.py
into project root? And now example2.py
is broken with stacktrace :[
You can clearly see from example2.py
that there is adequate bin space, and no remaining items, but some small bug is preventing items from being reported as binned up.
import json
from main import Packer, Bin, Item
packer = Packer()
packer.add_bin(Bin('small-envelope', 11.5, 6.125, 0.25, 0.8125))
packer.add_bin(Bin('large-envelope', 15.0, 12.0, 0.75, 0.8125))
packer.add_bin(Bin('small-box', 8.625, 5.375, 1.625, 70.0))
packer.add_bin(Bin('medium-box', 11.0, 8.5, 5.5, 70.0))
packer.add_bin(Bin('medium-box', 13.625, 11.875, 3.375, 70.0))
packer.add_bin(Bin('large-box', 12.0, 12.0, 5.5, 70.0))
packer.add_bin(Bin('large-box', 23.6875, 11.75, 3.0, 70.0))
packer.add_item(Item('50g [powder]', 3.9370, 1.9685, 1.9685, 50))
packer.add_item(Item('50g [powder]', 3.9370, 1.9685, 1.9685, 50))
packer.add_item(Item('50g [powder]', 3.9370, 1.9685, 1.9685, 50))
packer.add_item(Item('250g [powder]', 7.8740, 3.9370, 1.9685, 250))
packer.add_item(Item('250g [powder]', 7.8740, 3.9370, 1.9685, 250))
packer.add_item(Item('250g [powder]', 7.8740, 3.9370, 1.9685, 250))
packer.add_item(Item('250g [powder]', 7.8740, 3.9370, 1.9685, 250))
packer.add_item(Item('250g [powder]', 7.8740, 3.9370, 1.9685, 250))
packer.add_item(Item('250g [powder]', 7.8740, 3.9370, 1.9685, 250))
packer.pack()
for bin in packer.bins:
if bin.items:
print(json.dumps(bin, default=lambda x: x.__dict__))
print(len(bin.items))
Is the workaround to just pack one bin at a time, and compose them together at the end. That might work?
@gamesguru @janoxakes Sorry for no answer your questions, I was out of time in the last 3 weeks.
What it does the current version of the library is:
- The Bin and the Item params:
(name, width, height, depth, weight)
. - From a list of bins and items, it takes the smallest bin and try to put at least one item in it until the bin can not pack the next items. Then it does not try to put the rest of the items in the other bins and it stops.
- You can start from the bigger bin using the param
bigger_first=True
in the pack() function.
I was thinking to modify the library to accept the next two sceneries:
- From a list of bins and items, put the items in the bins that at least one item be in one bin that can be fitted. That is, distribute all the items in all the bins so that they can be contained.
- From a list of bins and items, try to put all the items in each bin and in the end it show per bin all the items that was fitted and the items that was not.
It is also pending to add more detailed documentation.
If you have more ideas, let me know, I would greatly appreciate them,
Greetings!
@gamesguru, I'm sorry, I thought I had answered you. In your example there is no enough space & weight for them, the only possible solution is to pack the three 50g [powder] items in any combination of the medium and large boxes. That is the response I was getting, just confirmed with my last commit. Please bear in mind I am making heavy changes to the code to make it more flexible. Your example can be executed using example.py in the root
@enzoruiz I have modified the code to split objects and algorithm in a way that new algorithms are easily implemented. The code is not properly commented, but I think it should be easy to understand. I will add more comments and function as time and requirements allow.
Hi @janoxakes @gamesguru
I recently upload a new version (1.0.0) that add the two scenarios that i wanted to cover.
I hope this version would more stable otherwise i would appreciate it if you let me know any problems you have encountered.
Greetings!!