def onAccept(self): if len(self.editID.text()) and " " not in list(self.editID.text()): item = Item() item.name = self.editName.text() item.idItem = self.editID.text() data = Database() try: data.insertItem(item) except sqlite3.IntegrityError: msg = QtWidgets.QMessageBox() msg.setIcon(QtWidgets.QMessageBox.Warning) msg.setText("ID này đã tồn tại !!") msg.setInformativeText("Xin hãy chọn một ID khác và thử lại !!") msg.setStandardButtons(QtWidgets.QMessageBox.Ok) msg.exec() self.isAccept = -1 return self.isAccept = 1 else: msg = QtWidgets.QMessageBox() msg.setIcon(QtWidgets.QMessageBox.Warning) msg.setText("ID này đã tồn tại !!") msg.setInformativeText("Xin hãy chọn một ID khác và thử lại !!") msg.setStandardButton(QtWidgets.QMessageBox.Ok) exec() self.isAccept = -1
def save(params, chunk, chunks_info): global latest_collection_name, history_collection_name data = File.readChunkData(chunk) dbManager = SharedMemoryManager.getInstance() db = dbManager.query() current_index = fn.getNestedElement(chunks_info, 'current', 0) total_index = fn.getNestedElement(chunks_info, 'total', len(data)) date = fn.getNestedElement(params, 'date') datetime = DateTime.convertDateTimeFromString(date) total_length = len(data) queue_info = chunks_info['queue'] # Logger.v('Running Index:', chunks_info['queue']['running']); chunks_info['queue']['current'] += 1 # Logger.v('Saving from... {0}/{1}, current package: {2}'.format(current_index, total_index, total_length) ); fn.printProgressBar(queue_info['current'], queue_info['total'], 'Processing Chunk Insertion') for idx in range(0, total_length): # insert stock_latest row = data[idx] obj_ = transformToLowercase(data=row, datetime=datetime) ModelStockIntegrity.update(data=obj_) dbManager.addBulkInsert(latest_collection_name, obj_, batch=True) # dbManager.addBulkInsert(history_collection_name, obj_, batch=True); # temporary off (need 7 day data only) # insert items # d = data[idx]; ModelItem.saveItem(row) # fn.printProgressBar(current_index+idx, total_index, 'Processing Item Insertion'); #ensure all data is save properly # dbManager.executeBulkOperations(history_collection_name); # temporary off (need 7 day data only) dbManager.executeBulkOperations(latest_collection_name) return chunks_info
def onAddNewItem(self): # sqlite3.IntegrityError if not self.entryName.get(): messagebox.showwarning("Empty !!!!", message="Tên mặt hàng không thể để trống") return if not self.entryID.get(): messagebox.showwarning("Empty !!!!", message="ID không thể để trống") return self.item = Item(name=self.entryName.get(), idItem=self.entryID.get()) try: self.data.insertItem(self.item) except sqlite3.IntegrityError: messagebox.showwarning("Opps !!!!", message="ID bạn nhập đã tồn tại !!!!") return # listItem = self.data.getItemList() # listName = [] # for item in listItem: # listName.append(item.name) # self.master.comboObject.config(values = listName) # self.master.listItem = listItem self.dialog.destroy()
def ReadBenchmarkData(path, instanceName): data = None filePath = os.path.join(path, instanceName) with open(filePath, 'r') as file: data = file.read() # parse file obj = json.loads(data) bin = obj['Objects'][0] W = int(bin['Length']) H = int(bin['Height']) newItems = [] itemId = 0 items = obj['Items'] for item in items: for _ in range(0, int(item['Demand'])): width = int(item['Length']) height = int(item['Height']) newItems.append(Item(itemId, width, height)) itemId += 1 return newItems, H, W
def post(self): json_data = request.get_json(force=True) if not json_data: return {'message': 'No input data provided'}, 400 # Validate and deserialize input data, errors = item_schema.load(json_data) if errors: return errors, 422 item = Item.query.filter_by(name=data['name']).first() if item: return {'message': 'Item with that name already exists'}, 400 item = Item( name=json_data['name'], cost=json_data['cost'], url=json_data['url'], comment=json_data['comment'] ) db.session.add(item) db.session.commit() result = item_schema.dump(item).data return { "status": 'success', 'data': result }, 201
def sell(self, event): # Get item name, price, item Description from Entry itemName = self.sellingFrame.itemEntry.get() price = self.sellingFrame.priceEntry.get() itemDesc = self.sellingFrame.descText.get("1.0", END) # Check price whether it is integer value if self.sellingFrame.imagePath is not '' or self.sellingFrame.imagePath is not None: try: integer_price = int(price) except ValueError: msg = 'price is not an integer' self.mainView.mc.showMessage('Selling Frame Error', msg) return else: # Create item instance item = Item.Item(self.mainView.mc.user.id, itemName, integer_price, itemDesc, self.sellingFrame.imagePath) # Get the Message from Controller whether sell request was succeeded sellFlag, msg = self.mainView.mc.eventHandler.sellingHandler.sell(item) if sellFlag: self.mainView.mc.eventHandler.changeFrame(self.mainView.frameList['main'].mainFrame) self.clearFrame() return else: self.mainView.mc.showMessage('Selling Frame Error', msg) else: msg = 'No Image!' self.mainView.mc.showMessage('Selling Frame Error', msg)
def Run(self): if self.IsCompleted: return items = sorted(self.Items, reverse=True) # TODO: build conflict graph and compute maximal clique items, newNumberOfItems = self.RemoveLargeItems(items, self.Bin.Dy, self.Bin.Dx) self.DetermineConflicts(items, self.Bin.Dy, self.Bin.Dx) conflictGraph = nx.Graph() conflictGraph.add_nodes_from([item.Id for i, item in enumerate(items)]) for i in range(len(items)): itemI = items[i] for j in range(len(items)): itemJ = items[j] if frozenset((itemI.Id, itemJ.Id)) in self.IncompatibleItems: conflictGraph.add_edge(itemI.Id, itemJ.Id) maxClique = clique.max_clique(conflictGraph) sortedMaxClique = sorted(maxClique) newItems = [] for i, oldIndex in enumerate(sortedMaxClique): newItems.append(Item(i, items[oldIndex].Dx, items[oldIndex].Dy)) for i, item in enumerate(items): if item.Id in sortedMaxClique: continue newItems.append(Item(len(newItems), items[item.Id].Dx, items[item.Id].Dy)) self.IncompatibleItems.clear() self.DetermineConflicts(newItems, self.Bin.Dy, self.Bin.Dx) newNumberOfItems = len(newItems) self.UpperBoundsBin = newNumberOfItems self.FixItemToBin = SymmetryBreaking.DetermineFixedItems(self.IncompatibleItems, newNumberOfItems) self.BinDomains = SymmetryBreaking.CreateReducedBinDomains(self.IncompatibleItems, newNumberOfItems, self.UpperBoundsBin, self.FixItemToBin) self.ItemPlacementPatternsX, self.ItemPlacementPatternsY, self.GlobalPlacementPatternsX = SymmetryBreaking.CreateBinDependentPlacementPatterns(self.IncompatibleItems, self.FixItemToBin, newItems, self.UpperBoundsBin, self.Bin, self.PlacementPointStrategy) self.ProcessedItems = newItems self.IsCompleted = True
def onAddItem(self): date = datetime.datetime.now() newId = "IT-" + date.strftime("%d%m%Y%H%M%S") newItem = Item(idItem=newId) data = Database() while True: try: data.insertItem(newItem) except sqlite3.IntegrityError: date = date + datetime.timedelta(0, 1) newId = "IT-" + date.strftime("%d%m%Y%H%M%S") newItem.idItem = newId else: break data.closeDatabase() self.addItemIntoTable(newItem)
def upload(params): Debug = DebugManager.DebugManager() Debug.start() Debug.trace('start') dbManager = SharedMemoryManager.getInstance() db = dbManager.query() date = fn.getNestedElement(params, 'date') path = fn.getNestedElement(params, 'path') # url = fn.getNestedElement(params, 'callback_url'); # required params to handle callback_url paths, should_reset = ModelUpload.getPath(params) for idx in range(0, len(paths)): p = paths[idx] processed_filename = File.converExcelFileToCsv(p, ignore_index=True) Logger.v('processed_filename', processed_filename) Debug.trace('convert to json : path {0}'.format(processed_filename)) if idx == 0 and should_reset: #reset once at the beginning Logger.v('Reset Database.') # ModelUpload.inserted = []; reset() #reset stock_latest collection ModelItem.reset() #reset items collection ModelStockIntegrity.reset(date) #reset stock_datalog by date given File.readCsvFileInChunks(processed_filename, save, params, chunksize=chunksize) Debug.trace('uploaded to mongo.') generateIndex() ModelStockIntegrity.generateIndex() Debug.trace('indexing mongo collection.') trigger_params = copy.deepcopy(params) trigger_params['result'] = 'data count: {0}'.format( params['data_count'][path]) dbManager.executeBulkOperations(None) # Insert all the remaining job at once. ReportStock.triggerOnComplete(trigger_params) Debug.trace('trigger api on complete.') Debug.end() Debug.show('Stock.upload')
def __init__(self, items, bin, enableDomainReduction=True): if enableDomainReduction: # Symmetry breaking according to # Soh, T., Inoue, K., Tamura, N., Banbara, M., & Nabeshima, H. (2010). A SAT-based method for solving the two-dimensional strip packing problem. Fundamenta Informaticae, 102(3-4), 467-487. self.reducedItemIndex = PlacementPointGenerator.DetermineMaximumItemIndexDx( items) self.reducedItem = items[self.reducedItemIndex] reducedDomainThresholdX = PlacementPointGenerator.ReducedDomainX( bin.Dx, self.reducedItem) reducedDomainThresholdY = PlacementPointGenerator.ReducedDomainY( bin.Dy, self.reducedItem) self.reducedDomainThreshold = Item(-1, reducedDomainThresholdX, reducedDomainThresholdY) else: self.reducedItemIndex = -1 self.reducedItem = Item(-1, 0, 0) self.reducedDomainThresholdX = bin.Dx self.reducedDomainThresholdY = bin.Dy self.enableMeetinTheMiddlePreprocessing = True self.meetInTheMiddleMinimizationTarget = MeetInTheMiddleMinimizationTarget.IndividualPlacementPoints
def RemoveLargeItems(self, items, H, W): filteredItemIndices = [] for i, item in enumerate(items): dy = item.Dy dx = item.Dx if dy == H and dx == W: #print(f'Item {i} has the same dimensions as the bin and will be removed.') self.RemovedItems.append(Item(i, dx, dy)) continue isFullyIncompatible = True for j, itemJ in enumerate(items): if i == j: continue if item.Dx + itemJ.Dx > W and item.Dy + itemJ.Dy > H: continue isFullyIncompatible = False break if isFullyIncompatible: #print(f'Item {i} is fully incompatible and will be removed.') self.RemovedItems.append(Item(i, dx, dy)) continue filteredItemIndices.append(i) #self.BinPacking.Model.ObjCon = len(self.RemovedItems) newItems = [] for index, i in enumerate(filteredItemIndices): newItems.append(Item(index, items[i].Dx, items[i].Dy)) return newItems, len(filteredItemIndices)
def createItem(self, msgDict, roomIdx): imgPath = str(roomIdx) + '_' + msgDict['SELLER'] + '_' + msgDict[ 'ITNAME'] + '.' + msgDict['ITPATH'] item = Item.Item(msgDict['SELLER'], msgDict['ITNAME'], msgDict['PRICE'], msgDict['ITDESC'], imgPath, None) return item
def __init__(self, roomIdx, seller, itemName): self.item = Item.Item(seller, itemName) self.roomIdx = roomIdx self.seller = seller self.watch = True
class PlacementPointGenerator: def __init__(self, items, bin, enableDomainReduction=True): if enableDomainReduction: # Symmetry breaking according to # Soh, T., Inoue, K., Tamura, N., Banbara, M., & Nabeshima, H. (2010). A SAT-based method for solving the two-dimensional strip packing problem. Fundamenta Informaticae, 102(3-4), 467-487. self.reducedItemIndex = PlacementPointGenerator.DetermineMaximumItemIndexDx( items) self.reducedItem = items[self.reducedItemIndex] reducedDomainThresholdX = PlacementPointGenerator.ReducedDomainX( bin.Dx, self.reducedItem) reducedDomainThresholdY = PlacementPointGenerator.ReducedDomainY( bin.Dy, self.reducedItem) self.reducedDomainThreshold = Item(-1, reducedDomainThresholdX, reducedDomainThresholdY) else: self.reducedItemIndex = -1 self.reducedItem = Item(-1, 0, 0) self.reducedDomainThresholdX = bin.Dx self.reducedDomainThresholdY = bin.Dy self.enableMeetinTheMiddlePreprocessing = True self.meetInTheMiddleMinimizationTarget = MeetInTheMiddleMinimizationTarget.IndividualPlacementPoints @staticmethod def DetermineMaximumItemIndexDx(items): maximumItemIndex = 0 maximumItemDx = items[0].Dx for i, item in enumerate(items): if item.Dx > maximumItemDx: maximumItemIndex = i maximumItemDx = item.Dx return maximumItemIndex @staticmethod def ReducedDomainX(binDx, item, offsetX=0): return offsetX + math.floor((binDx - item.Dx) / 2.0) @staticmethod def ReducedDomainY(binDy, item): return math.floor((binDy - item.Dy) / 2.0) @staticmethod def IsDomainReductionCompatible(placementPointStrategy): if (placementPointStrategy == PlacementPointStrategy.StandardUnitDiscretization or placementPointStrategy == PlacementPointStrategy.UnitDiscretization or placementPointStrategy == PlacementPointStrategy.NormalPatterns): return True # Domain reduction cannot be applied to mMeet-in-the-middle patterns after they have been generated. return False @staticmethod def IsMaximalPlaceableItem(item, itemSubset, domainReducedItems, binId): for otherItem in itemSubset: if otherItem.Dx > item.Dx or binId in domainReducedItems[ otherItem.Id]: #if otherItem.Dx > item.Dx or domainReducedItems[otherItem.Id] == True: return False return True def CreatePlacementPatterns(self, placementPointStrategy, items, bin): if placementPointStrategy == PlacementPointStrategy.MinimalMeetInTheMiddlePatterns: return self.GenerateMinimalMeetInTheMiddlePatterns(items, bin) placementPatternsX = [] placementPatternsY = [] for i, item in enumerate(items): itemSubset = [] for j, itemJ in enumerate(items): if i == j: continue itemSubset.append(itemJ) placementPatternX, placementPatternY = self.CreateItemSpecificPlacementPattern( placementPointStrategy, item, itemSubset, bin) placementPatternsX.append(placementPatternX) placementPatternsY.append(placementPatternY) return placementPatternsX, placementPatternsY def CreateItemSpecificPlacementPattern(self, placementPointStrategy, item, filteredItems, bin, offsetX=0): # TODO.Logic: bring for-loop over items into this methods and return a list of placement patterns, one entry for each item. # Before the loop, check if placementPointStrategy == PlacementPointStrategy.MinimalMeetInTheMiddlePatterns. If so, jump into separate routine and return immediately afterwards. binDx = bin.Dx binDy = bin.Dy placementPointsX = [] placementPointsY = [] if placementPointStrategy == PlacementPointStrategy.StandardUnitDiscretization: placementPointsX, placementPointsY = self.GenerateStandardUnitDiscretization( filteredItems, item, bin, offsetX) elif placementPointStrategy == PlacementPointStrategy.UnitDiscretization: placementPointsX, placementPointsY = self.GenerateUnitDiscretization( filteredItems, item, bin, offsetX) elif placementPointStrategy == PlacementPointStrategy.NormalPatterns: placementPointsX, placementPointsY = self.GenerateNormalPatterns( filteredItems, item, binDx - item.Dx, binDy - item.Dy, offsetX) elif placementPointStrategy == PlacementPointStrategy.MeetInTheMiddlePatterns: placementPointsX, placementPointsY = self.GenerateMeetInTheMiddlePatterns( filteredItems, item, binDx, binDy, offsetX) elif placementPointStrategy == PlacementPointStrategy.MinimalMeetInTheMiddlePatterns: #print("Item specific minimal meet-in-the-middle patterns are very inefficient. Instead, normal meet-in-the-middle patterns will be generated.") placementPointsX, placementPointsY = self.GenerateMeetInTheMiddlePatterns( filteredItems, item, binDx, binDy, offsetX) else: raise ValueError('UnkownPlacementPointStrategy') return placementPointsX, placementPointsY """ Without symmetry breaking. """ def GenerateStandardUnitDiscretization(self, filteredItems, item, bin, offsetX=0): placementPointsX = list(range(offsetX, offsetX + bin.Dx - item.Dx + 1)) placementPointsY = list(range(0, bin.Dy - item.Dy + 1)) return placementPointsX, placementPointsY """ With symmetry breaking. """ def GenerateUnitDiscretization(self, filteredItems, item, bin, offsetX=0): placementEndX = offsetX + bin.Dx - item.Dx placementEndY = bin.Dy - item.Dy if item.Id == self.reducedItem.Id: placementEndX = min( placementEndX, offsetX + self.reducedDomainThreshold.Dimension(Axis.X)) placementEndY = min(placementEndY, self.reducedDomainThreshold.Dimension(Axis.Y)) placementPointsX = list(range(offsetX, placementEndX + 1)) placementPointsY = list(range(0, placementEndY + 1)) return placementPointsX, placementPointsY """ Domain reduction is feasible for normal patterns. Any feasible solution where the reduced item is not placed within its reduced domain can be transformed into a solution where it is placed in its reduced domain by mirroring the solution. """ def DetermineNormalPatterns(self, items, item, axis, binDimension, offset=0): if binDimension <= 0: return [offset] X = [0] * (binDimension + 1) X[0] = 1 for i, itemI in enumerate(items): for p in range(binDimension - itemI.Dimension(axis), -1, -1): if X[p] == 1: X[p + itemI.Dimension(axis)] = 1 normalPatterns = [] decrementStart = binDimension if item.Id == self.reducedItem.Id: decrementStart = min(binDimension, self.reducedDomainThreshold.Dimension(axis)) for p in range(decrementStart, -1, -1): if X[p] == 1: normalPatterns.append(offset + p) return normalPatterns """ # In this variant, the fact that the item with a reduced domain can only be placed in a certain range is also considered # when generating placement points for other items, not only for the reduced item itself. # This might preserve optimality/feasibility but requires proof. What is special with this variant is that the order in # which the placement points are generated matters, i.e., the order of the items list, which was not the case before. # Consider a bin of dimension 10 and the item dimensions 1, 4, and 5. Reduced normal patterns are: # 5: 0, 1, 4, 5 --> reduced domain = floor((10 - 5) / 2) = 2 --> 0, 1 # 4: 0, 1, 5, 6 # 1 (5, 4): 0, 4, 5, 9 # 1 (4, 5): 0, 4, 5 (9 is not generated because the reduced item cannot be placed on 4) # With order (5, 4), # - the order 5, 4, 1 is possible so that item 1 can be placed at 9, # - the order 4, 5, 1 is not possible because item 5 is outside its reduced domain. # - the order 1, 5, 4 is possible and the mirror solution to 4, 5, 1 # With order (4, 5), # - the order 5, 4, 1, so that item 1 cannot be placed at 9, is not possible. # - the order 4, 5, 1 is not possible # - the order 1, 5, 4 is possible and its mirror solution 4, 5, 1 hast item 1 is placed at 9. # Does this exclude feasible solutions? def DetermineNormalPatternsX(self, items, item, binDx, offsetX = 0): if binDx <= 0: return [offsetX] X = [0] * (binDx + 1) X[0] = 1 for i, item in enumerate(items): itemDecrementStart = binDx - item.Dx if item.Id == self.reducedItem.Id: itemDecrementStart = min(itemDecrementStart, self.reducedDomainThresholdX) for p in range(itemDecrementStart, -1, -1): if X[p] == 1: X[p + item.Dx] = 1 normalPatternsX = [] decrementStart = binDx if item.Id == self.reducedItem.Id: decrementStart = self.reducedDomainThresholdX for p in range (decrementStart, -1, -1): if X[p] == 1: normalPatternsX.append(offsetX + p) return normalPatternsX def DetermineNormalPatternsY(self, items, item, binDy): if binDy <= 0: return [0] Y = [0] * (binDy + 1) Y[0] = 1 for i, item in enumerate(items): itemDecrementStart = binDy - item.Dy if item.Id == self.reducedItem.Id: itemDecrementStart = min(itemDecrementStart, self.reducedDomainThresholdY) for p in range(itemDecrementStart, -1, -1): if Y[p] == 1: Y[p + item.Dy] = 1 normalPatternsY = [] decrementStart = binDy if item.Id == self.reducedItem.Id: decrementStart = self.reducedDomainThresholdY for p in range (decrementStart, -1, -1): if Y[p] == 1: normalPatternsY.append(p) return normalPatternsY """ def GenerateNormalPatterns(self, items, item, binDx, binDy, offsetX=0): normalPatternsX = self.DetermineNormalPatterns(items, item, Axis.X, binDx, offsetX) normalPatternsY = self.DetermineNormalPatterns(items, item, Axis.Y, binDy) return normalPatternsX, normalPatternsY """ Domain reduction on normal patterns is compatible with meet-in-the-middle patterns. The proof should be similar to that of Proposition 5 in Cote and Iori (2018): Meet-in-the-middle principle, which more or less states that one item can be placed in onepcorner of the container. This implies that domain reduction is incompatible with preprocessing step 1 of Cote and Iori (2018). """ def DetermineMeetInTheMiddlePatternsX(self, items, itemI, binDx, t, offsetX=0): """ itemI = items[selectedItemIndex] filteredItems = [] for i, item in enumerate(items): if i == selectedItemIndex: continue filteredItems.append(item) """ meetInTheMiddlePoints = self.DetermineNormalPatterns( items, itemI, Axis.X, min(t - 1, binDx - itemI.Dx), offsetX) # placemenetPointsLeft placemenetPointsRightPrime = self.DetermineNormalPatterns( items, itemI, Axis.X, binDx - itemI.Dx - t, offsetX) for p in placemenetPointsRightPrime: meetInTheMiddlePoints.append(offsetX + binDx - itemI.Dx - p) return meetInTheMiddlePoints def DetermineMeetInTheMiddlePatternsY(self, items, itemI, binDy, t): """ itemI = items[selectedItemIndex] filteredItems = [] for i, item in enumerate(items): if i == selectedItemIndex: continue filteredItems.append(item) """ meetInTheMiddlePoints = self.DetermineNormalPatterns( items, itemI, Axis.Y, min(t - 1, binDy - itemI.Dy)) # placemenetPointsLeft placemenetPointsRightPrime = self.DetermineNormalPatterns( items, itemI, Axis.Y, binDy - itemI.Dy - t) for p in placemenetPointsRightPrime: meetInTheMiddlePoints.append(binDy - itemI.Dy - p) return meetInTheMiddlePoints def GenerateMeetInTheMiddlePatterns(self, items, itemI, binDx, binDy, offsetX=0): # Arbitrary threshold, can be parametrized thresholdDx = math.ceil(binDx / 2) thresholdDy = math.ceil(binDy / 2) meetInTheMiddlePointsX = self.DetermineMeetInTheMiddlePatternsX( items, itemI, binDx, thresholdDx, offsetX) meetInTheMiddlePointsY = self.DetermineMeetInTheMiddlePatternsY( items, itemI, binDy, thresholdDy) return meetInTheMiddlePointsX, meetInTheMiddlePointsY def DetermineMinimalMeetInTheMiddlePatterns(self, items, bin, axis, offset=0): binDimension = bin.Dimension(axis) meetInTheMiddlePointsLeft = [0] * (binDimension + 1) meetInTheMiddlePointsRight = [0] * (binDimension + 1) normalPatterns = [] for i, itemI in enumerate(items): itemSubset = [] for j, itemJ in enumerate(items): if i == j: continue itemSubset.append(itemJ) regularNormalPattern = self.DetermineNormalPatterns( items, itemI, axis, binDimension - itemI.Dimension(axis)) for p in regularNormalPattern: if self.meetInTheMiddleMinimizationTarget == MeetInTheMiddleMinimizationTarget.IndividualPlacementPoints: # Determine tMin according to (9) with individual placement point counts. meetInTheMiddlePointsLeft[p] += 1 meetInTheMiddlePointsRight[binDimension - itemI.Dimension(axis) - p] += 1 elif self.meetInTheMiddleMinimizationTarget == MeetInTheMiddleMinimizationTarget.PlacementPointUnion: # Alternatively, placement point union: meetInTheMiddlePointsLeft[p] = 1 meetInTheMiddlePointsRight[binDimension - itemI.Dimension(axis) - p] = 1 else: raise ValueError( "Invalid meet-in-the-middle minimization target.") normalPatterns.append(regularNormalPattern) for p in range(1, binDimension + 1): meetInTheMiddlePointsLeft[p] = meetInTheMiddlePointsLeft[ p] + meetInTheMiddlePointsLeft[p - 1] meetInTheMiddlePointsRight[ binDimension - p] = meetInTheMiddlePointsRight[ binDimension - p] + meetInTheMiddlePointsRight[binDimension - p + 1] tMin = 1 minThreshold = meetInTheMiddlePointsLeft[ 0] + meetInTheMiddlePointsRight[1] for p in range(2, binDimension + 1): if meetInTheMiddlePointsLeft[ p - 1] + meetInTheMiddlePointsRight[p] < minThreshold: minThreshold = meetInTheMiddlePointsLeft[ p - 1] + meetInTheMiddlePointsRight[p] tMin = p meetInTheMiddlePatterns = [] if self.enableMeetinTheMiddlePreprocessing: meetInTheMiddlePatterns = self.GenerateReducedMeetInTheMiddlePatterns( items, axis, binDimension, tMin) else: meetInTheMiddlePatterns = self.GenerateMeetInTheMiddleFromNormalPatterns( items, axis, binDimension, normalPatterns, tMin) return meetInTheMiddlePatterns def GenerateReducedMeetInTheMiddlePatterns(self, items, axis, binDimension, threshold): itemSpecificModifiedDimensions = [] itemSpecificPatternsLeft = [] itemSpecificPatternsRight = [] itemSpecificMeetInTheMiddlePatterns = [] for i, item in enumerate(items): meetInTheMiddlePointsLeft = self.DetermineNormalPatterns( items, item, axis, min(threshold - 1, binDimension - item.Dimension(axis))) # placemenetPointsLeft placemenetPointsRightPrime = self.DetermineNormalPatterns( items, item, axis, binDimension - item.Dimension(axis) - threshold) meetInTheMiddlePointsRight = [] for p in placemenetPointsRightPrime: meetInTheMiddlePointsRight.append(binDimension - item.Dimension(axis) - p) itemSpecificPatternsLeft.append(meetInTheMiddlePointsLeft) itemSpecificPatternsRight.append(meetInTheMiddlePointsRight) meetInTheMiddlePattern = list( set(meetInTheMiddlePointsRight) | set(meetInTheMiddlePointsLeft)) itemSpecificMeetInTheMiddlePatterns.append(meetInTheMiddlePattern) initialDimensions = [item.Dimension(axis)] * (binDimension + 1) itemSpecificModifiedDimensions.append(initialDimensions) # Proposition 6 for left self.DetermineEnlargedItemDimensionsLeft( items, axis, itemSpecificModifiedDimensions, itemSpecificPatternsLeft, binDimension, itemSpecificMeetInTheMiddlePatterns) # Proposition 6 for right self.DetermineEnlargedItemDimensionsRight( items, axis, itemSpecificModifiedDimensions, itemSpecificPatternsRight, binDimension, itemSpecificMeetInTheMiddlePatterns) # Merge left and right patterns to meet in the middle sets # Necessary since right placement points may be changed in DetermineEnlargedItemDimensionsRight() for i, _ in enumerate(items): itemSpecificMeetInTheMiddlePatterns[i] = list( set(itemSpecificPatternsLeft[i]) | set(itemSpecificPatternsRight[i])) # Proposition 7 self.RemoveRedundantPatterns(items, itemSpecificModifiedDimensions, itemSpecificMeetInTheMiddlePatterns) return itemSpecificMeetInTheMiddlePatterns def RemoveRedundantPatterns(self, items, itemSpecificModifiedDimensions, itemSpecificMeetInTheMiddlePatterns): for k, itemK in enumerate(items): modifiedItemDimensionsK = itemSpecificModifiedDimensions[k] placementPoints = itemSpecificMeetInTheMiddlePatterns[k] for p in placementPoints: # p < s for s in placementPoints: if p >= s: continue modifiedWidthP = modifiedItemDimensionsK[p] modifiedWidthS = modifiedItemDimensionsK[s] if s + modifiedWidthS <= p + modifiedWidthP: placementPoints.remove(p) def DetermineEnlargedItemDimensionsRight( self, items, axis, itemSpecificModifiedDimensions, itemSpecificPatternsRight, binDimension, preliminaryItemSpecificMeetInTheMiddlePatterns): for k, itemK in enumerate(items): itemK = items[k] minSelectedItemDimension = itemK.Dimension(axis) modifiedItemDimensionsK = itemSpecificModifiedDimensions[k] placementPointsRight = itemSpecificPatternsRight[k] for p in placementPointsRight: if p > binDimension - minSelectedItemDimension: continue sMax = 0 for i, itemI in enumerate(items): if i == k: continue minSelectedItemDimensionI = itemI.Dimension(axis) meetInTheMiddlePointsI = preliminaryItemSpecificMeetInTheMiddlePatterns[ i] modifiedItemDimensionsI = itemSpecificModifiedDimensions[i] for s in meetInTheMiddlePointsI: if s > binDimension - minSelectedItemDimensionI: continue if s + modifiedItemDimensionsI[s] <= p: sMax = max(sMax, s + modifiedItemDimensionsI[s]) else: break q = max(0, sMax) if q < p: if q not in placementPointsRight: placementPointsRight.append(q) placementPointsRight.remove(p) modifiedItemDimensionsK[ q] = p + minSelectedItemDimension - q def DetermineEnlargedItemDimensionsLeft( self, items, axis, itemSpecificModifiedDimensions, itemSpecificPatternsLeft, binDimension, preliminaryItemSpecificMeetInTheMiddlePatterns): for k, itemK in enumerate(items): itemK = items[k] minSelectedItemDimension = itemK.Dimension(axis) modifiedItemDimensionsK = itemSpecificModifiedDimensions[k] placementPointsLeft = itemSpecificPatternsLeft[k] for p in placementPointsLeft: if p > binDimension - minSelectedItemDimension: # can this even occur? Could break instead if points are guaranteed to be sorted (which they are!?) in order to be faster. continue sMin = binDimension for i, itemI in enumerate(items): if i == k: continue minSelectedItemDimensionI = itemI.Dimension(axis) meetInTheMiddlePointsI = preliminaryItemSpecificMeetInTheMiddlePatterns[ i] for s in meetInTheMiddlePointsI: if s > binDimension - minSelectedItemDimensionI: continue if s >= p + modifiedItemDimensionsK[p]: sMin = min(sMin, s) break q = min(binDimension, sMin) if q > p: assert q - p >= minSelectedItemDimension modifiedItemDimensionsK[p] = q - p def GenerateMeetInTheMiddleFromNormalPatterns(self, items, axis, binDimension, normalPatterns, tMin): meetInTheMiddlePatterns = [] for i, item in enumerate(items): meetInTheMiddlePattern = [] for p in normalPatterns[i]: if p < tMin: meetInTheMiddlePattern.append(p) if binDimension - item.Dimension(axis) - p >= tMin: meetInTheMiddlePattern.append(binDimension - item.Dimension(axis) - p) meetInTheMiddlePatterns.append(meetInTheMiddlePattern) return meetInTheMiddlePatterns def GenerateMinimalMeetInTheMiddlePatterns(self, items, bin, offsetX=0): meetInTheMiddlePatternsX = self.DetermineMinimalMeetInTheMiddlePatterns( items, bin, Axis.X, offsetX) meetInTheMiddlePatternsY = self.DetermineMinimalMeetInTheMiddlePatterns( items, bin, Axis.Y) return meetInTheMiddlePatternsX, meetInTheMiddlePatternsY
def find(params): group_by = fn.getNestedElement(params, 'group_by', None); data = ModelItem.search(params); # Logger.v(data); result = ModelItem.processItemList(data, group_by); return Params.generate(True, result);