贪心算法经典问题:活动安排,背包问题,最优装载,单源最短路径 Dijiksra,找零钱问题,多机调度

合集下载

JS基于贪心算法解决背包问题示例

JS基于贪心算法解决背包问题示例

JS基于贪⼼算法解决背包问题⽰例本⽂实例讲述了JS基于贪⼼算法解决背包问题。

分享给⼤家供⼤家参考,具体如下:贪⼼算法:在对问题求解时,总是做出在当前看来是最好的选择。

也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。

寻找最优解的过程,⽬的是得到当前最优解部分背包问题:固定容积的背包能放⼊物品的总最⼤价值物品 A B C D价格 50 220 60 60尺⼨ 5 20 10 12⽐率 10 11 6 5按⽐例降序尽可能多放⼊物品function greedy(values, weights, capacity){var returnValue = 0var remainCapacity = capacityvar sortArray = []values.map((cur, index) =>{sortArray.push({'value': values[index],'weight': weights[index],'ratio': values[index]/weights[index]})})sortArray.sort(function(a, b){return b.ratio > a.ratio})console.log(sortArray)sortArray.map((cur,index) => {var num = parseInt(remainCapacity/cur.weight)console.log(num)remainCapacity -= num*cur.weightreturnValue += num*cur.value})return returnValue}var items = ['A','B','C','D']var values = [50,220,60,60]var weights = [5,20,10,12]var capacity = 32 //背包容积greedy(values, weights, capacity) // 320更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《》、《》、《》、《》、《》及《》希望本⽂所述对⼤家JavaScript程序设计有所帮助。

2 贪心算法

2 贪心算法

18
2.3 最优装载
有一批集装箱要装上一艘载重量为c的轮船。其中集 装箱i的重量为Wi。最优装载问题要求确定在装载体积不 受限制的情况下,将尽可能多的集装箱装上轮船。
1、算法描述
最优装载问题可用贪心算法求解。采用重量最轻者先 装的贪心选择策略,可产生最优装载问题的最优解。具体 算法描述如下页。
19
2
2.1 贪心算法概述
贪心算法总是作出在当前看来最好的选择。 也就是说贪心算法并不从整体最优考虑,它所作出 的选择只是在某种意义上的局部最优选择。当然, 希望贪心算法得到的最终结果也是整体最优的。
虽然贪心算法不能对所有问题都得到整体最优 解,但对许多问题它能产生整体最优解, 如单源最 短路经问题、最小生成树问题等。在一些情况下, 即使贪心算法不能得到整体最优解,其最终结果却 是最优解的近似解。
3
2.1.1贪心算法策略
贪心算法采用的是逐步构造最好优解的方法, 即总是作出在当前看来最好的选择。
4
例2.1 付款问题 找零问题。如26.8。 “贪心” 原则:尽量给顾客大面值的钱。 20、5、1、0.5、0.2、0.1 问题描述: 已知:int m[]={500,200,100,50,20,10,5,2,1}; int v; 输出:各种钞票数 int n[9], 使得
Σ n[i]*m[i]=v 且Σn[i]最小。 i=1 i=1
5
9
9
void pay(int m[],int v){ int i,r,n[9]; for(i=0;i<9;i++)n[i]=0; r=v; i=0; while (r>0) { if (m[i]<=r) { r-=m[i]; n[i]++; } else i++; } for(i=0;i<9;i++) 输出n[i]个m[i]面值的钞票。 }

贪心算法之最优装载问题

贪心算法之最优装载问题

贪⼼算法之最优装载问题贪⼼算法之最优装载问题1. 问题描述有⼀批集装箱要装上⼀艘重量为c的轮船,其中集装箱i的重量为W i。

最优装载问题要求确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船。

2. 问题分析2.1确定贪⼼策略采⽤重量最轻者先装的贪⼼选择策略,可产⽣该问题的最优解。

