sisyphus/bruteforce2.py

156 lines
5.9 KiB
Python
Raw Normal View History

2012-05-02 09:12:10 +00:00
import sys
import itertools
2012-05-14 21:40:48 +00:00
from util import xmlfiletodict, get_pallet, get_articles, product_varlength
2012-05-08 08:01:10 +00:00
from arrange_spread2 import arrange_in_layer, spread_articles
2012-05-02 09:12:10 +00:00
import cPickle
from binascii import b2a_base64
2012-05-02 11:47:38 +00:00
import zlib
import os
2012-05-02 11:47:38 +00:00
def rotate(node):
if node is None:
return
if node['article']:
# exchange x and y coordinate
node['article']['PlacePosition']['X'], node['article']['PlacePosition']['Y'] = node['article']['PlacePosition']['Y'], node['article']['PlacePosition']['X']
# rotate article
node['article']['Orientation'] = node['article']['Orientation']%2+1
rotate(node['right'])
rotate(node['down'])
2012-05-02 09:12:10 +00:00
def get_layers(bins, pallet, rot_article=False, rot_pallet=False):
for abin in bins:
bins[abin] = sorted(bins[abin], key=lambda article: article['Article']['Length']*article['Article']['Width'], reverse=True)
plength, pwidth = (pallet['Dimensions']['Length'], pallet['Dimensions']['Width'])
2012-05-02 11:47:38 +00:00
if rot_pallet:
root, layer, rest = arrange_in_layer(bins[abin], pwidth, plength, rot_article=rot_article)
else:
root, layer, rest = arrange_in_layer(bins[abin], plength, pwidth, rot_article=rot_article)
2012-05-02 09:12:10 +00:00
while layer:
spread_articles(root)
2012-05-02 11:47:38 +00:00
if rot_pallet:
rotate(root)
2012-05-02 09:12:10 +00:00
occupied_area = 0
for article in layer:
length, width = article['Article']['Length'], article['Article']['Width']
occupied_area += length*width
# print "layer occupation:", occupied_area/float(plength*pwidth)
if occupied_area/float(plength*pwidth) <= 0.7:
rot_article, rot_pallet = (yield None, layer)
else:
rot_article, rot_pallet = (yield layer, None)
2012-05-02 11:47:38 +00:00
if rot_pallet:
root, layer, rest = arrange_in_layer(rest, pwidth, plength, rot_article=rot_article)
else:
root, layer, rest = arrange_in_layer(rest, plength, pwidth, rot_article=rot_article)
def get_bit(num, pos):
return num>>pos&1
2012-05-02 09:12:10 +00:00
2012-05-14 21:40:48 +00:00
def get_bitmask(num, length):
return tuple(( bool(num>>pos&1) for pos in xrange(length-1,-1,-1) ))
2012-05-02 09:12:10 +00:00
def main():
2012-05-08 08:01:10 +00:00
if len(sys.argv) != 2:
print "usage:", sys.argv[0], "order.xml"
2012-05-02 09:12:10 +00:00
exit(1)
orderline = xmlfiletodict(sys.argv[1])
pallet = get_pallet(orderline)
articles = get_articles(orderline)
bins = dict()
for article in articles:
abin = bins.get(article['Article']['Height'])
if abin:
abin.append(article)
else:
bins[article['Article']['Height']] = [article]
if os.environ.get("rot_article"):
try_rot_article = bool(int(os.environ["rot_article"]))
else:
try_rot_article = True
if os.environ.get("rot_pallet"):
try_rot_pallet = bool(int(os.environ["rot_pallet"]))
else:
try_rot_pallet = True
if os.environ.get("rot_article_default"):
rot_article_default = bool(int(os.environ["rot_article_default"]))
else:
rot_article_default = False
if os.environ.get("rot_pallet_default"):
rot_pallet_default = bool(int(os.environ["rot_pallet_default"]))
else:
rot_pallet_default = False
if try_rot_article and try_rot_pallet:
product_it = product_varlength(4)
elif try_rot_article or try_rot_pallet:
product_it = product_varlength(2)
2012-05-14 21:40:48 +00:00
while True:
2012-05-02 09:12:10 +00:00
rests = list()
layers = list()
2012-05-14 21:40:48 +00:00
try:
if try_rot_article and try_rot_pallet:
rot_article, rot_pallet = get_bitmask(product_it.send(True), 2)
elif try_rot_article and not try_rot_pallet:
rot_article = get_bitmask(product_it.send(True), 1)[0]
rot_pallet = rot_pallet_default
elif not try_rot_article and try_rot_pallet:
rot_article = rot_article_default
rot_pallet = get_bitmask(product_it.send(True), 1)[0]
else:
rot_article = rot_article_default
rot_pallet = rot_pallet_default
2012-05-14 21:40:48 +00:00
except TypeError:
if try_rot_article and try_rot_pallet:
rot_article, rot_pallet = get_bitmask(product_it.next(), 2)
elif try_rot_article and not try_rot_pallet:
rot_article = get_bitmask(product_it.next(), 1)[0]
rot_pallet = rot_pallet_default
elif not try_rot_article and try_rot_pallet:
rot_article = rot_article_default
rot_pallet = get_bitmask(product_it.next(), 1)[0]
else:
rot_article = rot_article_default
rot_pallet = rot_pallet_default
2012-05-14 21:40:48 +00:00
except StopIteration:
break # generator empty
it = get_layers(bins, pallet, rot_article, rot_pallet)
2012-05-02 09:12:10 +00:00
layer, rest = it.next()
if layer:
layers.append(layer)
if rest:
rests.append(rest)
2012-05-14 21:40:48 +00:00
while True:
2012-05-02 09:12:10 +00:00
try:
if try_rot_article and try_rot_pallet:
layer, rest = it.send(get_bitmask(product_it.send(False), 2))
elif try_rot_article and not try_rot_pallet:
layer, rest = it.send((get_bitmask(product_it.send(False), 1)[0], rot_pallet_default))
elif not try_rot_article and try_rot_pallet:
layer, rest = it.send((rot_article_default, get_bitmask(product_it.send(False), 1)[0]))
else:
layer, rest = it.send((rot_article_default, rot_pallet_default))
2012-05-02 09:12:10 +00:00
if layer:
layers.append(layer)
if rest:
rests.append(rest)
except StopIteration:
break
2012-05-02 11:47:38 +00:00
print b2a_base64(zlib.compress(cPickle.dumps((layers, rests, pallet)))),
if not try_rot_article and not try_rot_pallet:
break # only one iteration if both are deactivated
2012-05-02 09:12:10 +00:00
if __name__ == "__main__":
main()