实验二——动态高优先权优先调度算法

实验二——动态高优先权优先调度算法
实验二——动态高优先权优先调度算法

《操作系统》课程实验报告实验名称:动态分区存储管理

姓名:王子瑜

学号: 541413450235

地点:四教楼

指导老师:刘放美

专业班级:软件工程(测试技术14-02)

实验成绩:

一、实验要求:

熟悉并掌握动态分区分配的各种算法。

熟悉并掌握动态分区中分区回收的各种情况,并能够实现分区合并。

二、实验内容:

用高级语言模拟实现动态分区存储管理,要求:

1、分区分配算法至少实现首次适应算法、最佳适应算法和最坏适应算法中的至

少一种。熟悉并掌握各种算法的空闲区组织方式。

2、分区的初始化——可以由用户输入初始分区的大小。(初始化后只有一个空

闲分区,起始地址为0,大小是用户输入的大小)

3、分区的动态分配过程:由用户输入作业号和作业的大小,实现分区过程。

4、分区的回收:用户输入作业号,实现分区回收,同时,分区的合并要体现出

来。(注意:不存在的作业号要给出错误提示!)

5、分区的显示:任何时刻,可以查看当前内存的情况(起始地址是什么,大小

多大的分区时空闲的,或者占用的,能够显示出来)

要求考虑:(1)内存空间不足的情况,要有相应的显示;

(2)作业不能同名,但是删除后可以再用这个名字;

(3)作业空间回收是输入作业名,回收相应的空间,如果这个作业名不存在,也要有相应的提示。

三、实验代码

#include

#include

#define SIZE 640 // 内存初始大小

#define MINSIZE 5 // 碎片最小值

enum STATE { Free, Busy };

struct subAreaNode {

int addr; // 起始地址

int size; // 分区大小

int taskId; // 作业号

STATE state; // 分区状态

subAreaNode *pre; // 分区前向指针

subAreaNode *nxt; // 分区后向指针

}subHead;

// 初始化空闲分区链

void intSubArea()

