程序设计前分析:

初步想法:

最优适应算法只是在执行首次适应算法之前,对空闲区表按为空闲空间长度升序排序,之后只要执行最先适应算法即可。

通过程序实现初步想法之后发现:

在执行最优适应算法之后,由于会对空闲区进行合并,但是我的空闲区合并函数是在空闲区表按空闲空间起址升序排序的基础上进行合并的。而执行最优适应算法之前会会打乱这种排序,因此在执行空闲区合并函数的时候,应该在开头对空闲区表按空闲空间起址升序排序,这样才能得到正确的合并。执行空闲区合并函数后,要对空闲区表重新按照空闲空间长度升序排序,以显示正确的空闲区表。
此外,对于回收主存函数,回收过程同样需要执行空闲区合并函数,因此也要在执行空闲区合并函数后,对空闲区表重新按照空闲空间长度升序排序,以显示正确的空闲区表。

解决问题:

上述的问题涉及多个函数,一开始我想通过对各个函数引入一个参数,以达到选择不同的算法各个函数相应执行的代码不同的目的。但是,我发现这样做会大大降低代码的可读性,为了保证代码的可读性,我选择了一种算法对应一组函数的方式。
注意:
本程序中,最优适应算法空闲区表的打印是按空闲空间长度升序排序之后打印的。
而在首次适应算法中,空闲区表的打印是按空闲空间起址长度升序排序之后打印的。

完整代码

free_list = []
allocated_list = []
class FreeAreaTable:
    # 空闲区表
    def __init__(self, start, length, status):
        '''
        :param start:   起址
        :param length:  长度
        :param status:  状态
        '''
        self.start = start
        self.length =length
        self.status = status

class AllocatedTable:
    # 已分配表
    def __init__(self, start, length, name):
        '''
        :param start:   起址
        :param length:  长度
        :param name:    名称
        '''
        self.start = start
        self.length = length
        self.name = name

def merge_free_area(start):
    # 合并空闲区
    global free_list
    index = int(0)
    # 空闲区表按空闲空间起址升序排序
    free_list = sorted(
        free_list,
        key=lambda free: free.start,
    )
    for i in range(len(free_list)):
        # 查找归还区在空闲区表中的位置
        if free_list[i].start == start:
            index = i
            break
    if index == (len(free_list) - 1):
        # 归还区位于空闲区表最后时,只能向上合并
        if (free_list[index - 1].start + free_list[index - 1].length) == free_list[index].start:
            # 向上合并
            free_list[index - 1].length += free_list[index].length
            del free_list[index]
        return
    if (free_list[index].start + free_list[index].length) == free_list[index+1].start:
        # 向下合并
        free_list[index].length += free_list[index+1].length
        del free_list[index+1]
    if (free_list[index-1].start + free_list[index-1].length) == free_list[index].start:
        # 向上合并
        free_list[index-1].length += free_list[index].length
        del free_list[index]

def allocate_main_memory1(length, name):
    # 分配主存(首次适应算法)
    global free_list, allocated_list
    start = int(0)
    # flag用于标记是否在已有空闲区中找到合适的空间
    flag = False
    for i in range(len(free_list)):
        # 在已有空闲区中查找合适的空间
        if free_list[i].length >= length:
            flag = True
            start = free_list[i].start
            if free_list[i].length == length:
                del free_list[i]
            else:
                free_list[i].start += length
                free_list[i].length -= length
                merge_free_area(free_list[i].start)
            break
    allocated = AllocatedTable(
        start=start, length=length, name=name,
    )
    if not flag:
        # 未找到合适的空间则申请更大的空间,起址为当前空闲区表中最大的起址
        i = len(free_list)
        allocated.start = free_list[i-1].start
        del free_list[i-1]
    # 在已分配表中添加该作业
    for i in range(len(allocated_list)):
        if allocated_list[i].start > allocated.start:
            allocated_list.insert(i, allocated)
            return print('分配成功!\n')
    allocated_list.append(allocated)
    print('分配成功!\n')

def allocate_main_memory2(length, name):
    # 分配主存(最优适应算法)
    global free_list, allocated_list
    start = int(0)
    # flag用于标记是否在已有空闲区中找到合适的空间
    flag = False
    # 空闲区表按为空闲空间长度升序排序
    free_list = sorted(
        free_list,
        key=lambda free: free.length,
    )
    for i in range(len(free_list)):
        # 在已有空闲区中查找合适的空间
        if free_list[i].length >= length:
            flag = True
            start = free_list[i].start
            if free_list[i].length == length:
                del free_list[i]
            else:
                free_list[i].start += length
                free_list[i].length -= length
                merge_free_area(free_list[i].start)
                free_list = sorted(
                    free_list,
                    key=lambda free: free.length,
                )
            break
    allocated = AllocatedTable(
        start=start, length=length, name=name,
    )
    if not flag:
        # 未找到合适的空间则申请更大的空间,起址为当前空闲区表中最大的起址
        i = len(free_list) - 1
        free_list = sorted(
            free_list,
            key=lambda free: free.start,
        )
        allocated.start = free_list[i].start
        del free_list[i]
        free_list = sorted(
            free_list,
            key=lambda free: free.length,
        )
    # 在已分配表中添加该作业
    for i in range(len(allocated_list)):
        if allocated_list[i].start > allocated.start:
            allocated_list.insert(i, allocated)
            return print('分配成功!\n')
    allocated_list.append(allocated)
    print('分配成功!\n')

