【資料結構與演算法】貪心演算法解決揹包問題。java程式碼實現
阿新 • • 發佈:2018-11-27
揹包問題(貪心演算法)
貪心演算法思想
簡單的說,就是將大問題轉化為最優子問題,例如本題所要求的,揹包容量有限,要想使物品的總價值最高,那麼,我們必須儘可能的選擇權重高的(即單位價值更高)的物品進行裝載。
在揹包問題中,物品是可拆的,即可以分成任意部分進行裝載,而最終實現的目標是,揹包是滿的(即剩餘容量為0),且總價值儘可能高。這也就是揹包問題與0-1揹包的根本差別所在。
解題思想
- 先將所有物品的權重進行排序(可以使用任何排序方法)
- 從權重最高的進行裝載(如果裝得下)
- 權重較高的裝載成功後,包的最大剩餘容量也隨之變化,即減去上一物品的容量
- 繼續重複2,3操作
- 直到最大剩餘容量小於當前物品的重量,則將物品拆分成當前最大剩餘容量
- 計算總價值以及各部分裝載重量
程式碼如下:
public static void bG(Bag[] p,int k,int w,double v)
{
for(int i=k; i < p.length; i++){
if(p[i].weight<=w)
{
v=v+p[i].value;
System.out.println(p[i].pid+"全部裝入,當前揹包價值為"+v) ;
w=w-p[i].weight;
}else{
double a=w*p[i].wi;//當前價值
v=v+a;
System.out.println(p[i].pid+"裝入了"+((double)w/p[i].weight)+",當前揹包價值為"+v);
}
}
}
完整程式碼實現如下
import java.util.Scanner;
class Bag
{
public int weight; //重量
public int value;//價值
public double wi;//權重
public String pid;//揹包名稱
public Bag(int w,int v,String pid)
{
this.weight=w;
this.value=v;
this.pid=pid;
this.wi=(double)value/weight;
}
}
public class bagGreed
{
//選擇排序將陣列中的bag按權重排序(使用了選擇排序)
public static void sort(Bag[] p)
{
Bag t;
for(int i=0;i<p.length;i++)
{
int max=i;
t=p[i];
for(int j=i;j<p.length;j++)
{
if(t.wi<p[j].wi)
{
t=p[j];
max=j;
}
}
t=p[i];
p[i]=p[max];
p[max]=t;
}
}
//演算法核心
public static void bG(Bag[] p,int k,int w,double v)
{
for(int i=k; i < p.length; i++){
if(p[i].weight<=w)
{
v=v+p[i].value;
System.out.println(p[i].pid+"全部裝入,當前揹包價值為"+v);
w=w-p[i].weight;
}else{
double a=w*p[i].wi;//當前價值
v=v+a;
System.out.println(p[i].pid+"裝入了"+((double)w/p[i].weight)+",當前揹包價值為"+v);
}
}
}
public static void main(String args[])
{
System.out.println("請輸入揹包的容量w和物品的個數n");
Scanner reader = new Scanner(System.in);
int w=reader.nextInt();//揹包的容量
int n=reader.nextInt();//物品的個數
Bag[] p=new Bag[n];
//10 10 a 10 10 b 10 15 c
System.out.println("請依次輸入各個物品的重量w和價值v和名稱s");
int weigth;
int value;
String pid;
for(int i=0;i<n;i++)
{
weigth=reader.nextInt();
value=reader.nextInt();
pid=reader.next();
p[i]=new Bag(weigth,value,pid);
}
sort(p);
System.out.println("各物品的權重為:");
for(int i=0;i<n;i++)
{
System.out.println(p[i].wi+" "+p[i].pid);
}
bG(p,0,w,0.0);
}
}