{

// 分配初始分区内存

subAreaNode *fir = (subAreaNode *)malloc(sizeof(subAreaNode)); // 给首个分区赋值

fir->addr = 0;

fir->size = SIZE;

fir->state = Free;

fir->taskId = -1;

fir->pre = &subHead;

fir->nxt = NULL;

// 初始化分区头部信息

subHead.pre = NULL;

subHead.nxt = fir;

// 首次适应算法

int firstFit(int taskId, int size)

{

subAreaNode *p = subHead.nxt;

while(p != NULL)

{

if(p->state == Free && p->size >= size) {

// 找到要分配的空闲分区

if(p->size - size <= MINSIZE) {

// 整块分配

p->state = Busy;

p->taskId = taskId;

} else {

// 分配大小为size的区间

subAreaNode *node = (subAreaNode *)malloc(sizeof(subAreaNode)); node->addr = p->addr + size;

node->size = p->size - size;

node->state = Free;

node->taskId = -1;

// 修改分区链节点指针

node->pre = p;

node->nxt = p->nxt;

if(p->nxt != NULL) {

p->nxt->pre = node;

}

p->nxt = node;

// 分配空闲区间

p->size = size;

p->state = Busy;

p->taskId = taskId;

}

printf("内存分配成功!\n");

return 1;

}

p = p->nxt;

}

printf("找不到合适的内存分区,分配失败...\n"); return 0;

}

// 最佳适应算法

int bestFit(int taskId, int size)

{

subAreaNode *tar = NULL;

int tarSize = SIZE + 1;

subAreaNode *p = subHead.nxt;

while(p != NULL)

{

// 寻找最佳空闲区间

if(p->state == Free && p->size >= size && p->size < tarSize) { tar = p;

tarSize = p->size;

}

p = p->nxt;

}

if(tar != NULL) {

// 找到要分配的空闲分区

if(tar->size - size <= MINSIZE) {

// 整块分配

tar->state = Busy;

tar->taskId = taskId;

} else {

// 分配大小为size的区间

subAreaNode *node = (subAreaNode *)malloc(sizeof(subAreaNode)); node->addr = tar->addr + size;

node->size = tar->size - size;

node->state = Free;

node->taskId = -1;

// 修改分区链节点指针

node->pre = tar;

node->nxt = tar->nxt;

if(tar->nxt != NULL) {

tar->nxt->pre = node;

}

tar->nxt = node;

// 分配空闲区间

tar->size = size;

tar->state = Busy;

tar->taskId = taskId;

}

printf("内存分配成功!\n");

return 1;

} else {

// 找不到合适的空闲分区

printf("找不到合适的内存分区,分配失败...\n");

return 0;

}

}

// 回收内存

int freeSubArea(int taskId)

{

int flag = 0;

subAreaNode *p = subHead.nxt, *pp;

while(p != NULL)

{

if(p->state == Busy && p->taskId == taskId) {

flag = 1;

if((p->pre != &subHead && p->pre->state == Free) && (p->nxt != NULL && p->nxt->state == Free)) { // 情况1:合并上下两个分区

// 先合并上区间

pp = p;

p = p->pre;

p->size += pp->size;

p->nxt = pp->nxt;

pp->nxt->pre = p;

free(pp);

// 后合并下区间

pp = p->nxt;

p->size += pp->size;

p->nxt = pp->nxt;

if(pp->nxt != NULL) {

pp->nxt->pre = p;

}

free(pp);

} else if((p->pre == &subHead || p->pre->state == Busy) && (p->nxt != NULL && p->nxt->state == Free)) {

// 情况2:只合并下面的分区

pp = p->nxt;

p->size += pp->size;

p->state = Free;

p->taskId = -1;

p->nxt = pp->nxt;

if(pp->nxt != NULL) {

pp->nxt->pre = p;

}

free(pp);

} else if((p->pre != &subHead && p->pre->state == Free)

&& (p->nxt == NULL || p->nxt->state == Busy)) { // 情况3:只合并上面的分区

pp = p;

p = p->pre;

p->size += pp->size;

p->nxt = pp->nxt;

if(pp->nxt != NULL) {

pp->nxt->pre = p;

}

free(pp);

} else {

// 情况4:上下分区均不用合并

p->state = Free;

p->taskId = -1;

}

}

p = p->nxt;

}

if(flag == 1) {

// 回收成功

printf("内存分区回收成功...\n");

return 1;

} else {

// 找不到目标作业,回收失败

printf("找不到目标作业,内存分区回收失败...\n");

return 0;

}

}

// 显示空闲分区链情况

void showSubArea()

{

printf("*********************************************\n");

printf("** 当前的内存分配情况如下: **\n");

printf("*********************************************\n");

printf("** 起始地址 | 空间大小 | 工作状态 | 作业号 **\n");

subAreaNode *p = subHead.nxt;

while(p != NULL)

{

printf("**-----------------------------------------**\n"); printf("**");

printf("%d k |", p->addr);

printf("%d k |", p->size);

printf(" %s |", p->state == Free ? "Free" : "Busy"); if(p->taskId > 0) {

printf("%d ", p->taskId);

} else {

printf(" ");

}

printf("**\n");

p = p->nxt;

}

printf("*********************************************\n"); }

int main()

{

int option, ope, taskId, size;

// 初始化空闲分区链

intSubArea();

// 选择分配算法

while(1)

{

printf("请选择要模拟的分配算法:

0 表示首次适应算法,1 表示最佳适应算法\n");

scanf("%d", &option);

if(option == 0) {

printf("你选择了首次适应算法,下面进行算法的模拟\n"); break;

} else if(option == 1) {

printf("你选择了最佳适应算法,下面进行算法的模拟\n"); break;

} else {

printf("错误:请输入 0/1\n\n");

}

}

// 模拟动态分区分配算法

while(1)

{

printf("\n");

printf("*********************************************\n"); printf("** 1: 分配内存 2: 回收内存 0: 退出 **\n"); printf("*********************************************\n"); scanf("%d", &ope);

if(ope == 0) break;

if(ope == 1) {

// 模拟分配内存

printf("请输入作业号: ");

scanf("%d", &taskId);

printf("请输入需要分配的内存大小(KB): ");

scanf("%d", &size);

if(size <= 0) {

printf("错误:分配内存大小必须为正值\n"); continue;

}

// 调用分配算法

if(option == 0) {

firstFit(taskId, size);

} else {

bestFit(taskId, size);

}

// 显示空闲分区链情况

showSubArea();

} else if(ope == 2) {

// 模拟回收内存

printf("请输入要回收的作业号: ");

scanf("%d", &taskId);

freeSubArea(taskId);

// 显示空闲分区链情况

动态规划实验报告

华东师范大学计算机科学技术系上机实践报告 一、 内容与设计思想 1.对于以下5 个矩阵: M 1: 2?3, M 2: 3?6, M 3: 6?4, M 4: 4?2, M 5: 2?7 , (a) 找出这5个矩阵相乘需要的最小数量乘法的次数。 (b) 请给出一个括号化表达式,使在这种次序下达到乘法的次数最少。 输入: 第一行为正整数N,表示有N 组测试数据; 每组测试数据的第一行为n,表示有n 个矩阵,2<=n<=50; 接下去的n 行,每行有两个整数x 和y,表示第ni 个矩阵是x*y 的。 输出: 对行每组数据,输出一行,每行一个整数,最小的矩阵连乘积。 我们保证输出的结果在2^64之内。 基本思想: 对于n 个矩阵的连乘积,设其不同的计算次序为P(n)。 由于每种加括号方式都可以分解为两个子矩阵的加括号问题:(A1...Ak)(Ak+1…An)可以得到关于P(n)的递推式如下: 2.定义0/1/2背包问题为:}x p max{n 1i i i ∑=。限制条件为:c x w n 1i i i ≤∑=,且 n i 1},2,1,0{x i ≤≤∈。设f(i , y)表示剩余容量为y ,剩余物品为:i ,i+1,…,n 时的最优解的值。 1.)给出f(i , y)的递推表达式; 2.)请设计求解f(i , y)的算法,并实现你的算法; 3.)设W=[10,20,15,30],P=[6,10,15,18],c=48,请用你的算法求解。 输入: 第一行为一个正整数N ,表示有几组测试数据。 每组测试数据的第一行为两个整数n 和M ,0=-=∑-=

动态规划算法实验

一、实验目的 (2) 二、实验内容 (2) 三、实验步骤 (3) 四.程序调试及运行结果分析 (5) 附录:程序清单(程序过长,可附主要部分) (7)

实验四动态规划算法的应用 一、实验目的 1.掌握动态规划算法的基本思想,包括最优子结构性质和基于表格的最优值计算方法。 2.熟练掌握分阶段的和递推的最优子结构分析方法。 3.学会利用动态规划算法解决实际问题。 二、实验内容 1.问题描述: 题目一:数塔问题 给定一个数塔,其存储形式为如下所示的下三角矩阵。在此数塔中,从顶部出发,在每一节点可以选择向下走还是向右走,一直走到底层。请找出一条路径,使路径上的数值和最大。 输入样例(数塔): 9 12 15 10 6 8 2 18 9 5 19 7 10 4 16 输出样例(最大路径和): 59 题目二:最长单调递增子序列问题(课本184页例28) 设有由n个不相同的整数组成的数列,记为:a(1)、a(2)、……、a(n)且a(i)<>a(j) (i<>j) 若存在i1

题目三 0-1背包问题 给定n种物品和一个背包。物品i的重量是wi,其价值为vi,背包的容量为c,。问应如何选择装入背包中的物品,使得装入背包中物品的总价值最大? 在选择装入背包的物品时,对每种物品只有两个选择:装入或不装入,且不能重复装入。输入数据的第一行分别为:背包的容量c,,物品的个数n。接下来的n 行表示n个物品的重量和价值。输出为最大的总价值。 输入样例: 20 3 11 9 9 10 7 5 输出样例 19 2.数据输入:个人设定,由键盘输入。 3.要求: 1)上述题目任选一做。上机前,完成程序代码的编写 2)独立完成实验及实验报告 三、实验步骤 1.理解算法思想和问题要求; 2.编程实现题目要求; 3.上机输入和调试自己所编的程序; 4.验证分析实验结果; 5.整理出实验报告。