def recycle_main_memory1(name):
    # 回收主存(首次适应算法)
    global free_list, allocated_list
    start = int(0)
    length = int(0)
    for i in range(len(allocated_list)):
        # 在已分配表中查找要回收的作业
        if allocated_list[i].name == name:
            start = allocated_list[i].start
            length = allocated_list[i].length
            del allocated_list[i]
            break
    free = FreeAreaTable(
        start=start, length=length, status='未分配'
    )
    # 对空闲区表按空闲空间起址升序排序
    free_list = sorted(
        free_list,
        key=lambda free: free.start,
    )
    # 在空闲区表中加入回收的空间,并对相邻空闲区进行合并
    for i in range(len(free_list)):
        if free_list[i].start > free.start:
            free_list.insert(i, free)
            merge_free_area(free.start)
            return print('回收成功!\n')
    free_list.append(free)
    merge_free_area(free.start)
    print('回收成功!\n')

def recycle_main_memory2(name):
    # 回收主存(最优适应算法)
    global free_list, allocated_list
    start = int(0)
    length = int(0)
    for i in range(len(allocated_list)):
        # 在已分配表中查找要回收的作业
        if allocated_list[i].name == name:
            start = allocated_list[i].start
            length = allocated_list[i].length
            del allocated_list[i]
            break
    free = FreeAreaTable(
        start=start, length=length, status='未分配'
    )
    # 在空闲区表中加入回收的空间,并对相邻空闲区进行合并
    for i in range(len(free_list)):
        if free_list[i].start > free.start:
            free_list.insert(i, free)
            merge_free_area(free.start)
            free_list = sorted(
                free_list,
                key=lambda free: free.length,
            )
            return print('回收成功!\n')
    free_list.append(free)
    merge_free_area(free.start)
    free_list = sorted(
        free_list,
        key=lambda free: free.length,
    )
    print('回收成功!\n')

def show_main_memory():
    # 显示主存
    print('-------------------空闲区表-------------------')
    print('起址'.center(8)+'|'+'长度'.center(8)+'|'+'    状态'.center(8))
    for i in free_list:
        print('{:3d}K'.center(11).format(i.start)+'|'+'{:3d}K'.center(11).format(i.length)+'|'+'{}'.center(11).format(i.status))
    print('--------------------------------------------')
    print('-------------------已分配表-------------------')
    print('起址'.center(8)+'|'+'长度'.center(8)+'|'+'    名称'.center(8))
    for i in allocated_list:
        print('{:3d}K'.center(11).format(i.start)+'|'+'{:3d}K'.center(11).format(i.length)+'|'+'{}'.center(11).format(i.name))
    print('--------------------------------------------')

if __name__=='__main__':
    free1 = FreeAreaTable(
        start=14, length=12, status='未分配',
    )
    free2 = FreeAreaTable(
        start=32, length=96, status='未分配',
    )
    free_list.append(free1)
    free_list.append(free2)
    allocated1 = AllocatedTable(
        start=5, length=5, name='作业一',
    )
    allocated2 = AllocatedTable(
        start=10, length=4, name='作业三',
    )
    allocated3 = AllocatedTable(
        start=26, length=6, name='作业二',
    )
    allocated_list.append(allocated1)
    allocated_list.append(allocated2)
    allocated_list.append(allocated3)
    print('选择分配主存算法(a-首次适应算法、b-最优适应算法)')
    select_algorithm = input('请输入选择的算法:')
    if select_algorithm == 'a':
        # 首次适应算法
        while True:
            print('选择功能项(0-退出、1-分配主存、2-回收主存、3-显示主存)')
            select = int(input('请输入选择的功能:'))
            if select == 0:
                print('程序已退出!')
                break
            elif select == 1:
                # 分配主存
                name = input('请输入要分配的作业名称:')
                length = int(input('请输入作业主存量:'))
                allocate_main_memory1(length, name)
            elif select == 2:
                # 回收主存
                name = input('请输入要回收的作业名称:')
                recycle_main_memory1(name)
            elif select == 3:
                # 显示主存
                show_main_memory()
            else:
                # 功能选择错误
                print('您选择的功能项有误,请重新输入!')
    elif select_algorithm == 'b':
        while True:
            print('选择功能项(0-退出、1-分配主存、2-回收主存、3-显示主存)')
            select = int(input('请输入选择的功能:'))
            if select == 0:
                print('程序已退出!')
                break
            elif select == 1:
                # 分配主存
                name = input('请输入要分配的作业名称:')
                length = int(input('请输入作业主存量:'))
                allocate_main_memory2(length, name)
            elif select == 2:
                # 回收主存
                name = input('请输入要回收的作业名称:')
                recycle_main_memory2(name)
            elif select == 3:
                # 显示主存
                show_main_memory()
            else:
                # 功能选择错误
                print('您选择的功能项有误,请重新输入!')
    else:
        print('您选择的算法有误,请重新输入!')

结果示例

首次适应算法

Python 单一连续分区固定分 区和可变分区 python磁盘分区_升序


Python 单一连续分区固定分 区和可变分区 python磁盘分区_操作系统_02


Python 单一连续分区固定分 区和可变分区 python磁盘分区_升序_03


Python 单一连续分区固定分 区和可变分区 python磁盘分区_主存_04


Python 单一连续分区固定分 区和可变分区 python磁盘分区_python_05


Python 单一连续分区固定分 区和可变分区 python磁盘分区_主存_06

最优适应算法

Python 单一连续分区固定分 区和可变分区 python磁盘分区_升序_07


Python 单一连续分区固定分 区和可变分区 python磁盘分区_python_08


Python 单一连续分区固定分 区和可变分区 python磁盘分区_Python_09


Python 单一连续分区固定分 区和可变分区 python磁盘分区_升序_10


Python 单一连续分区固定分 区和可变分区 python磁盘分区_升序_11


Python 单一连续分区固定分 区和可变分区 python磁盘分区_Python_12