算法设计与分析实验报告-贪心算法

 校课程的简单实验报告。

算法设计与分析实验报告-递归与分治策略

算法设计与分析实验报告-动态规划算法

算法设计与分析实验报告-贪心算法 

        dijkstra迪杰斯特拉算法(邻接表法)

算法设计与分析实验报告-回溯法

算法设计与分析实验报告-分支限界法 

算法设计与分析实验报告-分治法相关练题

北京大学出版社-算法设计与分析


一、实验目的

1.理解贪心算法的概念;

2.掌握贪心算法的基本要素;

3.掌握设计贪心算法的步骤和策略。

二、实验内容

使用贪心法求解以下问题,要求给出程序代码,并编译运行程序:

1.P118习题2。

2.P118习题5。

三、实验环境

1. 使用的操作系统及版本:

Windows 10

2. 使用的编译系统及版本:

CLion 2022.2.4

四、实验步骤及说明

1、P118习题2

对于用邻接链表表示的有向无环图,设计一个解单起点最短路径问题的线性算法。

dijkstra迪杰斯特拉算法(邻接表法)

代码如下:

//
// Created by GiperHsiue on 2022/11/27.
//
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
#define INFINE 99999 // 定义最大
// 邻接表
struct ArcNode // 边信息
{int adjvex; //有向边的 目标顶点 下标(从1开始)int weight; //边的权值struct ArcNode *next; //邻接表, 指向下一个邻接边信息
};
struct VertexNode // 顶点
{int vertex; //顶点下标(1 ~)ArcNode *firstedge; // 有向边信息节点指针(源为vertex)
};
struct AdjList // 图
{vector<VertexNode> adjlist; //顶点数组int vexnum;  //顶点数 int arcnum;  //边数
};
// 图的初始化
void createGraph(AdjList& G){cout << "输入顶点数 边数: " << endl;cin >> G. vexnum >> G. arcnum;// 初始化G的顶点数组for(int i = 0; i <= G. vexnum; i ++){ // 下标从1开始, 所以初始化vexnum + 1个顶点(0无作用)VertexNode* tmp = new VertexNode;tmp->vertex = i, tmp->firstedge = nullptr;G. adjlist. emplace_back(*tmp);}//边信息// n1: 源顶点     n2: 目标顶点   we: 权重(距离)int n1, n2, we;cout << "输入边信息: (a b we): " << endl; // a -> b  weight: wefor(int i = 0; i < G. arcnum; i ++){cin >> n1 >> n2 >> we;// 初始化一个边节点, 目标顶点为n2ArcNode* tmp = new ArcNode;tmp->adjvex = n2, tmp->weight = we;// 头插法 将边信息节点插入// 节约时间(尾插要一直遍历到尾部插入)tmp->next = G. adjlist[n1]. firstedge;G. adjlist[n1]. firstedge = tmp;}
}
// 获取两顶点之间权重weight(距离)
int getWeight(AdjList& G, int n1, int n2){if(n1 == n2) return 0;ArcNode* tmp = G. adjlist[n1]. firstedge;while(tmp){if(tmp->adjvex == n2) return tmp->weight;tmp = tmp->next;}// 两点之间没有边, 返回INFINEreturn INFINE;
}
void Dijkstra(AdjList& G, int ear, vector<int>& prev, vector<int>& dist){// 初始化// flag数组记录 某点是否纳入已找到点集合// prev数组记录 前驱顶点下标// dist数组记录 从源顶点ear 到 i顶点的最短路径vector<bool> flag (G. adjlist. size() + 1, false);for(int i = 1; i <= G. vexnum; i ++) dist[i] = getWeight(G, ear, i), prev[i] = ear;flag[ear] = true, prev[ear] = 0;// 开始for(int i = 2; i <= G. vexnum; i ++){int pos = 1; // 未纳入的距离最小的顶点int weiMin = INFINE;for(int j = 1; j <= G. vexnum; j ++){if(!flag[j] && dist[j] < weiMin){weiMin = dist[j], pos = j;}}flag[pos] = true;for(int j = 1; j <= G. vexnum; j ++){if(!flag[j]){ // 未纳入点集中, 找到pos到这些点的距离, 与dist数组比较是否更新int tmpWei = getWeight(G, pos, j);if(tmpWei != INFINE) tmpWei = tmpWei + weiMin; // 两点距离应该为ear -> pos -> jif(tmpWei < dist[j]) {dist[j] = tmpWei; // 距离更小则更新distprev[j] = pos; // 前顶点更新为pos}}}}
}
// 找路径
void pathDist(vector<int>& prev, vector<int>& dist, int ear){// prev数组中为1有2种情况(djikstra初始化过程的时候全赋值为1, 后续一直未改变):// 1: 从ear到 顶点 只有 ear -> 顶点 这一条路最短// 2: 无法从ear到达的顶点for(int i = 1; i <= prev. size() - 1; i ++){stack<int> trace;if(ear == i) continue;cout << ear << " 到 " << i ;// 无连通if(dist[i] == INFINE) {cout << "无连通" << endl;continue;}cout << "最短距离: " << dist[i] << "  最短路径: ";int tmp = i;while(tmp){ //  源顶点prev是0trace. push(tmp);tmp = prev[tmp];}// 开始出栈, 栈顶一定是ear源顶点cout << trace. top();trace. pop();while(!trace. empty()){cout << " -> " << trace. top();trace. pop();}cout << endl;}
}
int main(){AdjList G;createGraph(G);// prev数组记录 前驱顶点下标vector<int> prev (G. vexnum + 1, 0);// dist数组记录 从源顶点ear 到 i顶点的最短路径vector<int> dist (G. vexnum + 1, INFINE);// 从源点ear 出发, 到达其余所有点的最短路径cout << "输入源顶点ear: ";int ear;cin >> ear;Dijkstra(G, ear, prev, dist);pathDist(prev, dist, ear);return 0;
}

