zoukankan      html  css  js  c++  java
  • 结对编程第二次作业

    电梯调度算法

    在学操作系统课程的时候记得老师在讲磁盘IO的时候讲到过电梯调度算法(SCAN),依稀记得当时讲的时候是预先输入数据,所以这个算法应该是一个非实时算法,本次作业的题目要求应该是实现一个根据用户实时输入完成电梯调度的一个算法。

    思路

    权值

    看到这个题目的时候,首先百度了电梯调度算法,看了大体思想,让电梯在最底层和最顶层之间连续往返运行,在运行过程中响应处在于电梯运行方向相同的各楼层上的请求,题目里有四个电梯,怎么判断那个电梯进行响应呢,首先我想到了根据一定的规则计算出电梯的权值,然后对权值排序选择最小的,虽然不知道正规的电梯调度算法该怎么写,但是我有了这个想法那就这么做吧。

    规则

    同向

    反向

    实现

    Github地址

    https://github.com/ljshLLW/homework/tree/master/结对h2

    电梯类

    代码稍微有点长,如有需求请点击Github链接自行查看。

    class Elevator:
        def __init__(self, eNum, type, pMaxNum, weight):
            """
            :param eNum: 电梯编号
            :param type: 电梯类型 0 全部楼层 1 单层 2 双层
            :param pMaxNum: 最大载客量
            :param weight: 最大载重量
             pNum      : 现载客量
             direction : 电梯运行方向  1 上 0 下
             floor     : 电梯所在楼层
             list      : 记录电梯所有需要停下的楼层
             maxFloor  : 记录运行方向最远的楼层
             status    : 电梯状态 0 等待 1 运行 2 操作
            """
            self.eNum = eNum
            self.type = type
            self.pMaxNum = pMaxNum
            self.weight = weight天
            self.pNum = 0
            self.direction = 1
            self.floor = 0
            self.list = []
            self.maxFloor = 0
            self.status = 0
            self.signal = 0
    
        # 电梯日志函数
        def log(self):
            if self.direction == 0:
                print("电梯 " + str(self.eNum) + " 所在楼层 " + str(self.floor) +
                      " 电梯运行方向 " + "↓")
            else:
                print("电梯 " + str(self.eNum) + " 所在楼层 " + str(self.floor) +
                      " 电梯运行方向 " + "↑")
                                  ·
                                  ·
                                  ·
    

    权重算法

        def weighT(self, num, direction):
            """
            算法尚不完备
            :param num: 所在楼层
            :param direction: 要去的方向
            :return: 权值 权值小的电梯接任务
            """
            if (num % 2 == 0 and (self.type == 0 or self.type == 2)) or(
                    num % 2 == 1 and (self.type == 0 or self.type == 1)):
                if self.pNum < self.pMaxNum:
                    if self.direction == direction:
                        if direction == 1:
                            if self.floor > num:
                                return 2 * self.maxFloor - num - self.floor
                            else:
                                return num - self.floor
                        else:
                            if self.floor < num:
                                return self.floor + num - 2 * self.maxFloor
                            else:
                                return self.floor - num
                    else:
                        if direction == 1:
                            if self.floor < num:
                                return self.floor + num - 2 * self.maxFloor +10
                            else:
                                if self.maxFloor < num:
                                    return self.floor + num - 2 * self.maxFloor +10
                                else:
                                    return self.floor - num
                        else:
                            if self.floor > num:
                                return 2 * self.maxFloor - num - self.floor +10
                            else:
                                if self.maxFloor > num:
                                    return 2 * self.maxFloor - num - self.floor +10
                                else:
                                    return num - self.floor
    
            return 999
    

    多线程

    多个电梯是独立运行的,所以采用多线程,每个线程运行一个电梯,通过总线程来分配乘客。

    from elevator import *
    
    import threading
    
    e1 = Elevator(1, 0, 10, 800)
    e2 = Elevator(2, 1, 10, 800)
    e3 = Elevator(3, 2, 10, 800)
    e4 = Elevator(4, 0, 20, 2000)
    
    elevators = [e1,e2,e3,e4]
    # 创建线程
    for e in elevators:
        t = threading.Thread(target=e.run)
        t.start()
    

    GUI图形界面

    采用TKinter库,实现了一个稍微能入眼的界面,左侧一个Canvas,右侧是根据电梯状态而显示隐藏的输入框,因为也是现学现卖,代码写得不堪入目就不贴了,实现效果如下图

    结对编程

    这次结对编程给我带来的收益很大,我的领航员给了我充分的鼓励和指导,帮助我分析错误,找到原因,没有他的帮助,我可能会写一半放弃了,之后我的领航员还会和我一起对代码进行分析和优化,因为想要趁热打铁就提前把这篇博客写了出来,但是不代表我俩这次的任务就到此为止,还会不断进行优化,得到自己想要的效果。

    总结

    本次实验是我第一从用Python写一个稍微像样的东西,(框架除外)这是我第一次写Python的类,多线程,和Tkinter的GUI图形界面,好吧,之前连类都没写过,写的时候还是现查类的写法。。正是因为这次任务让我体验到了Python的便捷,但是没有受到良好的规范,代码还是写的很烂,不够Pythonic。期间也出现了很多错误比如

    变量类型

    整个任务刚开始的时候,首先构思了电梯类的变量和函数,然后开始上手写起来,除了权值部分,需要仔细想想,其余的部分写起来还是很轻松的,写了很多printf用于输出提醒,到最后一运行,printf全报错了,原来我采用字符串拼接的方式,拼接了一些整型的变量,我以为会像JS一样帮我转换类型呢,结果并不能,只能乖乖的挨个str(),可能因为Python是动态类型,就让我没有很注意变量的类型,但是其实这也是很重要的,现在Js除了TypeScript,Python现在也能像静态语言一样声明变量类型,看似静态类型才是最终的归属,但这里是非不是我这样的大白菜可以理解的,不管是动态还是静态都要着重注意变量类型才是我该做的。

    多线程

    这是第一次写多线程,(示例除外),感觉还是很不同的,都说Python的多线程不是真正的多线程,因为Global Interpreter Lock的存在,每个线程需要获得GIL锁才能执行,每执行100条字节码就释放GIL锁,所以只能用到一个核,多核也没用,这似乎对我这个老旧的电脑很友好啊(并不),当我第一次写的时候把传入的参数带了(),导致卡死,我听见了来自我的笔记本的咆哮声,抑或是无助的呼喊,一打开任务管理器,看到100%的占用我的心都碎了,之后修改正确,每次运行还是会让电脑大喘气,因为子线程一直在while(1)等待信号量,暂时不知道该如何更改。

    引用

    我把电梯类单独写到了一个.py文件中,把GUI图形界面写到了另一个.py文件中,GUI需要引用电梯类,根据输入判断权值,选择电梯,写到后面突然发现需要在电梯类中引用图形界面文件里的变量,然后我就又在类文件中导入了图形界面的文件,相当于他俩互相导入了,结果很显然,报错,这不就相当于他俩写在同一个文件里了吗,但是写在同一个文件里肯定不易读,让我的领航员小伙伴怎么办,所以我就添加了几个类变量解决了这个问题,感觉还是好麻烦啊。

    图形界面

    虽然是第一次用这个图形界面吧,但是之前写过一个WinForm程序,好像是叫这个名字,来,帮我做个课设,你学这个的应该不难吧,完活儿请你吃饭,最主要还是排版的问题,现在也没整明白,这个pack排版是怎么回事,真是太奇怪了。控件的显示隐藏也很奇怪,直接在流里消失,相当于 Display:None 做出来的效果好差啊,Canvas的刷新也耽搁了我好长一段时间,一开始是因为粗心大意增量设置错误,试了各种方法,矩形岿然不动,最后调好了效果也是差强人意,update函数完全没啥卵用,面向百度工程师发现百度居然没有的那种绝望你懂吗,Stack Overflow又看不懂,是时候好好加强英语水平了,最后用的方法是删除重绘,每次重绘都一闪一闪的,可能是我这个CPU真的不行了,算四个矩形都要那么久,也不知道有什么回调函数可以间歇性刷新,只能又开了个线程,先sleep(为了不瞎眼),然后删除重绘,效果真的是太差了。

    写在最后

    一开始计划的很美好,类,和类的函数都写得很简洁,实际运行一看还差很多意思,就删删改改,最后确实能完成一定功能了,但是却没有那么美好了,也许这就像是,活成了自己最不喜欢的样子?

  • 相关阅读:
    TSQL--按某字段列分组,在将各组中某列合并成一行
    疑难杂症--SQL SERVER 2012下数据库内存异常回收
    TSQL--删除登陆相关的用户
    杂谈--一次”失败“问题处理过程
    layer.open如何关闭自身弹出窗口
    简单的Http请求数据保存到Hdfs
    layui栅格布局问题
    redis单机版安装
    redis详细配置文件
    批量修改mysql数据库引擎
  • 原文地址:https://www.cnblogs.com/ljsh/p/10781202.html
Copyright © 2011-2022 走看看