Example #1
0
 public bool Solve(Dictionary <MyDefinitionId, MyFixedPoint> componentCounts)
 {
     this.m_solution.Clear();
     this.m_solvedItemCounter = 0;
     foreach (KeyValuePair <MyDefinitionId, List <int> > pair in this.m_groups)
     {
         MyComponentGroupDefinition componentGroup = MyDefinitionManager.Static.GetComponentGroup(pair.Key);
         List <int> list = pair.Value;
         this.UpdatePresentItems(componentGroup, componentCounts);
         int itemValue = 1;
         while (true)
         {
             if (itemValue > componentGroup.GetComponentNumber())
             {
                 int componentNumber = componentGroup.GetComponentNumber();
                 while (true)
                 {
                     if (componentNumber < 1)
                     {
                         for (int i = 1; i <= componentGroup.GetComponentNumber(); i++)
                         {
                             int num8 = list[i];
                             if (num8 > 0)
                             {
                                 int num9 = this.TryCreatingItemsByMerge(componentGroup, i, num8);
                                 list[i] = num8 - num9;
                                 this.m_solvedItemCounter += num9;
                             }
                         }
                         break;
                     }
                     int itemCount = list[componentNumber];
                     int num6      = this.TryCreatingItemsBySplit(componentGroup, componentNumber, itemCount);
                     list[componentNumber]     = itemCount - num6;
                     this.m_solvedItemCounter += num6;
                     componentNumber--;
                 }
                 break;
             }
             int removeCount = list[itemValue];
             int num3        = this.TryRemovePresentItems(itemValue, removeCount);
             if (num3 > 0)
             {
                 this.AddRemovalToSolution(componentGroup.GetComponentDefinition(itemValue).Id, num3);
                 list[itemValue] = Math.Max(0, removeCount - num3);
             }
             this.m_solvedItemCounter += num3;
             itemValue++;
         }
     }
     return(this.m_totalItemCounter == this.m_solvedItemCounter);
 }
Example #2
0
        public void AddItem(MyDefinitionId groupId, int itemValue, int amount)
        {
            List <int> list = null;
            MyComponentGroupDefinition componentGroup = MyDefinitionManager.Static.GetComponentGroup(groupId);

            if (componentGroup != null)
            {
                if (!this.m_groups.TryGetValue(groupId, out list))
                {
                    list = this.m_listAllocator.Allocate();
                    list.Clear();
                    int num = 0;
                    while (true)
                    {
                        if (num > componentGroup.GetComponentNumber())
                        {
                            this.m_groups.Add(groupId, list);
                            break;
                        }
                        list.Add(0);
                        num++;
                    }
                }
                List <int> list2 = list;
                int        num2  = itemValue;
                list2[num2]             += amount;
                this.m_totalItemCounter += amount;
            }
        }
