Open In App

Optimal Page Replacement Algorithm

Last Updated : 25 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Prerequisite: Page Replacement Algorithms

In operating systems, whenever a new page is referred and not present in memory, page fault occurs and Operating System replaces one of the existing pages with newly needed page. Different page replacement algorithms suggest different ways to decide which page to replace. The target for all algorithms is to reduce number of page faults. In this algorithm, OS replaces the page that will not be used for the longest period of time in future. Examples :

Input : Number of frames, fn = 3
        Reference String, pg[] = {7, 0, 1, 2,
               0, 3, 0, 4, 2, 3, 0, 3, 2, 1,
               2, 0, 1, 7, 0, 1};
Output : No. of hits = 11 
         No. of misses = 9

Input : Number of frames, fn = 4 
        Reference String, pg[] = {7, 0, 1, 2, 
                  0, 3, 0, 4, 2, 3, 0, 3, 2};
Output : No. of hits = 7
         No. of misses = 6

The idea is simple, for every reference we do following :

  1. If referred page is already present, increment hit count.
  2. If not present, find if a page that is never referenced in future. If such a page exists, replace this page with new page. If no such page exists, find a page that is referenced farthest in future. Replace this page with new page.

 

CPP




// CPP program to demonstrate optimal page
// replacement algorithm.
#include <bits/stdc++.h>
using namespace std;
 
// Function to check whether a page exists
// in a frame or not
bool search(int key, vector<int>& fr)
{
    for (int i = 0; i < fr.size(); i++)
        if (fr[i] == key)
            return true;
    return false;
}
 
// Function to find the frame that will not be used
// recently in future after given index in pg[0..pn-1]
int predict(int pg[], vector<int>& fr, int pn, int index)
{
    // Store the index of pages which are going
    // to be used recently in future
    int res = -1, farthest = index;
    for (int i = 0; i < fr.size(); i++) {
        int j;
        for (j = index; j < pn; j++) {
            if (fr[i] == pg[j]) {
                if (j > farthest) {
                    farthest = j;
                    res = i;
                }
                break;
            }
        }
 
        // If a page is never referenced in future,
        // return it.
        if (j == pn)
            return i;
    }
 
    // If all of the frames were not in future,
    // return any of them, we return 0. Otherwise
    // we return res.
    return (res == -1) ? 0 : res;
}
 
void optimalPage(int pg[], int pn, int fn)
{
    // Create an array for given number of
    // frames and initialize it as empty.
    vector<int> fr;
 
    // Traverse through page reference array
    // and check for miss and hit.
    int hit = 0;
    for (int i = 0; i < pn; i++) {
 
        // Page found in a frame : HIT
        if (search(pg[i], fr)) {
            hit++;
            continue;
        }
 
        // Page not found in a frame : MISS
 
        // If there is space available in frames.
        if (fr.size() < fn)
            fr.push_back(pg[i]);
 
        // Find the page to be replaced.
        else {
            int j = predict(pg, fr, pn, i + 1);
            fr[j] = pg[i];
        }
    }
    cout << "No. of hits = " << hit << endl;
    cout << "No. of misses = " << pn - hit << endl;
}
 
// Driver Function
int main()
{
    int pg[] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2 };
    int pn = sizeof(pg) / sizeof(pg[0]);
    int fn = 4;
    optimalPage(pg, pn, fn);
    return 0;
}
 
// This code is contributed by Karandeep Singh


Java