2.2代码求解/*** x[] 保存最优解路径数组* w[] 集装箱重量数组* c 船的载重量* n 集装箱的数量**/void Loading(int x[], int w[], int c, int n) {// 按照集装箱重量从⼩到⼤排序sort(w, n);for (int i = 1; i <= n; i++)x[i] = 0;for (int i = 1; i <= n && w[i] <= c; i++) {x[i] = 1;c -= w[i];}}2.3贪⼼选择性质设集装箱依其重量从⼩到⼤排序,(x1,x2,…,x n)是其最优解,x i={0,1},设x k是第⼀个等于1的。

(1) 如k=1,则满⾜贪⼼选择性质(2) 如k≠1,⽤x1替换x k,构造的新解同原解最优值相同,故也是最优解,满⾜贪⼼选择性质该证明⽅法只证明了任何⼀个最优解都可以转换为第⼀个集装箱上船的最优解(满⾜贪⼼策略)。

此⽅法对⼦问题同样有效,因此可以将⼀个普通最优解转化为满⾜贪⼼策略的最优解。

如(0101)⇒(1100)2.4.最优⼦结构性质最优装载问题具有最优⼦结构性质,设1⾄n个集装箱装上船的最⼤数量为T(1,n,w),则T(1,n,w)=1+T(2,n,w−w1);因T(1,n,w)是最优值,则T(2,n,w−w i)⼀定是最优值,反证法证明之反证法:如果T(2,n,w−w1)不是该问题的最优解,则存在最优值T′(2,n,w−w1)>T(2,n,w−w1),则1+T′(2,n,w−w1)=T′(1,n,w)>T(1,n,w),这与⼤前提T(1,n,w)是最优值相⽭盾,故T(2,n,w−w1)⼀定是最优值。

贪心算法题库

贪心算法题库

贪心算法是一种在每一步选择中都采取当前情况下的局部最优选择,并希望导致结果是全局最优解的算法。

下面是一些贪心算法的题目和解答:1. 旅行商问题(Travelling Salesman Problem):问题描述:给定一个城市列表和一个距离列表,要求找出一条路径,使得路径上的所有城市都经过,且总距离最短。

贪心算法解法:首先对城市按照距离进行排序,然后从最近的两个城市开始,每次都选择距离当前位置最近的两个城市,直到遍历完所有城市。

由于贪心算法每次选择的都是当前情况下的最优解,因此最终得到的路径总距离是最短的。

2. 背包问题(Knapsack Problem):问题描述:给定一组物品,每个物品都有自己的重量和价值,要求在不超过背包总重量的情况下,如何选择物品使得背包中物品的总价值最大。

贪心算法解法:按照物品的重量对物品进行排序,然后每次选择重量最小的物品,直到背包已满或无物品可选。

由于贪心算法每次选择的都是当前情况下的最优解,因此最终得到的方案总是可以找到一个大于等于当前最优解的方案。

3. 网格找零问题(Currency Change Problem):问题描述:给定一组面值不同的硬币,要求用最少的组合方式从一定金额中找零。

贪心算法解法:首先对硬币面值进行排序,然后每次使用当前面值最小的硬币进行组合,直到金额为零或无硬币可选。

贪心算法在此问题中的思路是每次选择最小的硬币进行使用,这样可以保证找零的最小数量。

以上题目和解答只是贪心算法的一部分应用,实际上贪心算法在许多其他领域也有广泛的应用,例如网页布局优化、任务调度、网络流等等。

贪心算法的优势在于其简单易懂、易于实现,但也有其局限性,例如无法处理一些存在冲突的情况或最优解不唯一的问题。

因此在实际应用中需要根据具体问题选择合适的算法。

关于贪心算法的经典问题(算法效率or动态规划)

关于贪心算法的经典问题(算法效率or动态规划)

关于贪⼼算法的经典问题(算法效率or动态规划)如题,贪⼼算法⾪属于提⾼算法效率的⽅法,也常与动态规划的思路相挂钩或⼀同出现。

下⾯介绍⼏个经典贪⼼问题。

(参考⾃刘汝佳著《算法竞赛⼊门经典》)。

P.S.下⽂皆是我⼀个字⼀个字敲出来的,绝对“童叟⽆欺”,哈哈。

(。

⌒∇⌒) 耗费了我的很多时间,所以——希望对⼤家有帮助啊~ (=^‸^=)⼀、背包相关问题1.最优装载问题:给出N个物体,有⼀定重量。

请选择尽量多的物体,使总重量不超过C。

解法:只关⼼数量多,便把重量从⼩到⼤排序,依次选,直到装不下。

2.部分背包问题:给出N个物体,有⼀定重量和价值。

请选择⼀些物体的⼀部分使在总重量不超过C的条件下总价值最⼤。

解法:关⼼总价值⼤,物体可取部分,便优先取单位重量价值较⼤的物体。

3.乘船问题:有N个⼈,有⼀定重量。

每艘船的最⼤载重量均为C,且最多载2⼈。

请⽤最少的船装载所有⼈。

解法:关⼼数量少,要尽量使每艘船的实际载重量尽量接近于最⼤载重量。

便把重量从⼩到⼤排序,每艘船依次先载⼀个⼈,再载重量最接近船的剩余可载重量的⼈。

这样可以使眼前的消费(剩余载重量)最少。

实现:⽤2个变量 l , r 分别从两头往中间移动,l 和 r 可共乘⼀艘船,或 r ⾃⼰乘⼀艘船。

⼆、区间相关问题1.选择不相交区间:数轴上有N个开区间(Li,Ri),请选择尽量多个区间,并保证这些区间两两没有公共点。

解法:先把这些区间按找 Ri 从⼩到⼤的顺序排序,再对按序排列的每2个区间A,B分情况讨论:(1)A被B包含,选A最优;(2)A右边的⼀部分与B左边的⼀部分相交,选A最优,因为选A⽐B减少了与后⾯区间相交的可能性;(3)A、B不相交,便2个都选。

总的来说就是排序后,从左到右选第⼀个没有与前⾯已选的区间相交的区间。

O(n)。

拓展:那么如果可以⼀共覆盖两次,那该怎么选? ——也就是。

2.区间选点问题:数轴上有N个闭区间[Li,Ri],请选择尽量少的点,使得每个区间内都⾄少有⼀个点。

c++贪心算法经典例题

c++贪心算法经典例题

c++贪心算法经典例题摘要:一、贪心算法简介1.贪心算法的定义2.贪心算法的特点3.贪心算法适用的问题类型二、C++贪心算法经典例题1.背包问题a.0-1 背包问题b.完全背包问题c.动态背包问题2.最小生成树a.Kruskal 算法b.Prim 算法3.单源点最短路径a.Dijkstra 算法b.Floyd-Warshall 算法4.最长公共子序列a.贪心算法实现b.动态规划实现正文:一、贪心算法简介贪心算法(Greedy Algorithm)是一种求解最优解的方法。

它是在对问题求解时,总是做出在当前看来是最好的选择。

贪心算法并不追求整体最优解,只希望得到较为满意的解。

贪心算法的关键是贪心策略的选择,必须满足无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。

贪心算法适用的问题类型包括背包问题、最小生成树、单源点最短路径和最长公共子序列等。

二、C++贪心算法经典例题1.背包问题背包问题(Knapsack Problem)是一种典型的贪心算法问题。

它描述的是有一个背包,有一定的容量,需要装载若干物品,每个物品有一定的价值和重量,要求在不超过背包容量的前提下,如何选择装载物品使得背包中的物品总价值最大。

背包问题可以分为0-1 背包问题、完全背包问题和动态背包问题。

2.最小生成树最小生成树(Minimum Spanning Tree,简称MST)是一种图论中的算法问题。

给定一个加权连通图,求解一个生成树,使得该生成树中所有边的权值之和最小。

最小生成树的经典算法有Kruskal 算法和Prim 算法。

3.单源点最短路径单源点最短路径(Single Source Shortest Path)问题是在一个图中,从源点出发到其他所有顶点的最短路径。

经典算法包括Dijkstra 算法和Floyd-Warshall 算法。

4.最长公共子序列最长公共子序列(Longest Common Subsequence,简称LCS)问题是求两个序列中最长的公共子序列。

贪心算法和分支限界法解决单源最短路径

贪⼼算法和分⽀限界法解决单源最短路径单源最短路径计科1班朱润华 2012040732⽅法1:贪⼼算法⼀、贪⼼算法解决单源最短路径问题描述:单源最短路径描述:给定带权有向图G=(V,E),其中每条边的权是⾮负实数。

另外,还给定V中的⼀个顶点,称之为源(origin)。

现在要计算从源到其他各顶点的最短路径的长度。

这⾥的路径长度指的是到达路径各边权值之和。

Dijkstra算法是解决单源最短路径问题的贪⼼算法。

Dijkstra算法的基本思想是:设置顶点集合S并不断地做贪⼼选择来扩充集合。

⼀个顶点属于集合S当且仅当从源点到该顶点的最短路径长度已知。

贪⼼扩充就是不断在集合S中添加新的元素(顶点)。

初始时,集合S中仅含有源(origin)⼀个元素。

设curr是G的某个顶点,把从源到curr 且中间只经过集合S中顶点的路称之为从源到顶点curr的特殊路径,并且使⽤数组distance记录当前每个顶点所对应的最短路径的长度。

Dijkstra算法每次从图G中的(V-S)的集合中选取具有最短路径的顶点curr,并将curr加⼊到集合S中,同时对数组distance 进⾏必要的修改。

⼀旦S包含了所有的V中元素,distance数组就记录了从源(origin)到其他顶点的最短路径长度。

⼆、贪⼼算法思想步骤:Dijkstra算法可描述如下,其中输⼊带权有向图是G=(V,E),V={1,2,…,n},顶点v 是源。

c是⼀个⼆维数组,c[i][j]表⽰边(i,j)的权。

当(i,j)不属于E时,c[i][j]是⼀个⼤数。

dist[i]表⽰当前从源到顶点i的最短特殊路径长度。

在Dijkstra算法中做贪⼼选择时,实际上是考虑当S添加u之后,可能出现⼀条到顶点的新的特殊路,如果这条新特殊路是先经过⽼的S到达顶点u,然后从u经过⼀条边直接到达顶点i,则这种路的最短长度是dist[u]+c[u][i]。

如果dist[u]+c[u][i]1、⽤带权的邻接矩阵c来表⽰带权有向图, c[i][j]表⽰弧上的权值。

最佳装载背包问题--贪心算法

贪心法求解最佳装载背包问题描述:对于容量为c的背包进行装载,从n个物品中选择装入背包的物品,每个物品i的重量和价值分别为wi和pi。

在背包中物品的总重量不超过背包容量的前提下,求装入物品价值最高的装载法。

输入:5 20 //物品的数量和背包的容量6 3 //第一个物品的重量和价值2 5 //…3 810 67 4输出:1110.714286算法如下:#include <stdio.h>#include <stdlib.h>struct goodinfo//物品结构体{float p;//价值float w;//重量float x;//数量int flag;//标志变量};void Insertionsort(struct goodinfo goods[],int n)//将物品根据价值排序{int i,j;for(j=2;j<=n;j++){goods[0]=goods[j];//保存比较的对象i=j-1;while(goods[0].p>goods[i].p)//找到位置后退出{goods[i+1]=goods[i];//错位i--;}goods[i+1]=goods[0];//找到位置后将比较的对象覆盖}}void bag(struct goodinfo goods[],float M,int n){float cu;//剩余空间int i,j;for(i=1;i<=n;i++)goods[i].x=0;//初始化cu=M;//初始化for(i=1;i<=n;i++){if(goods[i].w>cu)break;goods[i].x=1;cu=cu-goods[i].w;}if(i<=n)goods[i].x=cu/goods[i].w;//将物品分割for(j=2;j<=n;j++)//按照物品的编号排序,便于输出goods[0]=goods[j];i=j-1;while(goods[0].flag<goods[i].flag){goods[i+1]=goods[i];i--;}goods[i+1]=goods[0];}printf("最优解为:\n");for(i=1;i<=n;i++){printf("第%d件物品要放:%f\n",i,goods[i].x);}}int main(){int j=1,n,i;float M;while(j)system("cls");printf("输入物品的总数:");scanf("%d",&n);struct goodinfo goods[n+1];//动态定义结构体数组的大小printf("背包最大容量:");scanf("%f",&M);for(i=1;i<=n;i++){goods[i].flag=i;printf("weight input:");scanf("%f",&goods[i].w);printf("price input:");scanf("%f",&goods[i].p);goods[i].p/=goods[i].w;}Insertionsort(goods,n);bag(goods,M,n);printf("press <1> to run again\npress <0> to exit\n请输入操作码:");scanf("%d",&j);}return 0; }。

贪心算法之背包问题

贪⼼算法之背包问题贪⼼算法(⼜称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。

也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。

贪⼼算法不是对所有问题都能得到整体最优解,关键是贪⼼策略的选择,选择的贪⼼策略必须具备⽆后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。

完全背包问题:给定n个物品和⼀个容量为C的背包,物品i的重量是Wi,其价值为Vi,背包问题是如何选择⼊背包的物品,使得装⼊背包的物品的总价值最⼤,与0-1背包的区别是,在完全背包问题中,可以将物品的⼀部分装⼊背包,但不能重复装⼊。

设计算法的思路很简单,计算物品的单位价值,然后尽可能多的将单位重量价值⾼的物品放⼊背包中。

python实现代码如下:1# coding=gbk2# 完全背包问题,贪⼼算法3import time4__author__ = 'ice'567class goods:8def__init__(self, goods_id, weight=0, value=0):9 self.id = goods_id10 self.weight = weight11 self.value = value121314# 不适⽤于0-1背包15def knapsack(capacity=0, goods_set=[]):16# 按单位价值量排序17 goods_set.sort(key=lambda obj: obj.value / obj.weight, reverse=True)18 result = []19for a_goods in goods_set:20if capacity < a_goods.weight:21break22 result.append(a_goods)23 capacity -= a_goods.weight24if len(result) < len(goods_set) and capacity != 0:25 result.append(goods(a_goods.id, capacity, a_goods.value * capacity / a_goods.weight))26return result272829 some_goods = [goods(0, 2, 4), goods(1, 8, 6), goods(2, 5, 3), goods(3, 2, 8), goods(4, 1, 2)]3031 start_time = time.clock()32 res = knapsack(6, some_goods)33 end_time = time.clock()34print('花费时间:' + str(end_time - start_time))3536for obj in res:37print('物品编号:' + str(obj.id) + ' ,放⼊重量:' + str(obj.weight) + ',放⼊的价值:' + str(obj.value), end=',')38print('单位价值量为:' + str(obj.value / obj.weight))394041# 花费时间:2.2807240614677942e-0542# 物品编号:3 ,放⼊重量:2,放⼊的价值:8,单位价值量为:4.043# 物品编号:0 ,放⼊重量:2,放⼊的价值:4,单位价值量为:2.044# 物品编号:4 ,放⼊重量:1,放⼊的价值:2,单位价值量为:2.045# 物品编号:1 ,放⼊重量:1,放⼊的价值:0.75,单位价值量为:0.75。

列举用贪心算法求解的经典问题

列举用贪心算法求解的经典问题
1. 零钱兑换问题:给定一些面值不同的硬币和一个金额,要求用最少的硬币凑出这个金额。

2. 最小生成树问题:给定一个无向带权图,要求用最小的权值构建一棵生成树。

3. 背包问题:给定一些物品和一个背包,每个物品有对应的价值和重量,要求在背包容量限制下,选取物品使得总价值最大。

4. 活动安排问题:有若干个活动需要分配一段时间,每个活动有对应的开始时间和结束时间,要求选取尽可能多的活动,使得任两个安排的活动时间不重叠。

5. 单源最短路径问题:给定一个有向带权图和一个起始节点,要求求出从起始节点到其他所有节点的最短路径。

6. 任务调度问题:有若干个需要完成的任务和多个可执行任务的处理器,要求将任务分配给处理器,使得执行总时间最小。

7. 区间覆盖问题:给定一些区间,要求用尽可能少的区间覆盖整个线段。

8. 哈夫曼编码问题:给定一些字符及其对应的出现概率,要求用最短的编码方式表示这些字符。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

活动安排
public static int greedySelector(int [] s, int [] f, boolean a[])
{ //s[]开始时间f[]结束时间
int n=s.length-1;
a[1]=true;
int j=1;
int count=1;
for (int i=2;i<=n;i++)
{ if (s[i]>=f[j]) { a[i]=true; j=i; count++; }
else a[i]=false;
}
return count;
}
背包问题
void Knapsack(int n,float M,float v[],float w[],float x[])
{ Sort(n,v,w); //以每种物品单位重量的价值Vi/Wi从大到小排序
int i;
for (i=1;i<=n;i++) x[i]=0;
float c=M;
for (i=1;i<=n;i++)
{ if (w[i]>c) break;
x[i]=1;
c-=w[i];
}
if (i<=n) x[i]=c/w[i]; //允许放入一个物品的一部分
}
最优装载
void Loading(int x[], T ype w[], T ype c, int n)
{ int *t = new int [n+1]; //t[i]要存的是w[j]中重量从小到大的数组下标Sort(w, t, n); //按货箱重量排序
for (int i = 1; i <= n; i++) x[i] = 0; //O(n)
for (int i = 1; i <= n && w[t[i]] <= c; i++)
{x[t[i]] = 1; c -= w[t[i]];} //调整剩余空间
}
单源最短路径Dijiksra
template<class Type>
void Dijikstra(int n, int v, Type dist[], int prev[], Type **c)
{ //c[i][j]表示边(i,j)的权,dist[i]表示当前从源到顶点i的最短特殊路径bool s[maxint];
for(int i= 1;i<=n; i++)
{ dist[i]=c[v][i]; s[i]=false;
if(dist[i]==maxint) prev[i]=0;
else prev[i]=v;
}
dist[v]=0 ; s[v]=true;
for(int i=1;i<n;i++)
{ int temp = maxint, u = v;
for(int j= 1;j<=n; j++)
if( (!s[j])&&(dist[j]<temp) ){u= j ; temp=dist[j]; }s[u]= true;
for(int j= 1;j<=n;j++)
if( (!s[j])&&(c[u][j])<maxint)
{ Type newdist = dist[u]+c[u][j];
if(newdist<dist[j]) {dist[j]= newdist; prev[j]=u; } }
}//ENDFOR
}//END
找零钱问题
#define NUM 4
void main()
{ int m[NUM]={25,10,5,1};
int n; //假设n=99
cin>>n;
cout<<n<<"的找钱方案为:";
for(int i=0;i<NUM;i++)
while(n>=m[i]&&n>0)
{cout<<m[i]<<" ";
n-=m[i];
}
}//END
多机调度
#define N 10
#define M 3
void sort(int t[],int n);
int set_work1(int t[],int n);
int max(int t[],int num);
int min(int t[],int m);
int set_work2(int t[],int n);
static int time[N]={2,8,18,32,50,72,98,128,182,200},s[M]={0,0,0};
void main()
{sort(time,N);
if(M>=N) //作业数小于机器数
cout<<set_work1(time,N)<<endl;
else
cout<<set_work2(time,N)<<endl;
}
void sort(int t[],int n)
{for(int k=0;k<n-1;k++) //用选择法将处理时间从大到小排序{int j=k;
for (int i=k; i<n; i++)
if (t[i]>t[j]) j=i;
{int temp=t[j];t[j]=t[k];t[k]=temp;}
}
}
int max(int t[],int num) //max函数求解处理时间总和最长{int max=t[0];
for(int i=1;i<num;i++)
if(max<t[i]) max=t[i];
return max;
}
int min(int t[],int m)
{int min=0; //min记录目前处理作业时间和最小的机器号for(int i=1;i<m;i++)
if(s[min]>s[i]) min=i;
return min;
}
int set_work1(int t[],int n)
{ int m=0;
for(int i=0;i<n;i++) //分派作业
s[m++]+=t[i];
return max(s,N);
}
int set_work2(int t[],int n)
{ for(int i=0;i<n;i++)
s[min(s,M)]+=t[i];
return max(s,M);
}。

相关文档
最新文档