python实现OPT,LRU,FIFO页面置换算法

本文详细介绍了三种页面置换算法:FIFO、LRU和OPT,并提供了改进后的Python代码实现,支持自定义页面数量和缓冲区大小。通过对比不同算法下的内存状态和缺页次数,深入理解内存管理机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

csdn小透明对大佬的代码做了一些小改进
仅作学习交流,侵权删除
大佬原文链接:https://blog.youkuaiyun.com/sdm12345/article/details/103281128

以下是改进后的代码

class page:
    def __init__(self,num,time):      
        # 记录页面号
        self.num = num  
        # 记录调入内存时间
        self.time = time


class main:
    # 初始化内存单元,缓冲区
    def __init__(self,M = 4,N = 17 ,a = [2,3,2,1,8,7,4,5,3,7,5,2,9,5,6,4,9]):
        # 以上设定了默认值
        self.queue = [] # 记录调入队列
        self.k = -1 # 每载入一次加一 即缺页次数
        self.flag =-1 # 标记内存4个空
        self.a = a # 需要排序的页面列表
        self.M = M # 缓冲区的大小
        self.N = N # 需要排序的页面列表的长度
         # 初始化内存单元
        self.b = [page(-1,self.M-i-1) for i in range(0,self.M)]
        # 初始化内存当前状态,缓冲区 初始化页号全为-1
        self.c = [[-1 for i in range(0,self.N)] for j in range(0,self.M)]
        self.process()


    # 打印图表用
    def print_string(self):
        str = '---+'
        print('|',end = '')
        for i in range(0,self.N-1):
            print(str,end = '')
        print("---|")

    # 取得在内存中停留最久的页面,默认状态下为最早点入的页面
    def get_max(self,b):
        max = -1
        flag = 0
        for i in range(0,self.M):
            if b[i].time >max:
                max = b[i].time
                flag = i
        return flag 

    # 判断页面是否已在内存中(fold为需要判断的页面)
    def equation(self,fold,b):
        for i in range(0,self.M):
            if fold == b[i].num:
                return i # 返回页面序号
        return -1


    # FIFO 算法
    def fifo(self, fold):
        val = self.equation(fold, self.b)
        if val >= 0:
            pass # 如果要调入的页内存中已存在则跳过
        else:
            self.queue.append(fold)
            self.k += 1 # 缺页数加一
            self.flag += 1
            self.flag %= 4 # 循环在四个位置动 
            if self.b[self.M-1].num!= -1: # 判断有没有空位
                for i in range(0,self.M-1):
                    self.b[i].num = self.b[i+1].num # 上移保证下一个要替换的是第一个
                self.b[self.M-1].num = fold # 更改内存区已存入的页号
            else:
                self.b[self.flag].num = fold


    # LRU 算法
    def lru(self, fold):
        val = self.equation(fold, self.b)
        if val >= 0:
            self.b[val].time = 0 # 如果已经存在则刷该页面新时间
            for i in range(0, self.M):
                if i != val: # 其余页面时间加一
                    self.b[i].time += 1
        else:
            self.queue.append(fold)
            self.k += 1 # 新页调入就得加一
            val = self.get_max(self.b) # 找到最旧的页面
            self.b[val].num = fold # 替换该页面
            self.b[val].time = 0
            for i in range(0, self.M):
                if (i != val): # 其余页面时间加一
                    self.b[i].time += 1


    # OPT 算法
    def opt(self,fold,index):
        # index记录当前页序号
        max = -1
        val = self.equation(fold,self.b)
        if val >= 0:
            pass
        else:
            self.queue.append(fold)
            self.k += 1

            for i in range(0,self.M):
                for j in range(index+1,self.N):
                    if self.b[i].num==self.a[j]:
                        # 这里的时间指的是距离下次使用的时间
                        self.b[i].time = j-i
                        break
                    else: # 不会再用到的设置非常大的时间
                        self.b[i].time = 999

            for i in range(0, self.M):
                if self.b[i].num == -1: # 如果有空位
                    val = i
                    break;
                else:
                    if self.b[i].time > max: # 找到缓冲区时间最长的
                        max = self.b[i].time
                        val = i
            self.b[val].num = fold


    def reset(self): # 重置内存区、队列等,便于更换算法
        self.b = [page(-1, self.M - i - 1) for i in range(0, self.M)]
        self.c = [[-1 for i in range(0, self.N)] for j in range(0, self.M)]
        self.queue = []
        self.k = -1


    # 打印内存状态
    def Myprint(self):
        self.print_string()
        for i in range(0, self.N): # 打印第一行 即要求存入的页面序列
            print("|%2d" % (self.a[i]), end=" ") # 两位整数,空格结尾
        print("|")

        self.print_string()
        for i in range(0, self.M):
            for j in range(0, self.N):
                if self.c[i][j] == -1:
                    print("|%2c" % (32), end=" ") # 无页面打印空格
                else:
                    print("|%2d" % (self.c[i][j]), end=" ")
            print("|")

        self.print_string()
        print("调入队列为")
        for i in range(0, self.k + 1):
            print("%2d" % (self.queue[i]), end=" ")
        print("\n缺页次数为:%6d\n缺页率:%16.6f" % (self.k + 1, (float)(self.k + 1) / self.N))

    # 主程序
    def process(self):
        # fifo算法
        for i in range(0, self.N): # 逐个存入
            self.fifo(self.a[i])
            # 记录当前的内存单元中的页面(即一列)
            for j in range(0, self.M):
                self.c[j][i] = self.b[j].num
        print("fifo算法内存状态为:")
        self.Myprint()

        # lru算法
        self.reset()
        for i in range(0, self.N):
            self.lru(self.a[i])
            # 记录当前的内存单元中的页面
            for j in range(0, self.M):
                self.c[j][i] = self.b[j].num
        print("lru算法内存状态为:")
        self.Myprint()

        # opt 算法
        self.reset()
        for i in range(0, self.N):
            self.opt(self.a[i], i)
            # 记录当前的内存单元中的页面
            for j in range(0, self.M):
                self.c[j][i] = self.b[j].num
        print("opt算法内存状态为:")
        self.Myprint()

if __name__ == "__main__":
    a = [2,3,2,1,5,2,4,5,3,2,5,2]
    N = len(a)
    M = 4 #可以改为3或其他大小
    main(M,N,a)

原文的代码只能支持固定的页面数量和缓冲区大小
改进为可以自定页面数量和缓冲区大小
如有错误欢迎指正!!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值