贪婪法——————贪心算法

华信清明节放假,所以不用去上课,而我又不想出去,所以就用了一点时间去研究算法。

我今天开始看王晓华写的《算法的乐趣》,把它当做教材。

看到贪心算法,因为大一的时候C语言没学好,所以作者写的C实现代码不是看得很懂,但是基本思想还是能够掌握的。


接下来我总结一下我今天学到的贪心算法:

贪心算法是寻找最优解问题的常用方法。

基本思想是分三个步骤:

1.建立对问题精确描述的数学模型,包货定义最优解的模型。

2.将问题分成一系列的子问题,同时定义子问题的最优解结构。

3.应用贪心算法原则可以确定每个子问题的局部最优解,并根据最优解模型,用子问题的局部最优解堆叠出全局最优解。


然后我用java实现了书上贪婪法的例子:0-1背包问题

这是贪婪法的一个经典案例,有N件物品和一个承重C的背包,每件物品重量wi,价值pi,求解将那几件物品放入背包价值最大而又不超过负重。

书上举了一个例子:物品重量{35,30,60,50,40,10,25}

物品价值{10,40,30,50,35,40,30}

策略一:取最小重量的包负重140,价值155

策略二:取最大价值的包负重130,价值165

策略三:取价值密度最大的包负重150,价值170

然后作者给了C语言的策略一的实现方法。


我不太看得懂C,但是我看了几次作者的思想,自己渐渐也有点思路了。

于是我就用java自己实现了贪心算法,其中策略三这里卡了有半个小时了,原因是算法出了问题。

算法这一块还是有一定难度的,特别考验逻辑思维。

我觉得一个算法只要知道了思想,接下来实现的话,无论用C还是用java,都是一样的,《数学之美》作者吴军提到过文字只是一种载体,本质是要传达一种信息思想,中文、英文甚至是机器语言都是一样的,其中不一样的只是编码方式的不同而已。


接下来是我实现的代码,代码这一块,小小的算法也搞了我两个多小时,理清的逻辑,思路就清晰了。

其中遇到最大的问题是:我再取价值密度最大的物品的时候,最后一个价值密度最大的物品加上后就超出了负重,所以跳出了循环,死活加不上那个35负重的包,那里就卡了我将近半个小时,还有一个地方卡了我20分钟,就是float转型的问题,我要定义一个float型的价值密度数据,然后比较,还要重新创建一个比较函数,还要再执行逻辑语句的时候强转,还好我思路比较清晰,不然就晕头转向,解决不了问题了。

哈哈,我自己解决了不少问题,看来我还是挺聪明的嘛偷笑


好了不废话了,下面是我的测试图:



上面那一张是由测试输出的图,下面的是没有的:



这也是我头一次听说价值密度这个概念。。。。。。。。

下面是我用java实现的代码:

分为三个类:先是主类

package 贪心算法;

import java.util.ArrayList;
import java.util.Vector;

public class Greedy {
	
		//有7个包:重量{35,30,60,50,40,10,25}
		//7个包的:价值{10,40,30,50,35,40,30}
	public static int[] strWeight = {35,30,60,50,40,10,25};
	public static int[] strValue = {10,40,30,50,35,40,30};
	
	public static void main(String[] args) {
		Greedy gd = new Greedy();
		gd.initGreedy();
	}
	public void initGreedy(){
		Choice.minWeight();
		Choice.maxValue();
		Choice.maxValueOFWeight();
	}
}
算法实现类:

package 贪心算法;

import java.util.ArrayList;

import javax.swing.plaf.synth.SynthSpinnerUI;

public class Choice {
	public static final int biggestWeight = 150;
	public static void minWeight(){//选择重量最少的包
		int weight = 0;
		int value = 0;
		ArrayList weightList = new ArrayList();
		ArrayList valueList = new ArrayList();
		for(int i=0;i<Greedy.strValue.length;i++){
			weightList.add(Greedy.strWeight[i]);
			valueList.add(Greedy.strValue[i]);
		}
		
		while(true){
			int index = Tool.getMix(weightList);
			//判断总重量小于150且加后的重量小于150
			if( weight<=biggestWeight&&(weight+(int)weightList.get(index))<=biggestWeight ){
				weight = weight + (int)weightList.get(index);
				value = value + (int)valueList.get(index);
				weightList.remove(index);
				valueList.remove(index);
			}else{
				break;
			}
		}
		System.out.println("贪心算法策略一:取最小重量的包:");
		System.out.println("可以载重:"+weight);
		System.out.println("价值:"+value);
	}
	