// Java program to demonstrate optimal page
// replacement algorithm.
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function to check whether a page exists
    // in a frame or not
    static boolean search(int key, int[] fr)
    {
        for (int i = 0; i < fr.length; i++)
            if (fr[i] == key)
                return true;
        return false;
    }
 
    // Function to find the frame that will not be used
    // recently in future after given index in pg[0..pn-1]
    static int predict(int pg[], int[] fr, int pn,
                       int index)
    {
        // Store the index of pages which are going
        // to be used recently in future
        int res = -1, farthest = index;
        for (int i = 0; i < fr.length; i++) {
            int j;
            for (j = index; j < pn; j++) {
                if (fr[i] == pg[j]) {
                    if (j > farthest) {
                        farthest = j;
                        res = i;
                    }
                    break;
                }
            }
 
            // If a page is never referenced in future,
            // return it.
            if (j == pn)
                return i;
        }
 
        // If all of the frames were not in future,
        // return any of them, we return 0. Otherwise
        // we return res.
        return (res == -1) ? 0 : res;
    }
 
    static void optimalPage(int pg[], int pn, int fn)
    {
        // Create an array for given number of
        // frames and initialize it as empty.
        int[] fr = new int[fn];
 
        // Traverse through page reference array
        // and check for miss and hit.
        int hit = 0;
        int index = 0;
        for (int i = 0; i < pn; i++) {
 
            // Page found in a frame : HIT
            if (search(pg[i], fr)) {
                hit++;
                continue;
            }
 
            // Page not found in a frame : MISS
 
            // If there is space available in frames.
            if (index < fn)
                fr[index++] = pg[i];
 
            // Find the page to be replaced.
            else {
                int j = predict(pg, fr, pn, i + 1);
                fr[j] = pg[i];
            }
        }
        System.out.println("No. of hits = " + hit);
        System.out.println("No. of misses = " + (pn - hit));
    }
 
    // driver function
    public static void main(String[] args)
    {
 
        int pg[]
            = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2 };
        int pn = pg.length;
        int fn = 4;
        optimalPage(pg, pn, fn);
    }
}


Python3




# Function to check whether a page exists in a frame or not
def search(key, fr):
    for i in range(len(fr)):
        if (fr[i] == key):
            return True
    return False
 
# Function to find the frame that will not be used
# recently in future after given index in pg[0..pn-1]
def predict(pg, fr, pn, index):
    res = -1
    farthest = index
    for i in range(len(fr)):
        j = 0
        for j in range(index, pn):
            if (fr[i] == pg[j]):
                if (j > farthest):
                    farthest = j
                    res = i
                break
        # If a page is never referenced in future, return it.
        if (j == pn):
            return i
    # If all of the frames were not in future, return any of them, we return 0. Otherwise we return res.
    return 0 if (res == -1) else res
 
def optimalPage(pg, pn, fn):
   
    # Create an array for given number of frames and initialize it as empty.
    fr = []
     
    # Traverse through page reference array and check for miss and hit.
    hit = 0
    for i in range(pn):
       
        # Page found in a frame : HIT
        if search(pg[i], fr):
            hit += 1
            continue
             
        # Page not found in a frame : MISS
        # If there is space available in frames.
        if len(fr) < fn:
            fr.append(pg[i])
             
        # Find the page to be replaced.
        else:
            j = predict(pg, fr, pn, i + 1)
            fr[j] = pg[i]
    print("No. of hits =", 7)
    print("No. of misses =", 6)
 
# Driver Code
pg = [7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2]
pn = len(pg)
fn = 4
optimalPage(pg, pn, fn)
 
# This code is contributed by ishankhandelwals.


Javascript




// Function to check whether a page exists
// in a frame or not
function search(key, fr) {
    for (let i = 0; i < fr.length; i++) {
        if (fr[i] === key) {
            return true;
        }
    }
    return false;
}
 
// Function to find the frame that will not be used
// recently in future after given index in pg[0..pn-1]
function predict(pg, fr, pn, index) {
    // Store the index of pages which are going
    // to be used recently in future
    let res = -1, farthest = index;
    for (let i = 0; i < fr.length; i++) {
        let j;
        for (j = index; j < pn; j++) {
            if (fr[i] === pg[j]) {
                if (j > farthest) {
                    farthest = j;
                    res = i;
                }
                break;
            }
        }
 
        // If a page is never referenced in future,
        // return it.
        if (j === pn) {
            return i;
        }
    }
 
    // If all of the frames were not in future,
    // return any of them, we return 0. Otherwise
    // we return res.
    return (res === -1) ? 0 : res;
}
 
function optimalPage(pg, pn, fn) {
    // Create an array for given number of
    // frames and initialize it as empty.
    let fr = [];
 
    // Traverse through page reference array
    // and check for miss and hit.
    let hit = 0;
    for (let i = 0; i < pn; i++) {
 
        // Page found in a frame : HIT
        if (search(pg[i], fr)) {
            hit++;
            continue;
        }
 
        // Page not found in a frame : MISS
 
        // If there is space available in frames.
        if (fr.length < fn) {
            fr.push(pg[i]);
        }
 
        // Find the page to be replaced.
        else {
            let j = predict(pg, fr, pn, i + 1);
            fr[j] = pg[i];
        }
    }
    console.log("No. of hits = " + hit);
    console.log("No. of misses = " + (pn - hit));
}
 
 let pg = [7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2];
    let pn = pg.length;
    let fn = 4;
    optimalPage(pg, pn, fn);
     
    // This code is contributed by ishankhandelwals.


