贪心方法知识总结

定义

是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。

例子

TSP问题设计题

在这里插入图片描述
在这里插入图片描述
贪心算法简介
贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。

贪心算法应用于TSP问题
贪心算法是一种算法策略,或者说问题求解的策略。基本思想是“今朝有酒今朝醉”。即一定要做当前情况下的最好选择,否则将来可能后悔,故名“贪心”。
将贪心算法应用于TSP问题中的求解思想:从某一个城市开始,每次选择一个城市,知道所有城市都被走完。注:每次在选择下一个城市的时候,只考虑当前情况,保证迄今为止经过的路径的总距离最短。

/*
外层循环:从i=1开始循环,i小于n, 初始化最短距离为10000(取一个大值,使其至少大于城市距离矩阵中的最大值)。即首先求出第1次将要访问的城市代号(利用中层循环及内层循环求解),然后将求出的第1次将要访问的城市代号j赋值给City[1],并将当前城市(代号0)至代号为j的城市的距离Dtmp累加至Sum。直至求出第n-1次要访问的城市代号。
中层循环:从k=1开始循环,k小于n,初始化Found的值为0。即先假设第i次要访问的城市代号为1,并判断代号为1的城市有没有出现在前几次访问过的城市中(利用内层循环判断),如果代号为1的城市没有出现在已经访问过的城市中并且当前城市(代号i-1)至代号为1的城市的距离小于Dtmp,那就把k=1的值赋值给j,再把当前城市(代号i-1)至代号为1的城市的距离赋值给Dtmp。直至循环到代号为n-1的城市,这样就能根据局部最短距离求出下一个城市的代号i与距离Dtmp。
内层循环:从l=0开始循环,l小于i,判断第l次访问过的城市代号是否与k的值相等,如果相等,代表第l次已经访问过代号为k的城市了,那么就将Found值置1,跳出循环。直至判断完第i-1次访问过的城市。
*/
#include <stdio.h>
#define n 4

int main(void) {
	int Dis[n][n], City[n], Sum, i, j, k, l, Dtmp, Found;
	City[0] = 0;
	Sum = 0;
	Dis[0][1] = 2; Dis[0][2] = 1; Dis[0][3] = 5; Dis[1][0] = 2; Dis[1][2] = 4;
	Dis[1][3] = 4; Dis[2][0] = 1; Dis[2][1] = 4; Dis[2][3] = 6; Dis[3][0] = 5;
	Dis[3][1] = 4; Dis[3][2] = 6;

	for (i = 1; i < n; i++) {
		Dtmp = 10000;                    
		for (k = 1; k < n; k++) {
			Found = 0;
			for (l = 0; l < i; l++) {
				if (City[l] == k) {
					Found = 1;
					break;
				}
			}
			if (Found == 0 && Dis[City[i - 1]][k] < Dtmp) {
				j = k;
				Dtmp = Dis[City[i - 1]][k];
			}
		}
		City[i] = j;
		Sum = Sum + Dtmp;
	}

	Sum = Sum + Dis[j][0];
	for (i = 0; i < n; i++) {
		printf("%d\t", City[i]);
	}
	printf("\n");
	printf("Sum = %d", Sum);

	getchar();
}

一般背包问题

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

带期限的作业排序问题

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

定理5.2证明

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

定理5.3的证明

在这里插入图片描述
在这里插入图片描述

#include <iostream>

using namespace std;

/*D(1),…,D(n)是期限值。n≥1。作业已按p1≥p2≥…≥pn的顺序排序。
J(i)是最优解中的第i个作业,1≤i≤k。
终止时, D(J(i))≤D(J(i+1)), 1≤i<k
*/
void JS(int d[], int J[], int n, int &k)
{
	int i, j, r;
	d[0] = J[0] = 0;
	k = 1;
	J[1] = 1;
	for (i = 2; i <= n; i++)
	{
		r = k;
		while (d[J[r]] > d[i] && d[J[r]] != r)
			r--;
		if (d[J[r]] <= d[i] && d[i] > r)
		{
			for (j = k; j > r; j--)
				J[j + 1] = J[j];
			J[r + 1] = i;
			k++;
		}
	}
}
int main()
{
	int d[5] = { 0,2,1,2,1 };
	int p[5] = { 0,100,20,15,10 };//已经按p值降序排才行哦!!!快排整一个
	int J[5] = { 0 };
	int k;
	JS(d, J, 4, k);
	for (int i = 1; i <= k; i++)
		printf("%d-%d-%d  ", p[J[i]], d[J[i]], J[i]);
	return 0;
}

在这里插入图片描述

利用并查集实现的作业排序

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

贪心的特点

在这里插入图片描述

贪心的核心

在这里插入图片描述

定理5.1证明

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

贪心方法的总结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值