Пример #1
0
        private int SplitHelper(MyComponentGroupDefinition group, int splitItemValue, int resultItemValue, int numItemsToSplit, int splitCount)
        {
            int            itemValue          = splitItemValue - (splitCount * resultItemValue);
            MyDefinitionId removedComponentId = group.GetComponentDefinition(splitItemValue).Id;

            if (itemValue == 0)
            {
                this.AddRemovalToSolution(removedComponentId, numItemsToSplit);
            }
            else
            {
                this.AddPresentItems(itemValue, numItemsToSplit);
                this.AddChangeToSolution(removedComponentId, group.GetComponentDefinition(itemValue).Id, numItemsToSplit);
            }
            return(splitCount * numItemsToSplit);
        }
        private int SplitHelper(MyComponentGroupDefinition group, int splitItemValue, int resultItemValue, int numItemsToSplit, int splitCount)
        {
            int            remainder          = splitItemValue - (splitCount * resultItemValue);
            MyDefinitionId removedComponentId = group.GetComponentDefinition(splitItemValue).Id;

            if (remainder != 0)
            {
                MyDefinitionId addedComponentId = group.GetComponentDefinition(remainder).Id;
                AddPresentItems(remainder, numItemsToSplit);
                AddChangeToSolution(removedComponentId, addedComponentId, numItemsToSplit);
            }
            else
            {
                AddRemovalToSolution(removedComponentId, numItemsToSplit);
            }

            return(splitCount * numItemsToSplit);
        }
 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;
     }
 }
Пример #4
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);
 }
        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);
        }
Пример #6
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);
        }