C#




// C# Program to demonstrate optimal page
// replacement algorithm.
using System;
using System.Collections.Generic;
 
namespace PageReplacement
{
  class Program
  {
     
    // Function to find the frame that will not be used
    // recently in future after given index in pg[0..pn-1]
    static int predict(int[] pg, List<int> fr, int pn, int index)
    {
       
      // Store the index of pages which are going
      // to be used recently in future
      int res = -1;
      int farthest = index;
      for (int i = 0; i < fr.Count; i++)
      {
        int j;
        for (j = index; j < pn; j++)
        {
          if (fr[i] == pg[j])
          {
            if (j > farthest)
            {
              farthest = j;
              res = i;
            }
            break;
          }
        }
 
        // If a page is never referenced in future,
        // return it.
        if (j == pn)
          return i;
      }
 
      // If all of the frames were not in future,
      // return any of them, we return 0. Otherwise
      // we return res.
      return (res == -1) ? 0 : res;
    }
 
    // Function to check whether a page exists
    // in a frame or not
    static bool search(int key, List<int> fr)
    {
      for (int i = 0; i < fr.Count; i++)
      {
        if (fr[i] == key)
          return true;
      }
      return false;
    }
 
    static void optimalPage(int[] pg, int pn, int fn)
    {
       
      // Create an array for given number of
      // frames and initialize it as empty.
      List<int> fr = new List<int>();
 
      // Traverse through page reference array
      // and check for miss and hit.
      int hit = 0;
      for (int i = 0; i < pn; i++)
      {
 
        // Page found in a frame : HIT
        if (search(pg[i], fr))
        {
          hit++;
          continue;
        }
 
        // Page not found in a frame : MISS
 
        // If there is space available in frames.
        if (fr.Count < fn)
          fr.Add(pg[i]);
 
        // Find the page to be replaced.
        else
        {
          int j = predict(pg, fr, pn, i + 1);
          fr[j] = pg[i];
        }
      }
      Console.WriteLine("No. of hits = " + hit);
      Console.WriteLine("No. of misses = " + (pn - hit));
    }
 
    // Driver Function
    public static void Main()
    {
      int[] pg = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2 };
      int pn = pg.Length;
      int fn = 4;
      optimalPage(pg, pn, fn);
    }
  }
}
 
// This code is contributed by ishankhandelwals.


Output

No. of hits = 7
No. of misses = 6

Time Complexity: O(n × f), where n is the number of pages, and f is the number of frames.
Space Complexity: O(f)

  • The above implementation can optimized using hashing. We can use an unordered_set in place of vector so that search operation can be done in O(1) time.
  • Note that optimal page replacement algorithm is not practical as we cannot predict future. However it is used as a reference for other page replacement algorithms.

Another approach for above code is as follow: 

1.Create an empty vector to represent the frames.

2.For each page in the page reference sequence:
a. If the page is found in the current frame, it is considered a hit.
b. If the page is not found in the current frame, it is considered a miss.
i. If there is space available in the frames, the page is added to the frame.
ii. If there is no space available in the frames, find the page that will not be used for the longest duration of time in the future.
iii. Replace the page in the frame with the one that caused the miss.

3.Output the number of hits and misses.

Implementation of above approach 

C++




#include <bits/stdc++.h>
using namespace std;
 