动态高优先权优先

《操作系统》课程实验报告实验名称:动态高优先权优先算法 姓名:王智昆 学号:541407110243 地点:4#302 指导老师:张旭 专业班级:运维1402

一、实验目的: 1、熟悉并掌握动态高优先权优先算法。 2、用C语言编程实现动态高优先权优先算法 二、实验内容:用高级语言模拟实现动态分区存储管理,要求: 模拟实现动态高优先权优先(若数值越大优先权越高,每运行一个时间单位优先权-n,若数值越小优先权越高,没运行一个时间单位优先权+n),具体如下: 设置作业体:作业名,作业的到达时间,服务时间,初始优先权,作业状态(W ——等待,R——运行,F——完成),作业间的链接指针 作业初始化:由用户输入作业名、服务时间、初始优先权进行初始化,同时,初始化作业的状态为W。 显示函数:在作业调度前、调度中和调度后进行显示。 排序函数:对就绪状态的作业按照优先权排序。优先权相同时进入等待队列时间早的作业在前。注意考虑到达时间 调度函数:每次从等待队列队首调度优先权最高的作业执行,状态变化。并在执行一个时间单位后优先权变化,服务时间变化,状态变化。当服务时间为0时,状态变为F。 删除函数:撤销状态为F的作业。 #include #include struct PCB{ charp_name[20]; intp_priority; intp_needTime; intp_runTime; charp_state; struct PCB* next; }; voidHighPriority(); void Information(); char Choice(); struct PCB* SortList(PCB* HL); int main() { printf(" 《演示最高优先数优先算法》\n\n"); HighPriority(); return 0; } voidHighPriority()

动态规划算法的应用实验报告

实验二动态规划算法的应用 一、实验目的 1.掌握动态规划算法的基本思想,包括最优子结构性质和基于表格的最优值计算方法。 2.熟练掌握分阶段的和递推的最优子结构分析方法。 3.学会利用动态规划算法解决实际问题。 二、实验内容 1.问题描述: 题目一:数塔问题 给定一个数塔,其存储形式为如下所示的下三角矩阵。在此数塔中,从顶部出发,在每一节点可以选择向下走还是向右走,一直走到底层。请找出一条路径,使路径上的数值和最大。 输入样例(数塔): 9 12 15 10 6 8 2 18 9 5 19 7 10 4 16 输出样例(最大路径和): 59 三、算法设计 void main() { 申明一个5*5的二维数组; for(int i=0;i<5;i++) { for(int j=0;j<=i;j++) { 输入数组元素p[i][j]; }

} for(int k=0;k<5;k++) { for(int w=0;w<=k;w++) { 输出数组元素p[k][w]; } } for(int a=4;a>0;a--) { for(int s=0;s<=a;s++) { if(p[a][s]大于p[a][s+1]) p[a-1][s]等于p[a-1][s]加p[a][s]; else p[a-1][s] 等于p[a-1][s] 加p[a][s+1]; } } 输出p[0][0] }

四.程序调试及运行结果分析 五.实验总结 虽然这个实验比较简单,但是通过这次实验使我更加了解的动态规划法的好处和、,在解决问题时要尝试使用动态规划,这样就有可能得到一种即简单复杂性有不高的算法。

(售后服务)操作系统编程进程或作业先来先服务高优先权按时间片轮转调度算法

(售后服务)操作系统编程进程或作业先来先服务高优先权按时间片轮转调度 算法

湖南农业大学科学技术师范学院 学生实验报告

