実験2:欲張りアルゴリズム
- 今夜、欲張りアルゴリズムの実験を始めました。新入生の夏休みに連絡を取りました。基本的な考え方は、全体的な最適を考えるのではなく、局所的な最適の観点から問題を解決することです。
- それでは質問をしましょう
- 問題は、バックパックの総容量を指定してから、アイテムの重量と値を個別に指定することです。アイテムは任意のサイズに分割でき、バックパック内のアイテムの合計値は最大である必要があります。合計値を見つけます。
- **ソリューションのアイデア:
- 入力:最初の行にバックパックの容量mとアイテム数nを入力し、次のn行にn個のバックパックの容量と合計値を入力します。
- 解決策:ステップ1:r []、j []配列の数値を除算して、これらのn個のバックパックの単価を取得し、それらをa []に入れて、次のようにします。
- 自分のコードと教師のコードの実行結果が異なるのはなぜですか???
- **!!!**実験要件は分解可能なナップサック問題ですが、実験コードは0-1ナップサック問題のコードを示しており、自分で書いたコードも正しいです。0-1バックパック問題はもっと難しいようです。
- ここに、分解可能な0-1ナップサック問題のアイデアがあります。可能な並べ替えは、このオブジェクトの接続容量と合計価格を単価に応じて高いものから低いものへと並べ替える必要があるため、バブル並べ替えは時間の複雑さをもたらします高い。
- ステップ1:単価、接続容量、このオブジェクトの合計価格に応じて並べ替えます
- step2:whileループでは、現在のバックパック容量current> = 0を制限条件としてループします。ループ内では、総利益がオブジェクトの値に直接追加されます。サイクルが満たされない場合、合計の利益がcurrent * j [i]に追加されます。すべてのオブジェクトがバックパックに入れられ、まだいっぱいになっていない場合は、壊れます。
- コードは次のように表示されます。
在这里插入代码片
#include <stdio.h>//可分解的背包问题
int main(){
double r[1000],j[1000],a[1000];
int n;
double m,t,Q=0;
scanf("%d%lf",&n,&m);
for(int i=0;i<n;i++)
scanf("%lf%lf",r+i,j+i);
for(int i=0;i<n;i++)
a[i]=j[i]/r[i];
for(int i=0;i<n-1;i++){
for(int k=0;k<n-i-1;k++){
if(a[k]<a[k+1]){
t=a[k];a[k]=a[k+1];a[k+1]=t;
t=r[k];r[k]=r[k+1];r[k+1]=t;
t=j[k];j[k]=j[k+1];j[k+1]=t;
}
//printf("%lf %lf %lf \n",a[k],r[k],j[k]);
}
}
double current=m;
// for(int i=0;i<n;i++)
// printf("%.2lf %.2lf %.2lf \n",a[i],r[i],j[i]);
int i=0,b=0;
while(current-r[i]>=0){
current=current-r[i];
Q+=j[i];//printf("%.2lf\t",Q);
if(i==n-1){
b=1;
break;
}
i++;
}
if(b==0)
Q+=current*a[i];
printf("%.2lf\n",Q);
}
/*测试样例
7 150
35 10
30 40
60 30
50 50
40 35
10 40
25 30
结果为190.63
*/
- OK!!!最初に3つ実験してください