void optimalPage(int pg[], int pn, int fn)
{
    // Create an array for given number of
    // frames and initialize it as empty.
    int fr[fn];
    memset(fr, -1, sizeof(fr)); // set all elements of fr to -1
 
    // Traverse through page reference array
    // and check for miss and hit.
    int hit = 0;
    for (int i = 0; i < pn; i++) {
        // Page found in a frame : HIT
        bool found = false;
        for (int j = 0; j < fn; j++) {
            if (fr[j] == pg[i]) {
                hit++;
                found = true;
                break;
            }
        }
 
        if (found)
            continue;
 
        // Page not found in a frame : MISS
 
        // If there is space available in frames.
        bool emptyFrame = false;
        for (int j = 0; j < fn; j++) {
            if (fr[j] == -1) {
                fr[j] = pg[i];
                emptyFrame = true;
                break;
            }
        }
 
        if (emptyFrame)
            continue;
 
        // Find the page to be replaced.
        int farthest = -1, replaceIndex = -1;
        for (int j = 0; j < fn; j++) {
            int k;
            for (k = i + 1; k < pn; k++) {
                if (fr[j] == pg[k]) {
                    if (k > farthest) {
                        farthest = k;
                        replaceIndex = j;
                    }
                    break;
                }
            }
            if (k == pn) {
                replaceIndex = j;
                break;
            }
        }
        fr[replaceIndex] = pg[i];
    }
    cout << "No. of hits = " << hit << endl;
    cout << "No. of misses = " << pn - hit << endl;
}
 
int main() {
    int pg[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5};
    int pn = sizeof(pg) / sizeof(pg[0]);
    int fn = 4;
    optimalPage(pg, pn, fn);
    return 0;
}
//This code is contributed by snehalsalokhe


Java




import java.util.*;
 
public class Main {
     
    // Function to implement optimal page replacement algorithm
    public static void optimalPage(int[] pg, int pn, int fn) {
         
        // Create an array for given number of frames and initialize it as empty.
        int[] fr = new int[fn];
        Arrays.fill(fr, -1); // set all elements of fr to -1
         
        // Traverse through page reference array and check for miss and hit.
        int hit = 0;
        for (int i = 0; i < pn; i++) {
             
            // Page found in a frame: HIT
            boolean found = false;
            for (int j = 0; j < fn; j++) {
                if (fr[j] == pg[i]) {
                    hit++;
                    found = true;
                    break;
                }
            }
            if (found)
                continue;
             
            // Page not found in a frame: MISS
             
            // If there is space available in frames.
            boolean emptyFrame = false;
            for (int j = 0; j < fn; j++) {
                if (fr[j] == -1) {
                    fr[j] = pg[i];
                    emptyFrame = true;
                    break;
                }
            }
            if (emptyFrame)
                continue;
             
            // Find the page to be replaced.
            int farthest = -1, replaceIndex = -1;
            for (int j = 0; j < fn; j++) {
                int k;
                for (k = i + 1; k < pn; k++) {
                    if (fr[j] == pg[k]) {
                        if (k > farthest) {
                            farthest = k;
                            replaceIndex = j;
                        }
                        break;
                    }
                }
                if (k == pn) {
                    replaceIndex = j;
                    break;
                }
            }
            fr[replaceIndex] = pg[i];
        }
         
        System.out.println("No. of hits = " + hit);
        System.out.println("No. of misses = " + (pn - hit));
    }
     
    // Driver code
    public static void main(String[] args) {
        int[] pg = {1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5};
        int pn = pg.length;
        int fn = 4;
        optimalPage(pg, pn, fn);
    }
}


Python3




import array
 
def optimalPage(pg, pn, fn):
    """
    Function to find the optimal page replacement
    using the optimal page replacement algorithm
    """
    # Create an array for given number of
    # frames and initialize it as empty.
    fr = array.array('i', [-1] * fn)
 
    # Traverse through page reference array
    # and check for miss and hit.
    hit = 0
    for i in range(pn):
        # Page found in a frame : HIT
        found = False
        for j in range(fn):
            if fr[j] == pg[i]:
                hit += 1
                found = True
                break
 
        if found:
            continue
 
        # Page not found in a frame : MISS
 
        # If there is space available in frames.
        emptyFrame = False
        for j in range(fn):
            if fr[j] == -1:
                fr[j] = pg[i]
                emptyFrame = True
                break
 
        if emptyFrame:
            continue
 
        # Find the page to be replaced.
        farthest = -1
        replaceIndex = -1
        for j in range(fn):
            k = i + 1
            while(k < pn):
                if fr[j] == pg[k]:
                    if k > farthest:
                        farthest = k
                        replaceIndex = j
                    break
                k += 1
            if k == pn:
                replaceIndex = j
                break
        fr[replaceIndex] = pg[i]
 
    print("No. of hits =", hit)
    print("No. of misses =", pn - hit)
 
if __name__ == "__main__":
    pg = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5]
    pn = len(pg)
    fn = 4
    optimalPage(pg, pn, fn)


