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; } }
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); }
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); }