第三次电梯作业个人优化

前言

由于个人能力有限,第二次电梯作业只能完成正确性设计,没能进行优化,也因此损失了强测分数,于是第三次电梯作业时便决定进行优化,结果强测错了一个点,同样损失了强测分数……但是总的来说,第三次作业的优化还是有一定效果的,性能分比起完全没有优化的第二次高了许多,有的点甚至达到了96、97分,也一定程度上弥补了我第三次作业的强测分数。

在写博客之前也拜读了很多大佬的优化博客,比起他们的一些很巧妙的优化方法,还有一些我看不懂的优化方法,我的优化实在是拿不出手,过于简单。但我最后还是决定写一下这次的优化博客,一方面是为了能够得点分数,另一方面是希望能给像我一样能力有限的同学提供一个思路,即使不会什么高深的算法和工具,用最简单基础的方法也是可以进行优化的,优化一定程度上是大佬们的游戏,但对于我们而言,只要尝试了也一定还有收获。

那么下面就讲一下我的优化思路。

优化思路

一、调度器

最简单并且保证正确的调度算法就是按照A,B,C(或者C,B,A等等)的顺序来进行轮询,找到第一个能够完成请求的电梯就把请求塞给它。但是,这样就有很有可能导致调度器把绝大多数请求都分给某一部电梯,其他电梯长时间空闲的情况。

所以,对于多部电梯均可以完成的请求,我们要把它分配给最合适的那一部。对于如何选择最合适的电梯,有大佬给出了极为复杂巧妙的算法,而我的做法则很白痴,就是将按照当前已经分配给个电梯的请求数量把三部电梯进行排序,然后从请求数量最少到最多依次进行询问,分给第一部可以完成的电梯。

Elevator e1 = elevator1;
Elevator e2 = elevator2;
Elevator e3 = elevator3;
if (e1.getNuma() > e2.getNuma()) {//getNuma方法返回已分配给该电梯的请求数量
Elevator temp;
temp = e1;
e1 = e2;
e2 = temp;
}
if (e2.getNuma() > e3.getNuma()) {
Elevator temp;
temp = e2;
e2 = e3;
e3 = temp;
}
if (e1.getNuma() > e2.getNuma()) {
Elevator temp;
temp = e1;
e1 = e2;
e2 = temp;
}
……
if (e1.able(t)) {
e1.getLista().add(t);//进行分配 } else if (e2.able(t)) {
e2.getLista().add(t); } else if (e3.able(t)) {
e3.getLista().add(t); }

当然,对于需要合作才能完成的请求,我也是先检查排序一位和排序二位的电梯合作是否可以完成,再依次检查。

我觉得这体现的其实是一种平均分配的思想,不仅适用于电梯,也适用于任何多线程完成任务的程序设计,当然也正因为于此,它可能在电梯这个特定的问题上表现的不如那些专门针对电梯特性设计的调度算法好,但是平均下来仍然有较好的优化效果,特别是在强测数据完全随机的情况下。

二、电梯

电梯的优化我主要分以下两个方面进行:

1.设定空闲目标楼层

简单来说,就是让每部电梯在没有任务,又恰好占用CPU资源的时候往一个最合适的楼层自主移动,这个最合适的楼层可以是换乘比较方便的楼层,可以是人流量比较大的楼层,也可以最简单的就设为所以可以到达楼层的中间楼层,在我的程序中我选择的是第三种。代码如下:

ft = fmid;//将目标楼层设为中间楼层
while (lista.isempty() && inc) {
try {
move();//在没有请求的时候向目标楼层即中间楼层移动
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}

不难发现,这种实现在某些情况下会产生负优化,比如过一段时间就从一楼来一个请求,这时候我的电梯往往会进行折返跑,浪费大量时间,但是同样,在平均效果上,这样的做法实现了优化,对于大量随机请求而言,电梯处于中间位置往往是最佳选择。

2.主请求的选择

在选择主请求的时候,我们的等待队列里往往已经有了许多等待的请求,这时候选择哪一个作为主请求呢,我认为应该选择那个出发楼层离电梯目前楼层最远的那个作为主请求,这样可以在去接主请求的路上捎带上尽可能多的请求,比如当前请求队列中有如下几个请求:5-9,4-3,1-2.;而我的电梯目前处于10层(假设各层均可停留),如果我们直接将第一个也就是5-9的请求作为主请求,电梯会先完成这个请求,然后再跑下来完成4-3,最后完成1-2,而如果按照之前所说选择1-2作为主请求,我们就会在去1层的路上完成4-3的请求,然后顺势而上完成5-9,完全没有无谓的折返。

我感觉这种优化体现的是和上面两处优化不同的思路,上面两处实现的是一种平均优化,即尽管某些情况会产生负优化,但平均起来效果更好。而第三处优化则是:某些情况下性能更好,其他情况下性能至少不会变差,这也是一种优化的思路。

OO第三次电梯作业优化的更多相关文章

  1. OO——电梯作业总结

    目录 电梯作业总结 程序结构与复杂度的分析 第一次作业 第二次作业 第三次作业 程序BUG的分析 互测 自动评测 有效性 总结 电梯作业总结 程序结构与复杂度的分析 第一次作业 1.设计思路 第一次作 ...

  2. OO第二次博客作业—17373247

    OO第二次博客作业 零.写在前面 OO第二单元宣告结束,在这个单元里自己算是真正对面向对象编程产生了比较深刻的理解,也认识到了一个合理的架构为编程带来的极大的便利. (挂三次评测分数 看出得分接近等差 ...

  3. OO第二次博客作业——电梯调度

    OO第二次博客作业——电梯调度 前言 最近三周,OO课程进入多线程学习阶段,主要通过三次电梯调度作业来学习.从单部电梯的傻瓜式调度到有性能要求的调度到多部电梯的调度,难度逐渐提升,对同学们的要求逐渐变 ...

  4. 学会拒绝,是一种智慧——OO电梯章节优化框架的思考

    在本章的三次作业里,每次作业我都有一个主题,分别是:托盘型共享数据.单步电梯运行优化.多部电梯运行优化,因而电梯优化实际是第二.三次作业.虽然后两次作业从性能分上看做得还不错,但阅读其他大佬博客,我深 ...

  5. OO第三单元作业总结

    OO第三单元作业总结--JML 第三单元的主题是JML规格的学习,其中的三次作业也是围绕JML规格的实现所展开的(虽然感觉作业中最难的还是如何正确适用数据结构以及如何正确地对于时间复杂度进行优化). ...

  6. OO第三单元作业——魔教规格

    OO第三单元作业--魔教规格 JML的理论基础和相关工具   JML(Java Modeling Language,Java建模语言),在Java代码种增加了一些符号,这些符号用来标志一个方法是干什么 ...

  7. oo第二次博客-三次电梯调度的总结与反思

    本单元从电梯调度相关问题层层深入,带领我们学习并运用了了多线程相关的知识. 三次电梯调度依次为单电梯单容量.单电梯可携带.多电梯可携带. 一.我的设计 在第一次作业中,使用了最简单的FIFO调度方法. ...

  8. OO电梯作业总结

    (一)第五次作业 一.设计思路 生产消费者模型,输入接口是producer,调度器是tray,电梯是customer.由于只有一架电梯,所以生产消费模型满足以下条件: 一个生产者,一个消费者 托盘不为 ...

  9. [BUAA OO]第三次博客作业

    OO第三次博客作业 1. 规格化设计的发展 我认为,规格化设计主要源自于软件设计的两次危机.第一次是由于大量存在的goto语句,让当时被广泛应用的面向过程式的编程语言臃肿不堪,在逻辑性上与工程规模上鱼 ...

随机推荐

  1. php UTF8 转字节数组,后使用 MD5 计算摘要

    Hex.encodeHexString(md5.digest);按 UTF8 转字节数组,后使用 MD5 计算摘要,得到 16 字节数组,使用 Hex 转为长度为 32 的字符串,保持小写 bin2h ...

  2. 洛谷 P2731 骑马修栅栏 Riding the Fences

    P2731 骑马修栅栏 Riding the Fences 题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样 ...

  3. 多媒体文件嵌入HTML中自动转码工具

    神器网址:https://iframely.com/embed 首先上传视频文件到服务器,视频管理网址平台 比如:   https://wistia.com/ 然后进入到 iframely 网址.复制 ...

  4. Luogu P4403 [BJWC2008]秦腾与教学评估【二分答案】By cellur925

    题目传送门 这道题:真·凉心出题人. 二分答案,个人感觉其实并不只适用于有明显的"最大值最小/最小值最大"条件的题目,其实也可以称它为一种"优化的暴力".这题就 ...

  5. 利用Hough变换识别图像中的直线

    引入 近期看到2015年数学建模A题太阳影子定位中的第四问,需要根据附件中视频里的直杆的太阳影子的变化确定拍摄地点.其实确定拍摄地点这个问题并不是十分困难,因为有前三问的铺垫,我们已经得出了太阳影子长 ...

  6. Java NIO 必知必会(Example)

    管道流: Java NIO 管道是2个线程之间的单向数据连接.Pipe有一个source通道和一个sink通道.数据会被写到sink通道,从source通道读取. package base.nio.t ...

  7. 用 scp 命令通过 SSH 互传文件

    上传单个文件到远程服务器 命令格式 scp [/path/local_dir/filename] [username@servername:/path/remote_dir] 上传本地的 vimrc ...

  8. Net Core开源日志框架

    Net Core开源日志框架 Exceptionless - .Net Core开源日志框架 作者:markjiang7m2原文地址:https://www.cnblogs.com/markjiang ...

  9. centos虚拟机安装指定版本docker

    环境: centos 7.6+ docker-ce 17.03.2 安装依赖包 yum -y install yum-utils device-mapper-persistent-data lvm2 ...

  10. 图像分类丨Inception家族进化史「GoogleNet、Inception、Xception」

    引言 Google提出的Inception系列是分类任务中的代表性工作,不同于VGG简单地堆叠卷积层,Inception重视网络的拓扑结构.本文关注Inception系列方法的演变,并加入了Xcept ...