	public static void maxValue(){//选择价值最大的包
		int weight = 0;
		int value = 0;
		ArrayList weightList = new ArrayList();
		ArrayList valueList = new ArrayList();
		for(int i=0;i<Greedy.strValue.length;i++){
			weightList.add(Greedy.strWeight[i]);
			valueList.add(Greedy.strValue[i]);
		}
		
		while(true){
			int index = Tool.getMax(valueList);
			if( weight<=biggestWeight && ((int)weightList.get(index)+weight)<=biggestWeight ){
				weight = weight + (int)weightList.get(index);
				value = value + (int)valueList.get(index);
				weightList.remove(index);
				valueList.remove(index);
			}else{
				break;
			}
		}
		System.out.println("贪心算法策略二:取最大价值的包");
		System.out.println("可以载重:"+weight);
		System.out.println("价值:"+value);
	}
	
	public static void maxValueOFWeight(){//选择价值密度最大的包
		int weight = 0;
		int value = 0;
		ArrayList weightList = new ArrayList();
		ArrayList valueList = new ArrayList();
		ArrayList theMaxValueOfWeight = new ArrayList();
		for(int i=0;i<Greedy.strValue.length;i++){
			weightList.add((float)Greedy.strWeight[i]);
			valueList.add((float)Greedy.strValue[i]);
			float v = (float)valueList.get(i)/(float)weightList.get(i);
			theMaxValueOfWeight.add(v);
			weightList.set(i, (int)Greedy.strWeight[i]);
			valueList.set(i, (int)Greedy.strValue[i]);
		}
		
		while(true){
			int index = Tool.getfloatListMax(theMaxValueOfWeight);
//			System.out.print("{");
//			for(int i=0;i<theMaxValueOfWeight.size();i++){
//				System.out.print(theMaxValueOfWeight.get(i)+":"+weightList.get(i)+"  ");
//			}
//			System.out.print("}");
//			System.out.println(index);
			if( weight<=biggestWeight && (weight+(int)weightList.get(index))<=biggestWeight ){
				weight = (int)(weight + (int)weightList.get(index));
				value =  (int)(value + (int)valueList.get(index));
				weightList.remove(index);
				valueList.remove(index);
				theMaxValueOfWeight.remove(index);
			}else{
				break;
			}
		}
		for(int i=0;i<theMaxValueOfWeight.size();i++){
			if( weight<=biggestWeight && weight+(int)weightList.get(i)<=biggestWeight ){
				weight = (int)(weight + (int)weightList.get(i));
				value =  (int)(value + (int)valueList.get(i));
				weightList.remove(i);
				valueList.remove(i);
				theMaxValueOfWeight.remove(i);
			}
		}
		System.out.println("贪心算法策略三:取价值密度最大的包");
		System.out.println("可以载重:"+weight);
		System.out.println("价值:"+value);
	}
}

最后一个是工具类:

package 贪心算法;

import java.util.ArrayList;

public class Tool {
	public static int getMix(ArrayList list){//获取队列中的最小值
		int index = 0;
		for(int i=0;i<list.size();i++){
			if( (int)list.get(i)<(int)list.get(index) ){
				index = i;
			}
		}
		return index;
	}
	public static int getMax(ArrayList list){//获取队列中的最大值
		int index = 0;
		for(int i=0;i<list.size();i++){
			if( (int)list.get(i)>(int)list.get(index) ){
				index = i;
			}
		}
		return index;
	}
	
	public static int getfloatListMax(ArrayList list){//获取队列中的最大值
		int index = 0;
		for(int i=0;i<list.size();i++){
			if( (float)list.get(i)>(float)list.get(index) ){
				index = i;
			}
		}
		return index;
	}
}

一步一个脚印,慢慢来。 再见

  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值