16,749
社区成员
发帖
与我相关
我的任务
分享
例1:
原材长度:3m,7m,9m(各有无限根)
余材长度:0m
截取情况:4根2m的
获得结果:取9m的1根余1m,余材1m
例2:
原材长度:3m,8m,9m
余材长度:0m
截取情况:4根2m的
获得结果:取8m的1根余0m,余材0m
例3:
原材长度:3m,7m
余材长度:0m
截取情况:4根2m的
获得结果:取3m的1根余1m,取7m的一根余1,m,余材1m,1m,总共2m
例4:
原材长度:3m,7m
余材长度:0m
截取情况:1根2m的
获得结果:取3m的1根余1m,余材1m
例5:
原材长度:3m,7m,9m
余材长度:0m
截取情况:2根3m的,4根2m的
获得结果:取3m的2根余0m,取9m的一根余1m,总共余材1m
例5:
原材长度:4m,7m,9m
余材长度:0m
截取情况:2根3m的,4根2m的
获得结果:取1根7m的余1根1m,取1根9m的余1m,总共余2m
procedure DFS(ABarIndex, ABarCount: Integer);
var
I, nUnusedLen: Integer;
begin
//剪枝
if (nHaveWasted > nMinWaste) or ((nLenCanUsed - nAllBarLen) > nMinWaste) then
Exit;
Inc(nTerminationCount);
if (ABarIndex = 0) and (ABarCount = -1) then //找到一个方案
begin
nMinWaste := nLenCanUsed; //更新找到的更小的消耗
SetLength(oBestAns, Length(oFindAns));
for I := Low(oFindAns) to High(oFindAns) do
oBestAns[I] := oFindAns[I];
oBestSurplusList := oSaveSurplusList; //记录最好方案时剩下的料头
Exit;
end;
if nTerminationCount >= 100000 then
Exit; //达到一定搜索次数就退出,避免数据量过大时死机
if (ABarIndex > 0) and (ABarCount = -1) then
begin
Dec(ABarIndex);
ABarCount := ABarList[ABarIndex].Count - 1;
DFS(ABarIndex, ABarCount);
Exit;
end;
//先从已经分配的料中里面搜索
for I := Low(oFindAns) to High(oFindAns) do
if oFindAns[I].UnUsedlen >= ABarList[ABarIndex].Len then
begin
oBarList := oFindAns[I].BarList;
SetLength(oBarList, Length(oBarList) + 1);
oBarList[High(oBarList)] := ABarList[ABarIndex];
oBarList[High(oBarList)].Count := 1;
oFindAns[I].BarList := oBarList;
nLenCanUsed := nLenCanUsed - ABarList[ABarIndex].Len;
nAllBarLen := nAllBarLen - ABarList[ABarIndex].Len;
nUnusedLen := oFindAns[I].UnUsedlen;
if nUnusedLen < nMinBarLen then
nHaveWasted := nHaveWasted + nUnusedLen; //更新已经确定消耗了的
DFS(ABarIndex, ABarCount - 1);
//恢复原样
if nUnusedLen < nMinBarLen then
nHaveWasted := nHaveWasted - nUnusedLen;
nAllBarLen := nAllBarLen + ABarList[ABarIndex].Len;
nLenCanUsed := nLenCanUsed + ABarList[ABarIndex].Len;
oBarList := oFindAns[I].BarList;
SetLength(oBarList, High(oBarList));
oFindAns[I].BarList := oBarList;
end;
//从原材里面搜索
for I := Low(oSaveSurplusList) to High(oSaveSurplusList) do
if (oSaveSurplusList[I].Count <> 0) and (oSaveSurplusList[I].Len >= ABarList[ABarIndex].Len) then
begin
Dec(oSaveSurplusList[I].Count);
SetLength(oBarList, 1);
oBarList[0] := ABarList[ABarIndex];
oBarList[0].Count := 1;
if oSaveSurplusList[I].Count >= 0 then
sRemark := SSurplus
else
sRemark := SMaterials;
SetLength(oFindAns, Length(oFindAns) + 1);
oFindAns[High(oFindAns)] := DetailsData(Length(oFindAns), 1, oSaveSurplusList[I].Len,
ABarList[ABarIndex].BarFormat, oBarList, sRemark);
nUnusedLen := oFindAns[High(oFindAns)].UnUsedlen;
nLenCanUsed := nLenCanUsed + nUnusedLen;
nAllBarLen := nAllBarLen - ABarlist[ABarIndex].Len;
if nUnusedLen < nMinBarLen then
nHaveWasted := nHaveWasted + nUnusedLen;
DFS(ABarIndex, ABarCount - 1);
//恢复数据
if nUnusedLen < nMinBarLen then
nHaveWasted := nHaveWasted - nUnusedLen;
nAllBarLen := nAllBarLen + ABarlist[ABarIndex].Len;
nLenCanUsed := nLenCanUsed - nUnusedLen;
SetLength(oFindAns, High(oFindAns));
Inc(oSaveSurplusList[I].Count);
end;
end;