1. 程式人生 > >實驗四 動態分割槽分配演算法

實驗四 動態分割槽分配演算法

一、  需求分析

說明程式設計的任務和目的,明確規定下述內容:

加深對動態分割槽分配演算法的理解,進一步掌握首次適應演算法、迴圈首次適應 演算法、最佳適應演算法和最壞適應演算法的實現方法。

(1)    輸入的形式和輸入值的範圍;

已在程式中預置好記憶體和程序等資訊

(2)    輸出的形式;

按記憶體地址從低到高的順序輸出記憶體狀態和程序的分配結果

(3)    程式所能達到的功能;

模擬首次適應演算法、迴圈首次適應  演算法、最佳適應演算法和最壞適應演算法對記憶體進行分配

(4)    測試資料,包括正確的輸入及其輸出結果和含有錯誤的輸入及其輸出結果。

程序資訊


記憶體資訊(一個 . 代表一個記憶體單元,| 代表 記憶體塊之間的劃分)

二、  概要設計

說明本程式中用到的所有抽象資料型別的定義、主程式的流程以及各程式模組之間的層次(呼叫)關係。

程序物件

classProcess

{

publicstring name;

publicint needSpace;

}

記憶體塊物件

classSpace

{

privatestaticstring usedFlag = "1";

privatestaticstring freeFlag = ".";

publicint id;//空間編號(從小到大排序)

publicint startIndex;//空間開始索引

publicint freeStartIndex;//空閒指標[空間內的相對位置0-空間大小]

publicint freeSize;//空間塊空閒大小

publicList<string> SpaceDetail;//空間詳情

privateList<string>SpaceDetailNote;//【輔助變數】空間詳情描述,便於觀察分配結果

privateint NoteStartIndex;//【輔助變數】空間塊空閒大小

}

記憶體物件

classRAM

{

publicint size;//記憶體大小      

publicList<Space> spaceDetail;//記憶體塊詳情

}

三、  詳細設計

實現程式模組的具體演算法。

publicbool

FirstPartition(List<Process> processList)

publicbool CycleFirstPartition(List<Process> processList)

publicbool BestPartition(List<Process> processList)

publicbool WorstPartition(List<Process> processList)

四、  除錯分析

(1)    除錯過程中遇到的問題以及解決方法,設計與實現的回顧討論和分析;

完全採用C#用面向物件的方式編寫,程式設計過程十分順利

五、  使用者使用說明

程式的使用說明,列出每一步的操作步驟。

執行程式---檢視結果

六、  測試結果

列出測試結果,包括輸入和輸出。


七、  附錄

帶註釋的源程式,註釋應清楚具體;