Example #3
0
        private int TryCreatingItemsBySplit(MyComponentGroupDefinition group, int itemValue, int itemCount)
        {
            int num = 0;

            for (int i = itemValue + 1; i <= group.GetComponentNumber(); i++)
            {
                int splitCount = i / itemValue;
                int num4       = itemCount / splitCount;
                int num5       = itemCount % splitCount;
                int num7       = this.TryRemovePresentItems(i, num4 + ((num5 == 0) ? 0 : 1));
                if (num7 > 0)
                {
                    int numItemsToSplit = Math.Min(num7, num4);
                    if (numItemsToSplit != 0)
                    {
                        int num9 = this.SplitHelper(group, i, itemValue, numItemsToSplit, splitCount);
                        num       += num9;
                        itemCount -= num9;
                    }
                    if ((num7 - num4) > 0)
                    {
                        int num10 = this.SplitHelper(group, i, itemValue, 1, num5);
                        num       += num10;
                        itemCount -= num10;
                    }
                }
            }
            return(num);
        }
 private void UpdatePresentItems(MyComponentGroupDefinition group, Dictionary <MyDefinitionId, MyFixedPoint> componentCounts)
 {
     m_presentItems.Clear();
     for (int i = 1; i <= group.GetComponentNumber(); i++)
     {
         var          compDef = group.GetComponentDefinition(i);
         MyFixedPoint amount  = 0;
         componentCounts.TryGetValue(compDef.Id, out amount);
         m_presentItems[i] = (int)amount;
     }
 }
        private int TryCreatingItemsBySplit(MyComponentGroupDefinition group, int itemValue, int itemCount)
        {
            int createdCount = 0;

            // Avoid making too much "mess" by trying to find the best-fitting items first
            for (int k = itemValue + 1; k <= group.GetComponentNumber(); k++)
            {
                int fitNumber = k / itemValue;                        // How many items fit into k-item

                int wholeCount = itemCount / fitNumber;               // How many k-items will be fully split

                int partialFitNumber = itemCount % fitNumber;         // How many items will be created from the last k-item
                int partialCount     = partialFitNumber == 0 ? 0 : 1; // How many k-items will be partially split (either 0 or 1 that is)

                int removedCount = TryRemovePresentItems(k, wholeCount + partialCount);
                if (removedCount > 0)
                {
                    int removedWholeCount = Math.Min(removedCount, wholeCount);
                    if (removedWholeCount != 0)
                    {
                        int created = SplitHelper(group, k, itemValue, removedWholeCount, fitNumber);
                        createdCount += created;
                        itemCount    -= created;
                    }

                    if (removedCount - wholeCount > 0)
                    {
                        Debug.Assert(removedCount == wholeCount + partialCount && partialCount == 1, "Calculation problem in cutting solver");
                        int created = SplitHelper(group, k, itemValue, 1, partialFitNumber);
                        createdCount += created;
                        itemCount    -= created;
                    }
                }
            }

            return(createdCount);
        }
        private int TryCreatingItemsByMerge(MyComponentGroupDefinition group, int itemValue, int itemCount)
        {
            // Removal buffer is here so that the method does not do anything until it's clear that the operation can be successful
            List <int> removalBuffer = m_listAllocator.Allocate();

            removalBuffer.Clear();
            for (int i = 0; i <= group.GetComponentNumber(); ++i)
            {
                removalBuffer.Add(0);
            }

            int createdCount = 0;

            // Create the items one-by-one
            for (int i = 0; i < itemCount; ++i)
            {
                // What remains to be found to create this item
                int remainder = itemValue;

                // Fill this item with smaller items as long as possible
                for (int k = itemValue - 1; k >= 1; k--)
                {
                    int amount = 0;
                    if (m_presentItems.TryGetValue(k, out amount))
                    {
                        int removeCount = Math.Min(remainder / k, amount);
                        if (removeCount > 0)
                        {
                            remainder         = remainder - k * removeCount;
                            amount           -= removeCount;
                            removalBuffer[k] += removeCount;
                        }
                    }
                }

                // The remainder was not reduced by the remaining items, which means that we don't have any items left
                if (remainder == itemValue)
                {
                    Debug.Assert(m_presentItems.Count == 0 || itemValue == 1, "There are still items present in the cutting solver, but they were not used in the solution!");
                    break;
                }

                // There are no more smaller items to fill the remainder. Try to split one of the larger ones
                if (remainder != 0)
                {
                    for (int j = remainder + 1; j <= group.GetComponentNumber(); ++j)
                    {
                        int present = 0;
                        m_presentItems.TryGetValue(j, out present);
                        // If there is some present item that is not planned to be removed, use it
                        if (present > removalBuffer[j])
                        {
                            MyDefinitionId removedComponentId = group.GetComponentDefinition(j).Id;
                            MyDefinitionId addedComponentId   = group.GetComponentDefinition(j - remainder).Id;
                            AddChangeToSolution(removedComponentId, addedComponentId, 1);
                            int removed = TryRemovePresentItems(j, 1);
                            AddPresentItems(j - remainder, 1);
                            Debug.Assert(removed == 1);
                            remainder = 0;
                            break;
                        }
                    }
                }

                if (remainder == 0)
                {
                    createdCount++;
                    // Add the buffered removals of the smaller items here
                    for (int k = 1; k <= group.GetComponentNumber(); ++k)
                    {
                        if (removalBuffer[k] > 0)
                        {
                            MyDefinitionId removedComponentId = group.GetComponentDefinition(k).Id;
                            int            removed            = TryRemovePresentItems(k, removalBuffer[k]);
                            Debug.Assert(removed == removalBuffer[k]);
                            AddRemovalToSolution(removedComponentId, removalBuffer[k]);
                            removalBuffer[k] = 0; // We need to clear the buffer for the next item
                        }
                    }
                } // The item could not be created and neither would be the others
                else if (remainder > 0)
                {
                    break;
                }
            }

            m_listAllocator.Deallocate(removalBuffer);

            return(createdCount);
        }
Example #7
0
        private int TryCreatingItemsByMerge(MyComponentGroupDefinition group, int itemValue, int itemCount)
        {
            int        num;
            List <int> item = this.m_listAllocator.Allocate();

            item.Clear();
            int num2 = 0;

            while (true)
            {
                if (num2 <= group.GetComponentNumber())
                {
                    item.Add(0);
                    num2++;
                    continue;
                }
                num = 0;
                int num3 = 0;
                while (true)
                {
                    if (num3 >= itemCount)
                    {
                        break;
                    }
                    int num4 = itemValue;
                    int key  = itemValue - 1;
                    while (true)
                    {
                        if (key >= 1)
                        {
                            int num6 = 0;
                            if (this.m_presentItems.TryGetValue(key, out num6))
                            {
                                int num7 = Math.Min(num4 / key, num6);
                                if (num7 > 0)
                                {
                                    num4 -= key * num7;
                                    num6 -= num7;
                                    List <int> list2 = item;
                                    int        num8  = key;
                                    list2[num8] += num7;
                                }
                            }
                            key--;
                            continue;
                        }
                        if (num4 != itemValue)
                        {
                            if (num4 != 0)
                            {
                                for (int i = num4 + 1; i <= group.GetComponentNumber(); i++)
                                {
                                    int num10 = 0;
                                    this.m_presentItems.TryGetValue(i, out num10);
                                    if (num10 > item[i])
                                    {
                                        MyDefinitionId removedComponentId = group.GetComponentDefinition(i).Id;
                                        this.AddChangeToSolution(removedComponentId, group.GetComponentDefinition(i - num4).Id, 1);
                                        this.TryRemovePresentItems(i, 1);
                                        this.AddPresentItems(i - num4, 1);
                                        num4 = 0;
                                        break;
                                    }
                                }
                            }
                            if (num4 == 0)
                            {
                                num++;
                                for (int i = 1; i <= group.GetComponentNumber(); i++)
                                {
                                    if (item[i] > 0)
                                    {
                                        MyDefinitionId id = group.GetComponentDefinition(i).Id;
                                        this.TryRemovePresentItems(i, item[i]);
                                        this.AddRemovalToSolution(id, item[i]);
                                        item[i] = 0;
                                    }
                                }
                                break;
                            }
                            if (num4 <= 0)
                            {
                                break;
                            }
                        }
                        break;
                    }
                    num3++;
                }
                break;
            }
            this.m_listAllocator.Deallocate(item);
            return(num);
        }