(高优先权流程图) (按时间片轮转调度) 程序说明及实现: 1)先来先服务调度算法: 高响应比优先实现进程调度.(用C语言实现), 2)优先级调度程序: 该程序由主程序、构造队列子程序、打印子程序、运行子程序构成。 3)时间片轮转法程序: 于此程序中由于程序比较小,未进行分模块设计。直接采用单壹模块。 1先来先服务 #include floatt,d;/*定义俩个全局变量*/ struct/*定义壹个结构体数组,包括进程的信息*/ { intid; floatArriveTime; floatRequestTime; floatStartTime; floatEndTime; floatRunTime; floatDQRunTime; intStatus; }arrayT ask[4];/*定义初始化的结构体数组*/ GetTask()/*给结构体数组赋值,输入到达,服务时间*/ {inti; floata; for(i=0;i<4;i++) {arrayT ask[i].id=i+1; printf("inputthenumber"); printf("inputthetheArriveTimeofarrayT ask[%d]:",i);/*用户输入进程的时间,初始为零*/ scanf("%f",&a); arrayT ask[i].ArriveTime=a; printf("inputtheRequestTimeofarrayT ask[%d]:",i); scanf("%f",&a); arrayT ask[i].RequestTime=a; arrayT ask[i].StartTime=0; arrayT ask[i].EndTime=0; arrayT ask[i].RunTime=0;

动态优先权算法模拟-操作系统课程设计

实用标准文档 东北大学分校 计算机与通信工程学院 操作系统课程设计 设计题目动态优先权算法模拟 专业名称计算机科学与技术 班级学号 学生 指导教师 设计时间

课程设计任务书 专业:计算机科学与技术学号:学生(签名): 设计题目:动态优先权算法模拟 一、设计实验条件 综合楼808 二、设计任务及要求 模拟单处理机环境下的进程调度模型,调度采用基于动态优先权的调度算法。 三、设计报告的容 1.设计题目与设计任务 设计题目:动态优先权算法模拟 设计任务:模拟单处理机环境下的进程调度模型,调度采用基于动态优先权的调度算法。 2.前言(绪论) 在操作系统中调度算法的实质是一种资源的分配,因而调度算法是指“根据系统资源分配策略所规定的资源分配算法”。对于不同的操作系统和系统目标,通

常采用不同的调度算法。 为了照顾紧迫作业,使之在进入系统后便获得优先处理,引入了最高优先权先调度算法。在作为进程调度算法时,该算法是把处理机分配给就绪队列优先权最高的进程。这可以分为抢占式优先权算法和非抢占式优先权算法。 对于最高优先权优先调度算法,其关键在于:它是使用静态优先权还是动态优先权,以及如何确定进程的优先权。本次课程设计所实现的算法就是动态优先权算法的抢占式优先权调度算法和非抢占式动态优先权算法。 动态优先权拥有其特有的灵活优点,同时,若所有的进程都具有相同的优先权初值,则显然是最先进入就绪队列的进程,将因其动态优先权变得高而优先获得处理机,此即FCFS算法。若所有的就绪进程具有各不相同优先权初值,那么,对于优先权初值低的进程,在等待了足够长的时间后,其优先权便可能升为最高,从而获得处理机。当采用抢占式优先权调度算法时,如果规定当前进程的优先权以一定速率下降,则可防止一个长作业长期垄断处理机。 这里,我们采用高响应比来决定每个进程的优先权。 3.设计主体(各部分设计容、分析、结论等) 【设计容】 动态优先权是指在创建进程时所赋予的优先权,是可以随进程的推进或随其等待时间的增加而改变的,以便获得更好的调度性能。 非抢占式优先权调度算法。在这种方式下,系统一旦把处理机分配给就绪队

使用动态优先权与时间片轮转的进程调度算法的模拟

计算机与信息工程学院设计性实验报告 一、实验目的 通过动态优先权调度算法的模拟加深进程概念和进程调度过程的理解。二、实验仪器或设备 虚拟机 三、总体设计(设计原理、设计方案及流程等) 实验内容 (1)在Linux下用C语言编程模拟N个进程采用高优先权优先(要求采用 动态优先权)和简单时间片轮转两种进程调度算法。为了清楚地观察每 个进程的调度过程,程序应将每个时间片内的进程情况显示出来; (2)进程控制块是进程存在的唯一标志,因此,在模拟算法中每一个进程用 一个进程控制块PCB来代表,PCB用一结构体表示。包括以下字段: ●进程标识数id,或者进程的名称name; ●进程优先数priority,并规定优先数越大的进程,其优先权越高; ●进程需要运行的CPU时间ntime; ●进程的运行时间rtime; ●进程状态state; ●队列指针next,用来将PCB排成队列。 (3)进程在运行过程中其状态将在就绪、执行、阻塞(可选)、完成几种状态 之间转换,同时进程可能处于不同的队列中,如就绪队列、阻塞队列(可 选)。在两种调度算法中,考虑分别可以选择什么样的队列及如何实现进 程的入队、出队操作; (4)为了便于处理,优先权调度每次也仅让进程执行一个时间片,若在一个 时间片内未运行结束,调整进程优先级将其插入就绪队列,进行新一轮

调度; (5)优先数改变原则: ●进程每运行若一个时间单位,优先数减3; ●进程在就绪队列中呆一个时间片,优先数增加1。(仅供参考,合理 即可) (6)优先权调度中,对于遇到优先权一致的情况,可采用FCFS策略解决; (7)由于是模拟进程调度,所以,对被选中的进程并不实际启动运行,而是 修改进程控制块的相关信息来模拟进程的一次运行; (8)为了清楚地观察诸进程的调度过程,程序应将每个时间片内的进程的情 况显示出来,参照格式如下: id cputime needtime priority(count) state 0 0 2 48 ready 1 0 3 47 ready 2 0 6 44 ready 3 0 5 45 ready 4 0 4 46 ready 简单时间片轮转调度模拟程序见roundrobin.c,优先权调度大家请参考时间片轮转自行实现,有自己想法的同学可以按照自己的思路独立完成实验,而不用参考roundrobin.c程序。 四、实验步骤(包括主要步骤、代码分析等) #include "stdio.h" #include #define getpch(type) (type*)malloc(sizeof(type)) struct pcb { char name[10]; char state; int count; int ntime; int rtime; int priority; struct pcb* link; }*ready=NULL,*tail=NULL,*p; typedef struct pcb PCB; int slice;