using Lab4;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lab4
{

    class Process
    {
        public string name;
        public int needSpace;
        public Process(string name, int needSpace)
        {
            this.name = name;
            this.needSpace = needSpace;
        }
    }
    class Space
    {
        private static string usedFlag = "1";
        private static string freeFlag = ".";
        public int id;//空間編號(從小到大排序)
        public int startIndex;//空間開始索引
        public int freeStartIndex;//空閒指標[空間內的相對位置0-空間大小]
        public int freeSize;//空間塊空閒大小
        public List<string> SpaceDetail;//空間詳情
        private List<string> SpaceDetailNote;//【輔助變數】空間詳情描述,便於觀察分配結果
        private int NoteStartIndex;//【輔助變數】空間塊空閒大小
        public Space(int id, int startIndex, int size)
        {
            this.id = id;
            this.startIndex = startIndex;
            freeStartIndex = 0;
            freeSize = size;
            SpaceDetail = new List<string>(); SpaceDetailNote = new List<string>(); NoteStartIndex = 0;
            for (int i = 0; i < size; i++)
            {
                SpaceDetail.Add(freeFlag); SpaceDetailNote.Add(freeFlag);
            }
        }

        public void useSpace(Process process)
        {
            for (int i = freeStartIndex; i < freeStartIndex + process.needSpace; i++)
            {
                SpaceDetail[i] = usedFlag;
            }
            freeSize -= process.needSpace;
            freeStartIndex = SpaceDetail.Count - freeSize - 1;

            SpaceDetailNote.RemoveRange(NoteStartIndex, process.needSpace); SpaceDetailNote.Insert(NoteStartIndex, process.name + "[" + process.needSpace + "]"); NoteStartIndex++;

        }
        public void printSpace()
        {
            for (int i = 0; i < SpaceDetail.Count; i++)
            {
                Console.Write(SpaceDetail[i]);
            }
        }
        public void printSpaceNote()
        {
            for (int i = 0; i < SpaceDetailNote.Count; i++)
            {
                Console.Write(SpaceDetailNote[i]);
            }
        }
    }
    class RAM
    {
        public int size;//記憶體大小       
        public List<Space> spaceDetail;//記憶體塊詳情
        public RAM(int[] spaceSizeArray)
        {
            size = 0;
            spaceDetail = new List<Space>();
            for (int i = 0; i < spaceSizeArray.Length; i++)
            {
                spaceDetail.Add(new Space(i, size, spaceSizeArray[i]));
                size += spaceSizeArray[i];
            }
        }
        public void printRAM(bool printNote = false)
        {
            //列印前將儲存塊從小到大排序
            spaceDetail = spaceDetail.OrderBy(m => m.id).ToList();
            Console.WriteLine("當前RAM狀態如下: \n");
            foreach (var space in spaceDetail)
            {
                space.printSpace();
                Console.Write("|");
                //Console.WriteLine(space.id + "[" + space.startIndex + "," + (space.startIndex + space.SpaceDetail.Count-1) + "]");
            }
            Console.WriteLine("\n");
            if (printNote)
            {

                foreach (var space in spaceDetail)
                {
                    space.printSpaceNote();
                    Console.Write("|");
                    //Console.WriteLine(space.id + "[" + space.startIndex + "," + (space.startIndex + space.SpaceDetail.Count-1) + "]");
                }
                Console.WriteLine("\n");
            }

        }
        //首次適應演算法
        public bool FirstPartition(List<Process> processList)
        {
            Console.WriteLine("首次適應演算法進行中...");
            //預設分配成功次數
            int succcefulCount = 0;
            //遍歷所有程序
            for (int i = 0; i < processList.Count; i++)
            {
                //遍歷所有空間塊
                for (int j = 0; j < spaceDetail.Count; j++)
                {
                    //如果空間充足
                    if (spaceDetail[j].freeSize >= processList[i].needSpace)
                    {
                        //分配空間並轉至處理下一程序
                        spaceDetail[j].useSpace(processList[i]);
                        succcefulCount += 1;
                        break;
                    }
                }
            }
            return succcefulCount == processList.Count ? true : false;
        }
        //迴圈首次適應演算法
        public bool CycleFirstPartition(List<Process> processList)
        {
            Console.WriteLine("迴圈首次適應演算法進行中...");
            //記錄上次空間塊的位置和1個程序比較空間塊的次數
            int spaceIndex = 0, compareCount = 0;
            //預設分配成功次數
            int succcefulCount = 0;
            //遍歷所有程序
            for (int i = 0; i < processList.Count; i++)
            {
                //切換到新程序時重置比較次數
                compareCount = 0;
                //迴圈遍歷所有空間塊
                while (compareCount < spaceDetail.Count)
                {
                    //如果比較了所有空間塊則終止,防止死迴圈!
                    if (compareCount == spaceDetail.Count)
                    {
                        compareCount = spaceDetail.Count;//同時跳出第二層迴圈
                        break;
                    }
                    //取模運算,防止迴圈越界!
                    if (spaceIndex >= spaceDetail.Count)
                    {
                        spaceIndex = spaceIndex % spaceDetail.Count;
                    }
                    //如果空間充足
                    if (spaceDetail[spaceIndex].freeSize >= processList[i].needSpace)
                    {
                        //分配空間並轉至處理下一程序
                        spaceDetail[spaceIndex].useSpace(processList[i]);
                        succcefulCount++;
                        spaceIndex++;//移動指標到下一空間
                        break;
                    }
                    spaceIndex++;//移動指標
                }

            }
            return succcefulCount == processList.Count ? true : false;
        }
        //最佳適應演算法
        public bool BestPartition(List<Process> processList)
        {
            Console.WriteLine("最佳適應演算法進行中...");
            //預設分配成功次數
            int succcefulCount = 0;

            //遍歷所有程序
            for (int i = 0; i < processList.Count; i++)
            {
                //空間塊排序(按剩餘空間從小到大)
                spaceDetail = spaceDetail.OrderBy(m => m.freeSize).ToList();
                //取出空間訪問順序
                List<int> orders = (from t in spaceDetail select t.id).ToList();

                //按訪問順序遍歷所有空間塊
                for (int j = 0; j < orders.Count; j++)
                {
                    int order = orders[j];
                    Space space = (from t in spaceDetail where t.id == order select t).FirstOrDefault();
                    //如果空間充足
                    if (space.freeSize >= processList[i].needSpace)
                    {
                        //分配空間並轉至處理下一程序
                        spaceDetail[j].useSpace(processList[i]);
                        succcefulCount += 1;
                        break;
                    }
                }

            }

            return succcefulCount == processList.Count ? true : false;
        }
        //最壞適應演算法
        public bool WorstPartition(List<Process> processList)
        {
            Console.WriteLine("最壞適應演算法進行中...");
            //預設分配成功次數
            int succcefulCount = 0;

            //遍歷所有程序
            for (int i = 0; i < processList.Count; i++)
            {
                //空間塊排序(按剩餘空間從大到小)
                spaceDetail = spaceDetail.OrderByDescending(m => m.freeSize).ToList();
                //取出空間訪問順序
                List<int> orders = (from t in spaceDetail select t.id).ToList();

                //按訪問順序遍歷所有空間塊
                for (int j = 0; j < orders.Count; j++)
                {
                    int order = orders[j];
                    Space space = (from t in spaceDetail where t.id == order select t).FirstOrDefault();
                    //如果空間充足
                    if (space.freeSize >= processList[i].needSpace)
                    {
                        //分配空間並轉至處理下一程序
                        spaceDetail[j].useSpace(processList[i]);
                        succcefulCount += 1;
                        break;
                    }
                }

            }

            return succcefulCount == processList.Count ? true : false;
        }
    }
    class Tool
    {
     
        public static void PrintProcessList(List<Process> processList)
        {
            Console.WriteLine("----------程序列表如下: \n");
            for (int i = 0; i < processList.Count; i++)
            {
                Console.Write("程序名 " + processList[i].name + " 程序所需空間大小" + processList[i].needSpace+"\n");
              
            }
            Console.WriteLine("\n提示: . 表示未使用, 1 表示已被程序佔用 \n");
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("----------動態分割槽分配演算法----------- \n");
        //初始化程序
        List<Process> processList = new List<Process>();
        processList.Add(new Process("A", 7));
        processList.Add(new Process("B", 18));
        processList.Add(new Process("C", 9));
        processList.Add(new Process("D", 20));

        //初始化記憶體
        int[] spaceSizeArray = new int[] { 16, 16, 8, 32, 64, 32 };

        //列印資訊
        Tool.PrintProcessList(processList);
      

        var r1 = new RAM(spaceSizeArray); r1.printRAM();
        if (r1.FirstPartition(processList))
        {
            r1.printRAM(true);
        }
        else
        {
            Console.Write("警告:RAM不足,部分程序未處理!!! \n");
            r1.printRAM(true);
        }
        var r2 = new RAM(spaceSizeArray); r2.CycleFirstPartition(processList); r2.printRAM(true);
        var r3 = new RAM(spaceSizeArray); r3.BestPartition(processList); r3.printRAM(true);
        var r4 = new RAM(spaceSizeArray); r4.WorstPartition(processList); r4.printRAM(true);

        Console.ReadLine();
    }
}