我正在研究一個必須處理揹包/子集和問題的特例的問題。問題如下:具有相同權重/值的修改揹包/子集合總和
您有一組隨機大小減小的包大小:{47, 35, 22, ...}
。您具有的值就是這樣的小部件數量:#widgets = 33. 查找可以構成捆綁包小部件數量的最少捆綁數量。如果沒有辦法返回等於數量的集合,則返回null。
- 實施例1:
- 包大小:46,25,12,如圖4所示,3
- 量:30
- 返回值:{46:0,25:0,12:2, 4:0,3:2}(束尺寸:束#)
- 實施例2:
- 包大小:46,25,12,如圖4所示,3
- 量:17
- 返回值:{46:0,25:0,12:0,4:2,3:3}
- 實施例3:
- 包大小:46,25 ,12,4,3
- 量:47
- 返回值:{46:0,25:1,12:1,4:1,3:2}
- 實施例4:
- 種尺寸:46,25,12,4,3
- 數量:5
- 返回值:空
將如何着手這個問題?
我已經在C#中編寫了一個程序,它能夠完成足夠的工作,但會重置for循環中的索引以轉儲不適用於其餘集合的程序包大小。如果請求發送源文件,它會發送多遠。
請求代碼:
public List<int> BreakDown(List<int> bunSize, int buySize)
{
List<int> tempBunSize = bunSize.ToList();
tempBunSize.RemoveAll(e => e > buySize);
List<int> ammountNeeded = new List<int>();
int result = buySize;
for (int index = 0; index < tempBunSize.Count; index++)
{
int size = tempBunSize[index];
int tempResult = 0;
double calcResult = 0;
int addAmmount = 0;
if (index == tempBunSize.Count - 2)
{
tempResult = result % size;
if ((tempBunSize.Count > 2 || result % tempBunSize[tempBunSize.Count - 1] == 0))
{
if (result % size != 0)
{
ammountNeeded.Add(0);
tempResult = result % tempBunSize[tempBunSize.Count - 1];
if (tempResult != 0)
{
tempResult = result;
int sizeInc = 0;
while (tempResult != 0)
{
tempResult = tempResult - size;
sizeInc++;
if (tempResult < 0)
{
int decreaseOne = ammountNeeded.First();
ammountNeeded[0] = --decreaseOne;
result = result + tempBunSize.First();
if (ammountNeeded[0] <= 0)
{
tempBunSize.RemoveAt(0);
index = 0;
ammountNeeded = new List<int>();
}
ammountNeeded.Remove(0);
--index;
break;
}
if (tempResult % tempBunSize[tempBunSize.Count - 1] == 0)
{
ammountNeeded.Remove(0);
ammountNeeded.Add(sizeInc);
ammountNeeded.Add(tempResult/tempBunSize[tempBunSize.Count - 1]);
break;
}
}
if (tempResult < 0) continue;
break;
}
else
{
calcResult = result/tempBunSize[tempBunSize.Count - 1];
addAmmount = (int)Math.Floor(calcResult);
ammountNeeded.Add(addAmmount);
break;
}
}
else if (result % size == 0)
{
tempResult = result % size;
if (tempResult != 0 && result % tempBunSize[tempBunSize.Count - 1] != 0)
{
int decreaseOne = ammountNeeded.First();
ammountNeeded.Insert(0, --decreaseOne);
result = result + tempBunSize.First();
continue;
}
else
{
calcResult = result/size;
addAmmount = (int)Math.Floor(calcResult);
ammountNeeded.Add(addAmmount);
if (result % size == 0)
{
ammountNeeded.Add(0);
break;
}
calcResult = result/tempBunSize[tempBunSize.Count - 1];
addAmmount = (int)Math.Floor(calcResult);
ammountNeeded.Add(addAmmount);
break;
}
}
}
else if (tempResult % tempBunSize[tempBunSize.Count - 1] != 0)
{
tempResult = result;
int sizeInc = 0;
while (tempResult != 0)
{
tempResult = tempResult - size;
sizeInc++;
if (tempResult % tempBunSize[tempBunSize.Count - 1] == 0)
{
ammountNeeded.Add(sizeInc);
ammountNeeded.Add(tempResult/tempBunSize[tempBunSize.Count - 1]);
break;
}
}
break;
}
else if (result == 0)
{
while (ammountNeeded.Count < bunSize.Count)
{
ammountNeeded.Add(0);
}
break;
}
else
{
calcResult = result/size;
ammountNeeded.Add((int)Math.Floor(calcResult));
calcResult = tempResult/tempBunSize[tempBunSize.Count - 1];
ammountNeeded.Add((int)Math.Floor(calcResult));
break;
}
}
ammountNeeded.Add((int)Math.Floor((decimal)result/size));
result = result % size;
if (result == 0) continue;
}
if (ammountNeeded.Count < bunSize.Count)
{
ammountNeeded.Reverse(0, ammountNeeded.Count);
while (ammountNeeded.Count < bunSize.Count)
{
ammountNeeded.Add(0);
}
ammountNeeded.Reverse(0, ammountNeeded.Count);
}
if (ammountNeeded.FindLast(e => e < 0) < 0 || ammountNeeded.Sum() == 0)
return null;
return ammountNeeded;
}
}
它*總是*發佈您創建的代碼的好主意。 – paqogomez
要做的一件事很簡單,就是刪除大於數量的所有捆綁包大小。 –
我相信「tempBunSize.RemoveAll(e => e> buySize)」如果有更大的數量(buySize),則從臨時捆綁列表中刪除捆綁包大小。 – MarcusM