算法实验动态规划----矩阵连乘

实验三:动态规划法 【实验目的】 深入理解动态规划算法的算法思想,应用动态规划算法解决实际的算法问题。 【实验性质】 验证性实验。 【实验要求】 对于下列所描述的问题,给出相应的算法描述,并完成程序实现与时间复杂度的分析。该问题描述为:一般地,考虑矩阵A1,A2,…,An的连乘积,它们的维数分别为d0,d1,…,dn,即Ai的维数为di-1×di (1≤i≤n)。确定这n个矩阵的乘积结合次序,使所需的总乘法次数最少。对应于乘法次数最少的乘积结合次序为这n个矩阵的最优连乘积次序。按给定的一组测试数据对根据算法设计的程序进行调试:6个矩阵连乘积A=A1×A2×A3×A4×A5×A6,各矩阵的维数分别为:A1:10×20,A2:20×25,A3:25×15,A4:15×5,A5:5×10,A6:10×25。完成测试。 【算法思想及处理过程】

【程序代码】

printf ("\n\n矩阵连乘次数的最优值为:\n"); printf ("-----------------------------------------------\n"); print2 (0, 6-1, s); printf ("\n-----------------------------------------------\n\n"); return 0; } void MatrixChain (int p[], int m[][6], int s[][6], int n) { int i, j, k, z, t; for (i=0; i

优先级调度算法实验报告

优 先 级 调 度 算 法 实 验 报 告 院系:****************学院班级:*********** 姓名:*** 学号:************

一、实验题目:优先级调度算法 二、实验目的 进程调度是处理机管理的核心内容。本实验要求用高级语言编写模拟进程调度程序,以便加深理解有关进程控制快、进程队列等概念,并体会和了解优先级算法的具体实施办法。 三、实验内容 1.设计进程控制块PCB的结构,通常应包括如下信息: 进程名、进程优先数(或轮转时间片数)、进程已占用的CPU时间、进程到完成还需要的时间、进程的状态、当前队列指针等。 2.编写优先级调度算法程序 3.按要求输出结果。 四、实验要求 每个进程可有三种状态;执行状态(RUN)、就绪状态(READY,包括等待状态)和完成状态(FINISH),并假定初始状态为就绪状态。(一)进程控制块结构如下: NAME——进程标示符 PRIO/ROUND——进程优先数 NEEDTIME——进程到完成还需要的时间片数 STATE——进程状态 NEXT——链指针 注: 1.为了便于处理,程序中进程的的运行时间以时间片为单位进行

计算; 2.各进程的优先数或,以及进程运行时间片数的初值,均由用户在程序运行时给定。 (二)进程的就绪态和等待态均为链表结构,共有四个指针如下:RUN——当前运行进程指针 READY——就需队列头指针 TAIL——就需队列尾指针 FINISH——完成队列头指针 五、实验结果:

六、实验总结: 首先这次实验的难度不小,它必须在熟悉掌握数据结构的链表和队列的前提下才能完成,这次实验中用了三个队列,就绪队列,执行队列和完成队列,就绪队列中的优先级数是有序插入的,当进行进程调度的时候,需要先把就绪队列的队首节点(优先级数最大的节点)移入执行队列中,当执行进程结束后,判断该进程是否已经完成,如果已经完成则移入完成队列,如果没有完成,重新有序插入就绪队列中,这就是这次实验算法的思想。 附录(算法代码):

南京邮电大学算法设计实验报告——动态规划法

实验报告 (2009/2010学年第一学期) 课程名称算法分析与设计A 实验名称动态规划法 实验时间2009 年11 月20 日指导单位计算机学院软件工程系 指导教师张怡婷 学生姓名丁力琪班级学号B07030907 学院(系) 计算机学院专业软件工程

实验报告 实验名称动态规划法指导教师张怡婷实验类型验证实验学时2×2实验时间2009-11-20一、实验目的和任务 目的:加深对动态规划法的算法原理及实现过程的理解,学习用动态规划法解决实际应用中的最长公共子序列问题。 任务:用动态规划法实现求两序列的最长公共子序列,其比较结果可用于基因比较、文章比较等多个领域。 要求:掌握动态规划法的思想,及动态规划法在实际中的应用;分析最长公共子序列的问题特征,选择算法策略并设计具体算法,编程实现两输入序列的比较,并输出它们的最长公共子序列。 二、实验环境(实验设备) 硬件:计算机 软件:Visual C++

三、实验原理及内容(包括操作过程、结果分析等) 1、最长公共子序列(LCS)问题是:给定两个字符序列X={x1,x2,……,x m}和Y={y1,y2,……,y n},要求找出X和Y的一个最长公共子序列。 例如:X={a,b,c,b,d,a,b},Y={b,d,c,a,b,a}。它们的最长公共子序列LSC={b,c,d,a}。 通过“穷举法”列出所有X的所有子序列,检查其是否为Y的子序列并记录最长公共子序列并记录最长公共子序列的长度这种方法,求解时间为指数级别的,因此不可取。 2、分析LCS问题特征可知,如果Z={z1,z2,……,z k}为它们的最长公共子序列,则它们一定具有以下性质: (1)若x m=y n,则z k=x m=y n,且Z k-1是X m-1和Y n-1的最长公共子序列; (2)若x m≠y n且x m≠z k,则Z是X m-1和Y的最长公共子序列; (3)若x m≠y n且z k≠y n,则Z是X和Y的最长公共子序列。 这样就将求X和Y的最长公共子序列问题,分解为求解较小规模的问题: 若x m=y m,则进一步分解为求解两个(前缀)子字符序列X m-1和Y n-1的最长公共子序列问题; 如果x m≠y n,则原问题转化为求解两个子问题,即找出X m-1和Y的最长公共子序列与找出X 和Y n-1的最长公共子序列,取两者中较长者作为X和Y的最长公共子序列。 由此可见,两个序列的最长公共子序列包含了这两个序列的前缀的最长公共子序列,具有最优子结构性质。 3、令c[i][j]保存字符序列X i={x1,x2,……,x i}和Y j={y1,y2,……,y j}的最长公共子序列的长度,由上述分析可得如下递推式: 0 i=0或j=0 c[i][j]= c[i-1][j-1]+1 i,j>0且x i=y j max{c[i][j-1],c[i-1][j]} i,j>0且x i≠y j 由此可见,最长公共子序列的求解具有重叠子问题性质,如果采用递归算法实现,会得到一个指数时间算法,因此需要采用动态规划法自底向上求解,并保存子问题的解,这样可以避免重复计算子问题,在多项式时间内完成计算。 4、为了能由最优解值进一步得到最优解(即最长公共子序列),还需要一个二维数组s[][],数组中的元素s[i][j]记录c[i][j]的值是由三个子问题c[i-1][j-1]+1,c[i][j-1]和c[i-1][j]中的哪一个计算得到,从而可以得到最优解的当前解分量(即最长公共子序列中的当前字符),最终构造出最长公共子序列自身。

实验二——动态高优先权优先调度算法

《操作系统》课程实验报告实验名称:动态分区存储管理 姓名:王子瑜 学号: 541413450235 地点:四教楼 指导老师:刘放美 专业班级:软件工程(测试技术14-02) 实验成绩:

一、实验要求: 熟悉并掌握动态分区分配的各种算法。 熟悉并掌握动态分区中分区回收的各种情况,并能够实现分区合并。 二、实验内容: 用高级语言模拟实现动态分区存储管理,要求: 1、分区分配算法至少实现首次适应算法、最佳适应算法和最坏适应算法中的至 少一种。熟悉并掌握各种算法的空闲区组织方式。 2、分区的初始化——可以由用户输入初始分区的大小。(初始化后只有一个空 闲分区,起始地址为0,大小是用户输入的大小) 3、分区的动态分配过程:由用户输入作业号和作业的大小,实现分区过程。 4、分区的回收:用户输入作业号,实现分区回收,同时,分区的合并要体现出 来。(注意:不存在的作业号要给出错误提示!) 5、分区的显示:任何时刻,可以查看当前内存的情况(起始地址是什么,大小 多大的分区时空闲的,或者占用的,能够显示出来) 要求考虑:(1)内存空间不足的情况,要有相应的显示; (2)作业不能同名,但是删除后可以再用这个名字; (3)作业空间回收是输入作业名,回收相应的空间,如果这个作业名不存在,也要有相应的提示。 三、实验代码 #include #include #define SIZE 640 // 内存初始大小 #define MINSIZE 5 // 碎片最小值 enum STATE { Free, Busy }; struct subAreaNode { int addr; // 起始地址 int size; // 分区大小

算法设计与分析实验报告

本科实验报告 课程名称:算法设计与分析 实验项目:递归与分治算法 实验地点:计算机系实验楼110 专业班级:物联网1601 学号:2016002105 学生姓名:俞梦真 指导教师:郝晓丽 2018年05月04 日

实验一递归与分治算法 1.1 实验目的与要求 1.进一步熟悉C/C++语言的集成开发环境; 2.通过本实验加深对递归与分治策略的理解和运用。 1.2 实验课时 2学时 1.3 实验原理 分治(Divide-and-Conquer)的思想:一个规模为n的复杂问题的求解,可以划分成若干个规模小于n的子问题,再将子问题的解合并成原问题的解。 需要注意的是,分治法使用递归的思想。划分后的每一个子问题与原问题的性质相同,可用相同的求解方法。最后,当子问题规模足够小时,可以直接求解,然后逆求原问题的解。 1.4 实验题目 1.上机题目:格雷码构造问题 Gray码是一个长度为2n的序列。序列无相同元素,每个元素都是长度为n的串,相邻元素恰好只有一位不同。试设计一个算法对任意n构造相应的Gray码(分治、减治、变治皆可)。 对于给定的正整数n,格雷码为满足如下条件的一个编码序列。 (1)序列由2n个编码组成,每个编码都是长度为n的二进制位串。 (2)序列中无相同的编码。 (3)序列中位置相邻的两个编码恰有一位不同。 2.设计思想: 根据格雷码的性质,找到他的规律,可发现,1位是0 1。两位是00 01 11 10。三位是000 001 011

010 110 111 101 100。n位是前n-1位的2倍个。N-1个位前面加0,N-2为倒转再前面再加1。 3.代码设计:

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

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

Module 1: 免费馅饼 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 59327 Accepted Submission(s): 20813 Problem Description 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼。说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的10米范围内。馅饼如果掉在了地上当然就不能吃了,所以gameboy马上卸下身上的背包去接。但由于小径两侧都不能站人,所以他只能在小径上接。由于gameboy平时老呆在房间里玩游戏,虽然在游戏中是个身手敏捷的高手,但在现实中运动神经特别迟钝,每秒种只有在移动不超过一米的范围内接住坠落的馅饼。现在给这条小径如图标上坐标: 为了使问题简化,假设在接下来的一段时间里,馅饼都掉落在0-10这11个位置。开始时gameboy站在5这个位置,因此在第一秒,他只能接到4,5,6这三个位置中其中一个位置上的馅饼。问gameboy最多可能接到多少个馅饼?(假设他的背包可以容纳无穷多个馅饼) Input 输入数据有多组。每组数据的第一行为以正整数n(0

设计一个按优先数调度算法实现处理器调度的程序 改

题目:设计一个按优先数调度算法实现处理器调度的程序 提示: (1)假定系统有5个进程,每个进程用一个PCB来代表。PCB的格式为: 进程名、指针、要求运行时间、优先数、状态。 进程名——P1~P5。 指针——按优先数的大小把5个进程连成队列,用指针指出下一个进程PCB的首地址。 要求运行时间——假设进程需要运行的单位时间数。 优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。 状态——假设两种状态,就绪,用R表示,和结束,用E表示。初始状态都为就绪状态。 (2) 每次运行之前,为每个进程任意确定它的“优先数”和“要求运行时间”。 (3) 处理器总是选队首进程运行。采用动态改变优先数的办法,进程每运行1次,优先 数减1,要求运行时间减1。 (4) 进程运行一次后,若要求运行时间不等于0,则将它加入队列,否则,将状态改为“结 束”,退出队列。 (5) 若就绪队列为空,结束,否则,重复(3)。 2.程序中使用的数据结构及符号说明: #define num 5//假定系统中进程个数为5 struct PCB{ char ID;//进程名 int runtime;//要求运行时间 int pri;//优先数 char state; //状态,R-就绪,F-结束 }; struct PCB pcblist[num];//定义进程控制块数组 3.流程图: (1)主程序流程图: (2)子程序init()流程图:

(3) 子程序max_pri_process()流程图:

(4)子程序show()流程图:

(5)子程序run()流程图:

算法实验 动态规划上机

实验3动态规划上机 [实验目的] 1.掌握动态规划的基本思想和效率分析方法; 2.掌握使用动态规划算法的基本步骤; 3.学会利用动态规划解决实际问题。 [实验要求] 按以下实验内容完成题目,并把编译、运行过程中出现的问题以及解决方法填入实验报告中,按时上交。 [实验学时] 2学时。 [实验内容] 一、实验内容 利用动态规划算法编程求解多段图问题,要求读入多段图,考虑多段图的排序方式,求源点到汇点的最小成本路径。并请对自己的程序进行复杂性分析。 二、算法描述 先输入点的个数和路径数以及每段路径的起点、长度、终点,再计算所有路径的值大小,比较输出后最小值。 三、源程序 #define N 2147483647 #include #include void main() { int i,pointnum,j; cout<<"输入图中点的个数:"<>pointnum; int **array; //array数组描述多段图 int *array2; //array2记录距离起点的最小路径 int *array3; //array3记录上一点编号 array=new int*[pointnum]; array2=new int[pointnum+1]; array3=new int[pointnum+1]; for(i=0;i

} array2[pointnum]=N; array3[pointnum]=N; for(i=0;i>pathnum; int a,k; cout<<"依次输入图中每段路径"<>i; cin>>a; cin>>j; array[i][j]=a; if(array2[j]>(a+array2[i])) { array3[j]=i; array2[j]=a+array2[i]; } // cout<

优先级调度算法

优先级调度算法 1、调度算法 考虑到紧迫型作业进入系统后能得到优先处理,引入了高优先级优先调度算法。 优先级调度的含义: (1)当该算法用于作业调度时,系统从后背作业队列中选择若干个优先级最高的,且系统能满足资源要求的作业装入内存运行;(2)当该算法用于进程调度时,将把处理机分配给就绪进行队列中优先级最高的进程。 2、调度算法的两种方式 非抢占式优先级算法:在这种调度方式下,系统一旦把处理机分配给就绪队列中优先级最高的进程后,该进程就能一直执行下去,直至完成;或因等待某事件的发生使该进程不得不放弃处理机时,系统才能将处理机分配给另一个优先级高的就绪队列。 抢占式优先级调度算法:在这种调度方式下,进程调度程序把处理机分配给当时优先级最高的就绪进程,使之执行。一旦出现了另一个优先级更高的就绪进程时,进程调度程序就停止正在执行的进程,将处理机分配给新出现的优先级最高的就绪进程。常用于实时要求比较严格的实时系统中,以及对实时性能要求高的分时系统。 3、优先级的类型 进程的优先级可采用静态优先级和动态优先级两种,优先级可由用户自定或由系统确定。

静态优先级调度算法 含义:静态优先级是在创建进程时确定进程的优先级,并且规定它在进程的整个运行期间保持不变。 确定优先级的依据: 1)进程的类型。 2)进程对资源的需求。 3)根据用户的要求。 优点:简单易行;系统开销小。 缺点:不太灵活,很可能出现低优先级的作业,长期得不到调度而等待的情况;静态优先级法仅适合于实时要求不太高的系统。 动态优先级调度算法 含义:动态优先级是创建进程时赋予该进程一个初始优先级,然后其优先级随着进程的执行情况的变化而改变,以便获得更好的调度性能。 优点:使相应的优先级调度算法比较灵活、科学,可防止有些进程一直得不到调度,也可防止有些进程长期垄断处理机。 缺点:需要花费相当多的执行程序时间,因而花费的系统开销比较大。 4、实时调度算法 由于在任何一个实时系统中毒存在着若干个实时进程或任务,用来反应或控制相应的外部事件,并往往具有某种程度的紧迫性,所以对实时系统中的调度算法提出了某些特殊要求。 对实时系统的要求

