鸡的选择问题--回溯法

来源:互联网 发布:ug8.0编程实例 编辑:程序博客网 时间:2024/04/27 18:44
#include <iostream>using namespace std;class farm{    friend void compute(int [],int [],int ,int);     private:    void Backtrack(int i);    bool Bound(int i);    int  n;//总的鸡的个数    int *x;//当前解    int *bestx;//当前最优解    int *w;//鸡的重量的数组    int *v;//鸡的产蛋量的数组    int bestv;//当前最优产蛋量    int cv;//当前产蛋量    int cw;//当前重量    int c;//最大载重};void farm::Backtrack(int i){     if(i>n)     {         if(cv>bestv)         {             for(int j=1;j<n;j++)             {                 bestx[j]=x[j];                 bestv=cv;             }         }         return ;     }     if(cw+w[i]<=c)     {         x[i]=1;         cw+=w[i];         cv+=v[i];         Backtrack(i+1);         cv-=v[i];         cw-=w[i];     }     if(Bound(i+1)>bestv)     {         x[i]=0;         Backtrack(i+1);     }}bool farm::Bound(int i){    int b=cv;    while(i<=n)    {        b+=v[i];        i++;    }    if(b>bestv)//满足上界函数,则进入右子树    {       return true;    }    return false;}void compute(int w[],int v[],int c,int n){    farm f;    f.n=n;    f.c=c;    f.cv=0;    f.cw=0;    f.x=new int[f.n+1];    f.bestx=f.x;    f.bestv=0;    f.w=w;    f.v=v;    f.Backtrack(1);    cout<<"最大产蛋量为:";    cout<<f.bestv<<endl;    cout<<"所选鸡为:";    for(int i=1;i<=f.n;i++)    {        cout<<f.bestx[i]<<' ';    }    delete[] f.x;}int main(){        //int w[]={3,5,2,1};        //int v[]={9,10,7,4};        int n,c;        cout<<"请输入总鸡数 n: ";        cin>>n;        cout<<"请输入总载重量 c: ";        cin>>c;        int *w=new int[n+1];        int *v=new int[n+1];         cout<<"请输入鸡的重量:";        for(int i=1;i<n+1;i++)        {            cin>>w[i];        }        cout<<"请输入鸡的产蛋量";        for(int i=1;i<n+1;i++)        {            cin>>v[i];        }        compute(w,v,c,n);    return 0;}

注意回溯法的特征鸡的选择问题中,约束函数为:所选鸡的总重量不超过卡车的最大载重量 ;上界函数为Bound(int i) :若将已经选择的鸡和剩下的鸡的所有产蛋量相加还小于当前最有产蛋量,则直接删除右子树。