求一个算法的解决方案(思路)

leejd 2003-03-19 03:40:21
问题:
有一堆不同批次的产品,其数量按批次分别为:1,5,38,4,24,78,1,4,21,2,9,48,12,4,6,12。
现在要将他们放入4只集装箱中,要求每箱的数量要尽可能相等。
问题:1,不拆分一个批次内的数量,怎么样放置比较合理;
2,可以拆分一个批次内的数量,怎么样放置合理。
...全文
75 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
alphax 2003-03-29
  • 打赏
  • 举报
回复
mark
leejd 2003-03-24
  • 打赏
  • 举报
回复
不好意思,我最多只能给200分,先给你200好了
leejd 2003-03-24
  • 打赏
  • 举报
回复
呵呵,非常好,再加100结分
ZhangYv 2003-03-22
  • 打赏
  • 举报
回复
如果有n个箱子可以分n份,就几乎可以让每个箱子零件尽可能相等。如果非要求个尽可能的少拆分,又要尽可能的使每个集装箱尽可能的相等,这很复杂!
假设是先拆分零件后再装箱,可能不会保证每个集装箱零件尽可能的相等;如果分好之后再考虑拆分零件,那可能不满足尽可能的少拆分的条件,如果有N个箱子,至多也最有可能被拆成N份。
如果对拆分使用一个折中的方法, 可能需要对要拆分的零件R分成的有0 <= d <= N的集合进行搜索,这又是NP规模的问题。除非再次使用近似算法(搜索部分子集,精度就不好保证),否则会极大提高算法复杂度。
总之,对你要求的条件,我暂时没想出什么有可能的好方法。但我觉得没必要考虑这么复杂,对要拆零件对半分就可以了,实际上这种拆分最少,但有只会损失不多的精度,划的来!所以,最好的解决方法我觉的是对第一次得出的解,做近一步的修正和调整。比如:
[48,12,6,2],[39,24,5],[39,21,4,1,1], [38,12,9,4,4,] = 68,68,66,67
平均线约是67,对近似解做近一步的调整:在平均线ave上的,看看能不能和在平均线ave下的箱子进行调整以达到提高精度的目的。考虑这个似乎比较容易,可以采用合适的算法来找需要调整的对象.对于上述的,就是2和1交换,如果找不到正好的项,我们可以取局部最优减少些精度,以节省大量的算法时间。剩下的自己考虑应该不会有困难吧?
leejd 2003-03-21
  • 打赏
  • 举报
回复
如果不拆分,我认为你的数据已经相当的不错了。
拆分的情况比较复杂,同一个批次要尽可能的少拆分(实际需要),但是又要尽可能的使每个集装箱尽可能的相等。

再加100分
ZhangYv 2003-03-20
  • 打赏
  • 举报
回复
执行后的结果为
[78],[48,12,2,1], [38,24,1], [21,12,9,6,5,4,4,4] = 78,63,63,65
比[78], [48,12,6,2], [38,24,5,1], [21,12,9,4,4,4,1] = 78,68,68,55更合理
ZhangYv 2003-03-20
  • 打赏
  • 举报
回复
这道题很象“把若干不同体积的零件放在n个容积为R的箱子里,问如何才能放最多零件”这是NPC的
你的问题可以这样描述,把n个数据划分成m个集合,让每个集合里的元素总和的方差最小。
至于为什么把78分成39*2是因为你没说至多可以分几份,我当成至少可以分2份来处理的,随便分的:) 如果78可以分4份的话,78这批零件可以先不考虑,最后对每个箱子均一下就可以得最优解。
为了求总和的方差最小,上述算法还可以改进一下:

假设每只箱子只有K(零件总数量/箱子数)个的容量,MaxSize是批次,boxnum是箱子数;
1 对零件M[16]按递减排序
2 s = 0, box[0..3] = 0, selected = 空集;
3 for (i = 0, j = 0; i < MaxSize; i++)
if (M[i] >= K){
box[j] = box[j] + M[i];
availBox_no = boxnum - j //求还有多少箱子可用
s = s + M[i]; //已装箱零件数量
selected <- i; //第i批次已选
k = (k * availBox_no - M[i]) / (availBox_no - 1);//重新修改平均数K
j++; //让超出箱子容量K的零件独占一个箱子
}
else
break;
startFlag = j;//从剩余可用的第j个箱子开始装剩下的零件
4 for (i = 0; i < MaxSize; i++)
{
for (j = startFlag; box[j] + M[i] > K && j < boxnum; j++);//寻找可容纳第i批箱子
//找到则装箱
if (j < boxnum){
box[j] = box[j] + M[i];
s = s + M[i]; //已装箱零件数量
selected <- i; //第i批次已选
}
}
5 for (i = 0; i < MaxSize; i++)
{
if (第i批次未被选)
{
对box[n]的容量按递增插入排序;//设box[m]数量最少
box[m] = box[m] + M[i];
s = s + M[i];
selected <- i; //第i批次已选
}
}
增加了第3步,可以让总和的方差最小,适合解决问题1,不影响问题2的解决
leejd 2003-03-20
  • 打赏
  • 举报
回复
加点分,希望能够扩展的谈论一下,不够继续加
leejd 2003-03-20
  • 打赏
  • 举报
回复
2 ZhangYv() :
谢谢你给的算法!
对于第二个问题,为什么需要那样分拆呢?我对算法不熟悉,还请多多指点
ZhangYv 2003-03-19
  • 打赏
  • 举报
回复
似乎是NPC的问题。给个用贪心求近似解的思路,把78拆成39*2适用问题2。问题1,把78装一个箱子里。
假设每只箱子只有K(零件总数量/箱子数)个的容量,MaxSize是批次;
1 对零件M[16]按递减排序 78,48,[39,39]38,24,21,12,12,9,6,5,4,4,4,2,1,1
2 s = 0, box[0..3] = 0, selected = 空集;
3 for (i = 0; i < MaxSize; i++)
{
for (j = 0; box[j] + M[i] > K && j < 4; j++);
if (j < 4){
box[j] = box[j] + M[i];
s = s + M[i]; //已装箱零件数量
selected <- i; //第i批次已选
}
}
4 for (i = 0; i < MaxSize; i++)
{
if (第i批次未被选)
{
对box[n]的容量按递增排序;//设box[m]数量最少
box[m] = box[m] + M[i];
s = s + M[i];
selected <- i; //第i批次已选
}
}
上述写为程序结果是:
问题1的解是:[78], [48,12,6,2], [38,24,5,1], [21,12,9,4,4,4,1] = 78,68,68,55
问题2的解是:[48,12,6,2],[39,24,5],[39,21,4,1,1], [38,12,9,4,4,] = 68,68,66,67
都为近似解


xdspower 2003-03-19
  • 打赏
  • 举报
回复
贪心算法是可以的,不过时间要化得比较多,而且你没有考虑集装箱是否够装
dcyu 2003-03-19
  • 打赏
  • 举报
回复
我觉得评价“放置比较合理”的标准是各个箱的方差最小,可以用最小均方误差法逐步调整。
这让我想到了神经网络……
tarkey 2003-03-19
  • 打赏
  • 举报
回复
...........呵呵,还是用贪心法吧。

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