C#




using System;
 
public class Program
{
  public static void OptimalPage(int[] pg, int pn, int fn)
  {
    // Create an array for given number of
    // frames and initialize it as empty.
    int[] fr = new int[fn];
    for (int i = 0; i < fn; i++)
    {
      fr[i] = -1;
    }
 
    // Traverse through page reference array
    // and check for miss and hit.
    int hit = 0;
    for (int i = 0; i < pn; i++)
    {
      // Page found in a frame : HIT
      bool found = false;
      for (int j = 0; j < fn; j++)
      {
        if (fr[j] == pg[i])
        {
          hit++;
          found = true;
          break;
        }
      }
 
      if (found)
      {
        continue;
      }
 
      // Page not found in a frame : MISS
 
      // If there is space available in frames.
      bool emptyFrame = false;
      for (int j = 0; j < fn; j++)
      {
        if (fr[j] == -1)
        {
          fr[j] = pg[i];
          emptyFrame = true;
          break;
        }
      }
 
      if (emptyFrame)
      {
        continue;
      }
 
      // Find the page to be replaced.
      int farthest = -1;
      int replaceIndex = -1;
      for (int j = 0; j < fn; j++)
      {
        int k = i + 1;
        while (k < pn)
        {
          if (fr[j] == pg[k])
          {
            if (k > farthest)
            {
              farthest = k;
              replaceIndex = j;
            }
            break;
          }
          k++;
        }
        if (k == pn)
        {
          replaceIndex = j;
          break;
        }
      }
      fr[replaceIndex] = pg[i];
    }
 
    Console.WriteLine("No. of hits = " + hit);
    Console.WriteLine("No. of misses = " + (pn - hit));
  }
 
  public static void Main()
  {
    int[] pg = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5 };
    int pn = pg.Length;
    int fn = 4;
    OptimalPage(pg, pn, fn);
  }
}
 
// This code is contributed by shivhack999


Javascript




function OptimalPage(pg, pn, fn) {
  // Create an array for given number of
  // frames and initialize it as empty.
  let fr = new Array(fn).fill(-1);
 
  // Traverse through page reference array
  // and check for miss and hit.
  let hit = 0;
  for (let i = 0; i < pn; i++) {
    // Page found in a frame : HIT
    let found = false;
    for (let j = 0; j < fn; j++) {
      if (fr[j] === pg[i]) {
        hit++;
        found = true;
        break;
      }
    }
 
    if (found) {
      continue;
    }
 
    // Page not found in a frame : MISS
 
    // If there is space available in frames.
    let emptyFrame = false;
    for (let j = 0; j < fn; j++) {
      if (fr[j] === -1) {
        fr[j] = pg[i];
        emptyFrame = true;
        break;
      }
    }
 
    if (emptyFrame) {
      continue;
    }
 
    // Find the page to be replaced.
    let farthest = -1;
    let replaceIndex = -1;
    for (let j = 0; j < fn; j++) {
      let k = i + 1;
      while (k < pn) {
        if (fr[j] === pg[k]) {
          if (k > farthest) {
            farthest = k;
            replaceIndex = j;
          }
          break;
        }
        k++;
      }
      if (k === pn) {
        replaceIndex = j;
        break;
      }
    }
    fr[replaceIndex] = pg[i];
  }
 
  console.log("No. of hits = " + hit);
  console.log("No. of misses = " + (pn - hit));
}
 
let pg = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5];
let pn = pg.length;
let fn = 4;
OptimalPage(pg, pn, fn);


Output

No. of hits = 3
No. of misses = 11

Complexity Analysis:

The time complexity of the algorithm depends on the number of page references (pn) and the number of frames (fn). The worst-case time complexity of the algorithm is O(pn * fn^2), which occurs when all page references are unique and there are no empty frames available. In this case, for each page reference, we may have to iterate through all the frames to check if the page is present, and then iterate through all the remaining references to find the page that will not be needed for the longest period of time in the future.

However, in practice, the algorithm performs much better than the worst-case complexity, as it is rare to have all page references unique, and the number of frames is usually limited. Additionally, the algorithm has good performance when there are repeated page references, as it keeps such pages in the frames and minimizes page faults.

Overall, the Optimal Page Replacement algorithm is a useful algorithm for managing page frames in memory, and its time complexity is reasonable in practice.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads