算法——贪心算法

集合覆盖问题、旅行商问题等都属于NP完全问题,在数学领域上并没有快速得到最优解的方案,非常适合用贪婪算法。

判断方法:1.元素较少时,一般运行速度很快,但随着元素数量增多,速度会变得非常慢 2.涉及到需要计算比较"所有的组合"情况的通常是NP完全问题 3.无法分割成小问题,必须考虑各种可能的情况。这可能是NP完全问题 4.如果问题涉及序列(如旅行商问题中的城市序列)且难以解决,它可能就是NP完全问题 5.如果问题涉及集合(如广播台集合)且难以解决,它可能就是NP完全问题 6.如果问题可转换为集合覆盖问题或旅行商问题,那它肯定是NP完全问题

 

总结:

1.贪婪算法可以寻找局部最优解,并尝试与这种方式获得全局最优解

2.得到的可能是近似最优解,但也可能便是最优解(区间调度问题,最短路径问题(广度优先、狄克斯特拉))

3.对于完全NP问题,目前并没有快速得到最优解的解决方案

4.面临NP完全问题,最佳的做法就是使用近似算法

5.贪婪算法(近似算法)在大部分情况下易于实现,并且效率不错


例题:

1.选择和目标覆盖城市交集最多的电台

2. 去除交集后生成新的目标覆盖城市,再重新进行1

/**
 * 贪婪算法 - 集合覆盖问题
 * @author Administrator
 *
 */
public class Greedy {
	
	public static void main(String[] args){
		//初始化广播台信息
		HashMap<String,HashSet<String>> broadcasts = new HashMap<String,HashSet<String>>();
		broadcasts.put("K1", new HashSet(Arrays.asList(new String[] {"ID","NV","UT"})));
		broadcasts.put("K2", new HashSet(Arrays.asList(new String[] {"WA","ID","MT"})));
		broadcasts.put("K3", new HashSet(Arrays.asList(new String[] {"OR","NV","CA"})));
		broadcasts.put("K4", new HashSet(Arrays.asList(new String[] {"NV","UT"})));
		broadcasts.put("K5", new HashSet(Arrays.asList(new String[] {"CA","AZ"})));
 
		//需要覆盖的全部地区
		HashSet<String> allAreas = new HashSet(Arrays.asList(new String[] {"ID","NV","UT","WA","MT","OR","CA","AZ"}));
		//所选择的广播台列表
		List<String> selects = new ArrayList<String>();
		
		HashSet<String> tempSet = new HashSet<String>();
		String maxKey = null;
		while(allAreas.size()!=0) {
			maxKey = null;
			for(String key : broadcasts.keySet()) {
				tempSet.clear();
				HashSet<String> areas = broadcasts.get(key);
				tempSet.addAll(areas);
				//求出2个集合的交集,此时tempSet会被赋值为交集的内容,所以使用临时变量
				tempSet.retainAll(allAreas);
				//如果该集合包含的地区数量比原本的集合多
				if (tempSet.size()>0 && (maxKey == null || tempSet.size() > broadcasts.get(maxKey).size())) {
					maxKey = key;
				}
			}
			
			if (maxKey != null) {
				selects.add(maxKey);
				allAreas.removeAll(broadcasts.get(maxKey));
			}
		}
		System.out.print("selects:" + selects);
 
	}
}
复制代码

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值