测试如下:

  1. P118习题5 小船过河问题

一群人划船过河,河边只有一条船,这条船可以容纳两个人,船过河后需要一人将船开回,以便所有人都可以过河,每个人过河速度不一样,两个人过河速度取决于慢的那个人,请问最少需要多久让所有人过河?

//
// Created by GiperHsiue on 2022/11/27.
//
// 小船过河问题
#include <iostream>
#include <vector>
using namespace std;
// 归并排序
void mergeSort(vector<int>& num, int l, int r){if(l >= r) return;int mid = l + (r - l) / 2;mergeSort(num, l, mid), mergeSort(num, mid + 1, r);int a = l, b = mid + 1, k = 0;vector<int> tmp (r - l + 1, 0);while(a <= mid && b <= r){if(num[a] <= num[b]) tmp[k++] = num[a++];else tmp[k++] = num[b++];}while(a <= mid) tmp[k++] = num[a++];while (b <= r) tmp[k++] = num[b++];for(int i = 0, j = l; j <= r; i ++, j ++) num[j] = tmp[i];
}
int calTime(vector<int>& num){int cnt = num. size(), res = 0;while(cnt > 3){int tmp1 = num + 2 * num + num[cnt - 1];int tmp2 = 2 * num + num[cnt - 1] + num[cnt - 2];res += min(tmp1, tmp2);cnt -= 2;}if(cnt == 2) res += num;if(cnt == 3) res += num + num + num;return res;
}
int main(){int n;cin >> n;vector<int> people(n, 0);for(auto &x: people) cin >> x;mergeSort(people, 0, n - 1);cout << "过河最少时间: " << calTime(people) << endl;return 0;
}

代码如下:

测试如下:

五、实验小结及思考

通过本次实验对于贪心算法有了进一步的认识与理解,并运用贪心思维解决实际问题,理解贪心算法的概念,掌握贪心算法的基本要素,掌握设计贪心算法的步骤和策略。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/584236.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Fastdeploy学习之路:Examples编译

