这个代码并不好!我写这个主要是理清思路。如果要具体明白算法,可以参考《算法设计与分析》181页和《计算机算法设计与分析》138页,
#include <stdio.h>
#include <stdlib.h>
#define n 5
#define M 50
typedef struct
{
float w;
float p;
float v;
}OBJECT;
OBJECT ob[n];
//int x[n];
//int y[n]={0,0,0,0,0};
int PP[n]={-1,-1,-1,-1,-1};
float p_est;
float p_total;
float w_cur;
float p_cur;
void sort_v(OBJECT* ob)
{
float t_v;
float t_w;
float t_p;
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
if(ob[i].v<ob[j].v)
{
t_v=ob[i].v;
ob[i].v=ob[j].v;
ob[j].v=t_v;
t_w=ob[i].w;
ob[i].w=ob[j].w;
ob[j].w=t_w;
t_p=ob[i].p;
ob[i].p=ob[j].p;
ob[j].p=t_p;
}
}
}
for(int t=0; t<n;t++)
{
printf(“%f\n”,ob[t].v);
}
}
void main()
{
//初始化
float w[n]={5,15,25,27,30};
float p[n]={12,30,44,46,50};
for(int l=0;l<n;l++)
{
ob[l].w=w[l];
ob[l].p=p[l];
ob[l].v=p[l]/w[l];
}
//排序
sort_v(ob);
int k=0;
p_total=0;
w_cur=0;
p_cur=0;
p_est=0;
while(k>=0)
{
while(1)
{
if(k==n)
{
if(p_cur>p_total)
{
p_total=p_cur;
for(int v=0;v<n;v++)
{
printf(“%d\t”,PP[v]);
}
printf(“%f\n”,p_total);
}
k++;
}
if(w_cur+ob[k].w<=M&& k<n)
{
w_cur=w_cur+ob[k].w;
p_cur=p_cur+ob[k].p;
PP[k]=1;
k++;
break;
}
else
{
if(w_cur+ob[k].w>M && k<n)
{
p_est=p_cur+(M-w_cur)*ob[k].v;
PP[k]=0;
k++;
break;
}
}
break;
}
//回溯——开始
while(k>n)
{
for(int l=n-1;PP[l]!=1;l–)
{
PP[l]=-1;
}
PP[l]=0;
if(l==0) exit(0);
p_cur=p_cur-ob[l].p;
w_cur=w_cur-ob[l].w;
k=l+1;
}
}
}
下面是《算法设计与分析》的代码:::
#define M …… //自己定义
#define n ……
typedef struct
{
float w; //重量
float p; //价值
float v; //价值重量比
}OBJECT;
OBJECT ob[n];
int x[n]; //可能的解向量
int y[n]; //当前搜索的解 //别忘了开辟空间 malloc(), new.
float p_est; //最大价值量的估计
float p_total; //上界
float w_cur; //总重量
float p_cur; //总价值
float knapsack_back( OBJECT ob[],float M,int n,BOOL x[])
{
int i,k;
float w_cur,p_total,p_cur,w_est,p_est;
BOOL *y=new BOOL[n];
for (i=0;i<=n;i++)
{
ob[i]].v=ob[i].p/ob[i].w;
y[i]=FALSE;
}
merge_sort(ob,n);
k=0;
while (k>=0)
{
w_est=w_cur;
p_est=p_cur;
for(i=k;i<n;i++)
{
w_est=w_est+ob[i].w;
if(w_est<M)
p_est=p_est+ob[ i].p;
else
{
p_est=p_est+((M-w_est+ob[i].w)/ob[i].w)*ob[i].p;
break;
}
}
if(p_est>p_total)
{
for(i=k;i<n;i++)
{
if(w_cur+ob[i].w<=M)
{
w_cur=w_cur+ob[i].w;
p_cur=p_cur+ob[i].p;
y[i]=TRUE;
}
else
{
y[i]=FALSE;
break;
}
}
if(i>=n)
{
if(p_cur>p_total)
{
p_total=p_cur;
k=n;
for(i=0;i<n;i++)
x[i]=y[i];
}
}
else k=i+1;
}
else
{
while((i>=0)&&(!y[i]))
i=i-1;
if(i<0) break;
else
{
w_cur=w_cur-ob[i].w;
p_cur=p_cur-ob[i].p;
y[i]=FALSE;
k=i+1;
}
}
}
delete y;
return p_total;
}
还有一个比较典型的代码::::
参考迭代回溯::http://blog.csdn.net/liufeng_king/article/details/8762073
- #include “stdafx.h”
- #include <iostream>
- using namespace std;
- template<class Type>
- Type MaxLoading(Type w[ ], Type c, int n, int bestx[ ]);
- int main()
- {
- int n=3,m;
- int c=50,c2=50;
- int w[4]={0,10,40,40};
- int bestx[4];
- m=MaxLoading(w, c, n, bestx);
- cout<<“轮船的载重量分别为:”<<endl;
- cout<<“c(1)=”<<c<<“,c(2)=”<<c2<<endl;
- cout<<“待装集装箱重量分别为:”<<endl;
- cout<<“w(i)=”;
- for (int i=1;i<=n;i++)
- {
- cout<<w[i]<<” “;
- }
- cout<<endl;
- cout<<“回溯选择结果为:”<<endl;
- cout<<“m(1)=”<<m<<endl;
- cout<<“x(i)=”;
- for (int i=1;i<=n;i++)
- {
- cout<<bestx[i]<<” “;
- }
- cout<<endl;
- int m2=0;
- for (int j=1;j<=n;j++)
- {
- m2=m2+w[j]*(1-bestx[j]);
- }
- cout<<“m(2)=”<<m2<<endl;
- if(m2>c2)
- {
- cout<<“因为m(2)大于c(2),所以原问题无解!”<<endl;
- }
- return 0;
- }
- template <class Type>
- Type MaxLoading(Type w[],Type c,int n,int bestx[])//迭代回溯法,返回最优载重量及其相应解,初始化根结点
- {
- int i=1;//当前层,x[1:i-1]为当前路径
- int *x=new int[n+1];
- Type bestw=0, //当前最优载重量
- cw=0, //当前载重量
- r=0; //剩余集装箱重量
- for (int j=1;j<=n;j++)
- {
- r+=w[j];
- }
- while(true)//搜索子树
- {
- while(i<=n &&cw+w[i]<=c)//进入左子树
- {
- r-=w[i];
- cw+=w[i];
- x[i]=1;
- i++;
- }
- if (i>n)//到达叶结点
- {
- for (int j=1;j<=n;j++)
- {
- bestx[j]=x[j];
- }
- bestw=cw;
- }
- else//进入右子树
- {
- r-=w[i];
- x[i]=0; i++;
- }
- while (cw+r<=bestw)
- { //剪枝回溯
- i–;
- while (i>0 && !x[i])
- {
- r+=w[i];
- i–;
- }
- //从右子树返回
- if (i==0)
- {
- delete []x;
- return bestw;
- }
- x[i]=0;
- cw-=w[i];
- i++;
- }
- }
- }