实验报告:动态规划---0-1背包问题)

XXXX大学计算机学院实验报告计算机学院2017级软件工程专业 5 班指导教师 学号姓名2019年10 月21 日成绩

实验内容、上机调试程序、程序运行结果 System.out.println("选中的物品是第"); for(int i=1;i<=n;i++){ for(int j=1;j<=maxweight;j++){ //当前最大价值等于放前一件的最大价值 maxvalue[i][j] = maxvalue[i-1][j]; //如果当前物品的重量小于总重量,可以放进去或者拿出别的东西再放进去 if(weight[i-1] <= j){ //比较(不放这个物品的价值)和(这个物品的价值放进去加上当前能放的总重量减去当前物品重量时取i-1个物品是的对应重量时候的最高价值) if(maxvalue[i-1][j-weight[i-1]] + value[i - 1] > maxvalue[i-1][j]){ maxvalue[i][j] = maxvalue[i-1][j-weight[i-1]] + value[i - 1]; } } } } return maxvalue[n][maxweight]; } public static void main(String[] args) { int weight[] = {2,3,4,5}; int value[] = {3,4,5,7}; int maxweight = 8; System.out.println(knapsack(weight,value,maxweight)); } } 完成效果:

动态规划算法实验报告

动态规划算法实验报告

————————————————————————————————作者: ————————————————————————————————日期:

实验标题 1、矩阵连乘 2、最长公共子序列3、最大子段和 4、凸多边形最优三角剖分 5、流水作业调度 6、0-1背包问题 7、最优二叉搜索树 实验目的掌握动态规划法的基本思想和算法设计的基本步骤。 实验内容与源码1、矩阵连乘 #include #include using namespace std; const int size=4; //ra,ca和rb,cb分别表示矩阵A和B的行数和列数 void matriMultiply(int a[][4],int b[][4],int c[][4],int ra,intca,int rb,int cb) { if(ca!=rb) cerr<<"矩阵不可乘"; for(int i=0;i<ra;i++) for(int j=0;j<cb;j++) { int sum=a[i][0]*b[0][j]; for(int k=1;k

非抢占式高优先级调度算法

/* 非抢占式高优先级调度算法(优先数越大级别越高) 算法思想:在按进程达到时间由小到大的顺序输入进程信息后,先对其优先数进行排列,将最先到达的进程的到达时间设为开始时间,计算结束时间, 然后对后面到达的时间与该进程的结束时间进行比较,如若小于该进程的结束时间,记录进程的个数,再对其优先数逐个进行比较,将优 先数最大的提到前面,每次进程结束都要进行比较,得到执行序列,在依次输出结果 */ #include<> #define MAX 100 struct hrfs { char name[10]; float arrvitetime; float starttime; float servietime; float finishtime; int priority;riority; j=1; while((jp[i].priority){ max_priority=p[j].priority; i=j; } j++; } k=i; p[k].starttime=p[k].arrvitetime;inishtime=p[k].starttime+p[k].servietime; p[k].run_flag=1; temp_time=p[k].finishtime; p[k].order=1; temp_count=1; while(temp_countmax_priority){ max_priority=p[j].priority; k=j; } } p[k].starttime=temp_time; p[k].finishtime=p[k].starttime+p[k].servietime;

中南大学算法实验报告

算法设计与分析基础 ——实验报告 姓名:周建权 学号:0909122820 班级:信安1202

实验一分治 —最近点对 一.问题 Problem Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some toys, with all the toys encircled awarded. In the field of Cyberground, the position of each toy is fixed, and the ring is carefully designed so it can only encircle one toy at a time. On the other hand, to make the game look more attractive, the ring is designed to have the largest radius. Given a configuration of the field, you are supposed to find the radius of such a ring. Assume that all the toys are points on a plane. A point is encircled by the ring if the distance between the point and the center of the ring is strictly less than the radius of the ring. If two toys are placed at the same point, the radius of the ring is considered to be 0. Input The input consists of several test cases. For each case, the first line contains an integer N (2 <= N <= 100,000), the total number of toys in the field. Then N lines follow, each contains a pair of (x, y) which are the coordinates of a toy. The input is terminated by N = 0. Output For each test case, print in one line the radius of the ring required by the Cyberground manager, accurate up to 2 decimal places. 二.分析思路 题目是给n个点的坐标,求距离最近的一对点之间距离的一半。第一行是一个数n表示有n个点,接下来n行是n个点的x坐标和y坐标。 首先,假设点是n个,编号为1到n。找一个中间的编号mid,先求出1到mid点的最近距离设为d1,还有mid+1到n的最近距离设为d2。如果说最近点对中的两点都在1-mid 集合中,或者mid+1到n集合中,则d就是最小距离了。但是还有可能的是最近点对中的两点分属这两个集合,若存在,则把这个最近点对的距离记录下来,去更新d。这样就得到最小的距离d了。 三.源代码 #include #include #include using namespace std; #define N 1000010 struct point {

相关文档
最新文档