1. 前置条件&#xff1a; 编译完Fastdeploy SDK & make install > /opt/fd_sdk 2. 进入Examples相关目录&#xff0c;然后执行&#xff1a; mkdir build & cd buildcmake .. -DFASTDEPLOY_INSTALL_DIR/opt/fd_sdk/即可生成&#xff1a; Infer_demo文件 3. 执行…

halcon字符识别结果为“\x1A”

最近在做OCR字符识别&#xff0c;遇到了点小问题&#xff0c;记录一下。 由于是项目初期&#xff0c;所以我就打算调halcon自带库去识别一下看看效果如何&#xff0c;结果分类器的结果显示为“\x1A”。如下图 百度搜了一圈没有这个解答&#xff0c;所以就在halcon帮助文档里…

AtCoder Beginner Contest 334 G

G.Christmas Color Grid 2&#xff08;枚举&#xff0c;Tarjan&#xff09; 题意&#xff1a; 本题与问题 E E E类似。有一个 H H H行和 W W W列的网格&#xff0c;每个单元格都被涂成红色或绿色。用 ( i , j ) (i,j) (i,j)表示从上到下第 i i i行、从左到右第 j j j列的单元…

Docker五 | DockerFile

目录 DockerFile 常用保留字 FROM MAINTAINER RUN EXPOSE WORKDIR USER ENV VOLUME ADD COPY CMD ENTRYPOINT DockerFile案例 前期准备 编写DockerFile文件 运行DockerFile 运行镜像 DockerFile是用来构建Docker镜像的文本文件&#xff0c;是由一条条构建…

JavaScript----数组及操作方法

1. 数组的介绍 数组就是一组数据的集合&#xff0c;javascript 中&#xff0c;数组里面的数据可以是不同类型的数据&#xff0c;好比 python 里面的列表。 2. 数组的定义 // 实例化对象方式创建 var aList new Array(1,2,3);// 字面量方式创建&#xff0c;推荐使用 var aLi…

【LeetCode】修炼之路-0001-Two Sum(两数之和)【python】【简单】

前言 计算机科学作为一门实践性极强的学科,代码能力的培养尤为重要。当前网络上有非常多优秀的前辈分享了LeetCode的最佳算法题解,这对于我们这些初学者来说提供了莫大的帮助,但对于我这种缺乏编程直觉的学习者而言,这往往难以消化吸收。&#xff08;为什么别人就能想出这么优雅…

《异常检测——从经典算法到深度学习》25 基于深度隔离林的异常检测算法

《异常检测——从经典算法到深度学习》 0 概论1 基于隔离森林的异常检测算法 2 基于LOF的异常检测算法3 基于One-Class SVM的异常检测算法4 基于高斯概率密度异常检测算法5 Opprentice——异常检测经典算法最终篇6 基于重构概率的 VAE 异常检测7 基于条件VAE异常检测8 Donut: …

Red Hat系列Docker安装与移除

目录 Docker 安装 Docker 移除 Docker 安装 添加 Docker 官方 YUM 源 sudo yum-config-manager --add-repohttps://download.docker.com/linux/centos/docker-ce.repo 安装 Docker Engine sudo yum install -y docker-ce docker-ce-cli containerd.io 启动 Docker 服务并…

一篇文章掌握 NestJS 所有的生命周期以及生命周期的执行时机

前言 NestJS 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的框架&#xff0c;它使用 TypeScript 作为开发语言&#xff0c;也支持原生的 JavaScript。在 NestJS 中&#xff0c;生命周期事件是一个重要的概念。在我们构建和管理应用程序时&#xff0c;有时需要在特定…

Prometheus快速入门实战

Prometheus快速入门实战 1. 介绍 prometheus受启发于Google的Brogmon监控系统&#xff08;相似kubernetes是从Brog系统演变而来&#xff09;。 2016年5月继kubernetes之后成为第二个加入CNCF基金会的项目&#xff0c;同年6月正式发布1.0版本。2017年底发布基于全新存储层的2.…

