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

csdn小透明对大佬的代码做了一些小改进
仅作学习交流,侵权删除
大佬原文链接:https://blog.csdn.net/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)

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

以下是Python实现页面置换算法OPTFIFOLRU和clock算法的程序: ```python # -*- coding: utf-8 -*- # 定义常量 PAGE_NUM = 10 # 页面数 MEMORY_SIZE = 3 # 内存块数 # 生成随机页面序列 page_seq = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 随机打乱页面序列 import random random.shuffle(page_seq) # 初始化内存 memory = [] # OPT算法 def opt(page): if page not in memory: if len(memory) < MEMORY_SIZE: memory.append(page) else: max_index = 0 max_page = memory[0] for i in range(MEMORY_SIZE): if memory[i] not in page_seq: max_page = memory[i] break elif page_seq.index(memory[i]) > max_index: max_index = page_seq.index(memory[i]) max_page = memory[i] memory[memory.index(max_page)] = page # FIFO算法 def fifo(page): if page not in memory: if len(memory) < MEMORY_SIZE: memory.append(page) else: memory.pop(0) memory.append(page) # LRU算法 def lru(page): if page in memory: memory.remove(page) else: if len(memory) >= MEMORY_SIZE: memory.pop(0) memory.append(page) # clock算法 def clock(page): global clock_pointer if page not in memory: if len(memory) < MEMORY_SIZE: memory.append(page) else: while True: if memory[clock_pointer][1] == 0: memory[clock_pointer] = [page, 1] clock_pointer = (clock_pointer + 1) % MEMORY_SIZE break else: memory[clock_pointer][1] = 0 clock_pointer = (clock_pointer + 1) % MEMORY_SIZE # 执行页面置换算法 for i in range(PAGE_NUM): opt(page_seq[i]) #fifo(page_seq[i]) #lru(page_seq[i]) #clock(page_seq[i]) # 输出每次置换后的内存状态 print("第%d次置换:" % (i+1), end=" ") for j in range(MEMORY_SIZE): if j < len(memory): print(memory[j], end=" ") else: print("-", end=" ") print() # 输出缺页率 print("缺页率:", (PAGE_NUM - len(memory)) / PAGE_NUM) ``` 程序中先定义了常量`PAGE_NUM`和`MEMORY_SIZE`,分别表示页面数和内存块数。然后生成随机的页面序列,打乱顺序,用于模拟页面的访问。接着定义了全局变量`memory`和`clock_pointer`,分别表示当前内存状态和clock算法的指针位置。 程序中实现了四种页面置换算法OPTFIFOLRU和clock算法。每次访问一个页面时,会根据当前算法的规则来决定是否需要将该页面加入内存,如果内存已满,则选择一个页面进行替换。每次置换后会输出当前的内存状态,以便观察算法的效果。最后输出缺页率。 注释中提到的FIFOLRU算法的实现也在程序中给出,可以通过注释掉OPT算法的执行语句,取消注释FIFOLRU或clock算法的执行语句,来测试不同算法的效果。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值