这个该如何用递补归快速求出解来呢?(100分)

CSDN的留言不能发太长的,只能贴在这里了。
你好,关于你的问题目前没有现成的算法,至少在未来10年内也不会有。那个程序太长又没有注释,我看
得太累啦!我想他应该是硬搜吧,这个问题计算的规模随木材数量以几何级数递增,所以如果死搜索的话
对于大一点的数据则程序就变得毫无用处。对于一些人工只能的方法可以使这个问题得到较好的解决,但
难度太大。
以下C++程序是我对上次给你的近似算法的没有本质变化的小改进,他的PASCAL程序可以求最优解但速度
奇慢无比,可在木材数很小话速度还是可以接受的。我们可以取一个中和,先用我的算法求解(相当于预
处理)一部分,对于某几组最不好的解加上未处理的数据再利用他的程序调整。你可以手动测试一下,效
果会略好一些。
/*
以下是NEXT-FIT近似算法,设V(N) = m为最优解,
则由NIFF算法得出解Rniff(N) <= m + [(m+1)/3] <= 4/3 + 1/3*m
*/
#include <iostream.h>
#include <stdio.h>
const int MAXSIZE_WOOD = 50;
const int MAXSIZE = 500;//最大分类不能超过MAXSIZE份
const int lq = 5;
struct List{
int index;
struct List *next;
};
int N = 0;
int WoodNum;
int num;
float A[MAXSIZE_WOOD];
List *Result[MAXSIZE];//存放最后结果的有表头链表
void Sort()
{
int i, j;
float temp;
for (i = 0;
i < WoodNum;
i++)
for (j = i;
j < WoodNum;
j++)
if (A < A[j]){
temp = A;
A = A[j];
A[j] = temp;
}
}
void Create()
{
int i;
float t;
cout << "Input N = ";
//N是原材料的长度
cin >> N;
cout << "Input WoodNum = ";
cin >> WoodNum;
cout << "Please Input WoodLenght <= N " << endl;
for (i = 0;
i < WoodNum;
i++){
do
{
cout << "Input A[" << i << "] = ";
cin >> t;}
while (t > N);
A = t;
}
Sort();
//进行排序预处理提高近似精度
num = WoodNum;
WoodNum -= lq;
}
void Destroy()
{
}
void Insert(int i, int j)//对Result链表插入
{
List *temp;
temp = new List;
temp->index = i;
temp->next = Result[j]->next;
Result[j]->next = temp;
}
int ComputeResult()//计算分类方案,返回至少需要分max份
{
float s[MAXSIZE];
int *selected = new int[MAXSIZE+1];
int i, j, max;
for (i = 0;
i < MAXSIZE;
i++){
s = 0;
Result = new List;
Result->next = NULL;
}
for (i = 0, max = 1;
i < WoodNum;
i++){
j = 0;
while (A + s[j] > N) j++;
//寻找总容量不超过N的第j份
if (j == max) max++;//调整最大分类数max
//以下进行调整
s[j] += A;
selected = j;
Insert(i, j);
//把结果存到链表Result中去。
}
return max < MAXSIZE? max : 0;
}
void Print()
{
int i;
float total;
List *p;
int max = ComputeResult();
//以下是输出结果
if (max == 0)
cout << "Computer max Error!";
else
for (i = 0;
i < max;
i++){
total = 0;
cout << i << " ";
for (p = Result->next;
p != NULL;
p = p->next){
printf ("%2.2f ", A[p->index]);
total += A[p->index];
}
cout << " " << "Waster = " << N - total << endl;
}

for (i = WoodNum;
i < num;
i++)
cout << A << " ";
//这些木材还没被分配,合并计算结果中最差的3组数据用pascal那个求解
}
void main()
{

Create();
Print();
getchar();
}
 
不知道这种方法可行吗? 请建议谢谢!!!
用例子来说吧
定长L为90 现各需要a=40,b=25,c=30,d=15的各1根(如果不是1根,可化为单根的,如有2根40那么数
据为40,40,25,30,15)
现在a,b,c,d任意组合,只要组合的长度不超过定长L的都列出来。
有:
组合方式 组合长度
a+b 65
a+c 70
a+d 55
b+c 55
b+d 40
c+d 45
a+b+d 80
a+c+d 85
b+c+d 70
现按组合长度排序(大->小)
是:
a+c+d 85
a+b+d 80
a+c 70
b+c+d 70
a+b 65
a+d 55
b+c 55
c+d 45
b+d 40
再加上所有的单根(由大->小
a+c+d 85
a+b+d 80
a+c 70
b+c+d 70
a+b 65
a+d 55
b+c 55
c+d 45
b+d 40
a 40
c 30
b 25
d 15
根据上面这一组数据求出所有可能的答案:
从第一个a+c+d 开始,往下面查找,只要各个组合方式中不含a,b,c的就是解有:
a+c+d
b
(找到B后再往下查各个组合方式中不含a,b,c,d的,以下同)
需要根数为2根,接着第二个a+b+d,从当前位置往下查各个组合方式,不含有a,b,d的
a+b+d
c
接着第三个有:
a+c
b+d
第四个是:
b+c+d
a
第五个有:
a+b
c+d
第六个是
a+d
b+d
上面的六组解,每组解都需要原材料为2根。
接着第七个有:
b+c
a
d
从这组解开始,需要的是三根原材料,比上面的都要多出一根,故从这个开始算,下面的肯定不是最优
解。
因些最优解应该只能从上面六种中选出一种。
不知上面分析有没有错。
如果没有错,那么编程来实现应该是没什么问题的吧。。
 

看来没什么最最最好,优的办法喽。。。。。
看来得结帐了。。。
看来大家都有分了。。。呵
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
927
SUNSTONE的Delphi笔记
S
D
回复
0
查看
739
DelphiTeacher的专栏
D
D
回复
0
查看
742
DelphiTeacher的专栏
D
D
回复
0
查看
590
DelphiTeacher的专栏
D
顶部