istio 应用灰度发布部署注意点(包括 deploy、svc、gw、vs 和 dr)

创建 deployment 分别部署两个版本的 deployment。在灰度发布的过程中&#xff0c;注意 pod 标签的设置&#xff0c;后续 svc 和 dr 就是根据标签来划分 pod apiVersion: apps/v1 kind: Deployment metadata:labels:app: bbjcxtversion: v1name: bbjcxtnamespace: mm-nbxt-hu…

【数据结构】C语言实现双链表的基本操作

双链表及其基本操作的实现 导言一、单链表与双链表二、双链表类型的创建三、双链表的初始化四、双链表的创建五、双链表的遍历六、双链表的查找七、双链表的插入八、双链表的删除结语 导言 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;&#xff01; 经过…

NSNotificationCenter通知

使用观察者模式来实现的用于跨层传递消息的机制 参考文章 ios消息机制(NSNotification 和 NSNotificationCenter) 透彻理解 NSNotificationCenter 通知&#xff08;含实现代码&#xff09; - 掘金 NSNotificationCenter property (class, readonly, strong) NSNotification…

【.NET Core】匿名方法与扩展方法

【.NET Core】匿名方法与扩展方法 文章目录 【.NET Core】匿名方法与扩展方法一、匿名方法1.1 匿名方法定义1.2 通过Delegate关键字创建委托匿名方法1.3 通过Action关键字创建无返回值的匿名方法1.4 通过Func关键字创建有返回值的匿名方法1.5 使用Lambda表达式表示匿名方法 二、…

反射讲解(有图有真相)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、反射是什么&#xff1f;二、反射有啥好处&#xff1f;1. 没反射2. 有反射 三、反射的常用方法1. 获取 Class 对象&#xff1a;2. 获取类的构造方法&#xf…

python统计学-两个总体均值差的区间估计

简介 两个总体均值差的区间估计是指&#xff0c;在给定的置信水平下&#xff0c;估计两个总体均值差的置信区间。两个总体均值差的区间估计的公式为&#xff1a; X ‾ 1 − X ‾ 2 t α / 2 , n 1 n 2 − 2 s 1 2 n 1 s 2 2 n 2 \overline{X}_1 - \overline{X}_2 \pm t_{\a…

数组的声明

概要&#xff1a; 数组的声明分为三个部分 第一部分&#xff1a;数组中元素的数据类型 第二部分&#xff1a;数组名 第三部分&#xff1a;数组标识符(方括号)和数组大小 一、测试代码 #include<stdio.h> int main() {int arr_int[10];char* arr_str[10];arr_in…

软件测试/测试开发丨Selenium环境安装配置

一、selenium 环境配置 1、下载浏览器 目前比较常用的浏览器是 Google Chrome 浏览器&#xff0c;所以本教程以 chrome 为主&#xff0c;后面简介一下其他浏览器的环境配置。 chrome 下载: www.google.cn/chrome/ 2、chromedriver 环境配置 chromedriver 是chromedriver提…

R语言【base】——sprintf():接受格式化文本和变量值来搭建字符型向量。

Package base version 4.2.0 Parameters sprintf(fmt, ...)gettextf(fmt, ..., domain NULL, trim TRUE) 参数【fmt】&#xff1a;格式字符串的字符向量&#xff0c;每个字符串最多 8192 个字节。 参数【...】&#xff1a;要传递给参数【fmt】的值。仅支持逻辑向量、整数向…

【C++】引用详解

前言 在学习C语言时&#xff0c;我们通常会遇到两个数交换的问题&#xff0c;为了实现这一功能&#xff0c;我们会编写一个经典的Swap函数&#xff0c;如下所示&#xff1a; void Swap(int *a, int *b) {int tmp *a;*a *b;*b tmp; } 然而&#xff0c;这个Swap函数看起来可…