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
Exemple #2
0
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
Exemple #3
0
    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()
Exemple #4
0
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
Exemple #5
0
    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
Exemple #6
0
    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)
Exemple #7
0
    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)
Exemple #9
0
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')
Exemple #10
0
    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
Exemple #11
0
    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)
Exemple #12
0
 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
Exemple #13
0
 def __init__(self, roomIdx, seller, itemName):
     self.item = Item.Item(seller, itemName)
     self.roomIdx = roomIdx
     self.seller = seller
     self.watch = True
Exemple #14
0
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
Exemple #15
0
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);