Prerequisite: Optimal Storage on Tapes
You are given tapes[] of different sizes and records[] of different volumes. The task is to fill the volumes in tapes horizontally or vertically such that Retrieval Time is minimised.
Examples:
Input: tape[] = { 25, 80, 160}, records[] = { 15, 2, 8, 23, 45, 50, 60, 120 }
Output:
Horizontal Filling:
1st tape : [ 2 8 15 ] MRT : 12.3333
2nd tape : [ 23 45 ] MRT : 45.5
3rd tape : [ 50 60 ] MRT : 80
Vertical Filling:
1st tape : [ 2 23 ] MRT : 13.5
2nd tape : [ 8 45 ] MRT : 30.5
3rd tape : [ 15 50 60 ] MRT : 68.3333
For Minimum Retrieval Time we will insert volumes of records in increasing order of their size.
The formula for Minimum Retrieval Time is:
MRT = (1/N)*Σ(A(i)*(N-i)) where 0 ≤ i < N
There are two ways of adding volumes on tapes for reducing retrieval time:
- Horizontal Retrieval
- Vertical Retrieval
Horizontal Retrieval
We have,
tapes[] = { 25, 80, 160}
records[] = { 2, 8, 15, 23, 45, 50, 60, 120 } (in increasing order)
Horizontal Filling on tape:
- Inserting 2
1st tape : [ 2 ] 2nd tape : [ ] 3rd tape : [ ]
- Inserting 8
1st tape : [ 2 8 ] 2nd tape : [ ] 3rd tape : [ ]
- Inserting 15
1st tape : [ 2 8 15 ] 2nd tape : [ ] 3rd tape : [ ]
- Inserting 23
1st tape : [ 2 8 15 ] 2nd tape : [ 23 ] 3rd tape : [ ]
- Inserting 45
1st tape : [ 2 8 15 ] 2nd tape : [ 23 45 ] 3rd tape : [ ]
- Inserting 50
1st tape : [ 2 8 15 ] 2nd tape : [ 23 45 ] 3rd tape : [ 50 ]
- Inserting 60
1st tape : [ 2 8 15 ] 2nd tape : [ 23 45 ] 3rd tape : [ 50 60 ]
Below is the program for Horizontal Filling
// C++ program to print Horizontal // filling #include <bits/stdc++.h> using namespace std;
void horizontalFill( int records[],
int tape[], int nt)
{ // It is used for checking whether
// tape is full or not
int sum = 0;
// It is used for calculating
// total retrieval time
int Retrieval_Time = 0;
// It is used for calculating
// mean retrieval time
double Mrt;
int current = 0;
// vector is used because n number of
// records can insert in one tape with
// size constraint
vector< int > v;
for ( int i = 0; i < nt; i++) {
// Null vector obtained to use fresh
// vector 'v'
v.clear();
Retrieval_Time = 0;
// initialize variables to
// 0 for each iteration
sum = 0;
cout << "tape " << i + 1 << " : [ " ;
// sum is used for checking whether
// i'th tape is full or not
sum += records[current];
// check sum less than size of tape
while (sum <= tape[i]) {
cout << records[current] << " " ;
v.push_back(records[current]);
// increment in j for next record
current++;
sum += records[current];
}
cout << "]" ;
// calculating total retrieval
// time
for ( int i = 0; i < v.size(); i++) {
// MRT formula
Retrieval_Time += v[i] * (v.size() - i);
}
// calculating mean retrieval time
// using formula
Mrt = ( double )Retrieval_Time / v.size();
// v.size() is function of vector is used
// to get size of vector
cout << "\tMRT : " << Mrt << endl;
}
} // Driver Code int main()
{ int records[] = { 15, 2, 8, 23, 45, 50, 60, 120 };
int tape[] = { 25, 80, 160 };
// store the size of records[]
int n = sizeof (records) / sizeof (records[0]);
// store the size of tapes[]
int m = sizeof (tape) / sizeof (tape[0]);
// sorting of an array is required to
// attain greedy approach of
// algorithm
sort(records, records + n);
horizontalFill(records, tape, m);
} |
// Java program to print Horizontal // filling import java.util.*;
class GFG
{ static void horizontalFill( int records[],
int tape[], int nt)
{ // It is used for checking whether
// tape is full or not
int sum = 0 ;
// It is used for calculating
// total retrieval time
int Retrieval_Time = 0 ;
// It is used for calculating
// mean retrieval time
double Mrt;
int current = 0 ;
// vector is used because n number of
// records can insert in one tape with
// size constraint
Vector<Integer> v = new Vector<Integer>();
for ( int i = 0 ; i < nt; i++)
{
// Null vector obtained to use fresh
// vector 'v'
v.clear();
Retrieval_Time = 0 ;
// initialize variables to
// 0 for each iteration
sum = 0 ;
System.out.print( "tape " + (i + 1 ) + " : [ " );
// sum is used for checking whether
// i'th tape is full or not
sum += records[current];
// check sum less than size of tape
while (sum <= tape[i])
{
System.out.print(records[current] + " " );
v.add(records[current]);
// increment in j for next record
current++;
sum += records[current];
}
System.out.print( "]" );
// calculating total retrieval
// time
for ( int j = 0 ; j < v.size(); j++)
{
// MRT formula
Retrieval_Time += v.get(j) * (v.size() - j);
}
// calculating mean retrieval time
// using formula
Mrt = ( double )Retrieval_Time / v.size();
// v.size() is function of vector is used
// to get size of vector
System.out.print( "\tMRT : " + Mrt + "\n" );
}
} // Driver Code public static void main(String[] args)
{ int records[] = { 15 , 2 , 8 , 23 , 45 , 50 , 60 , 120 };
int tape[] = { 25 , 80 , 160 };
// store the size of records[]
int n = records.length;
// store the size of tapes[]
int m = tape.length;
// sorting of an array is required to
// attain greedy approach of
// algorithm
Arrays.sort(records);
horizontalFill(records, tape, m);
} } // This code is contributed by 29AjayKumar |
# Python3 program to print Horizontal # filling def horizontalFill(records, tape, nt) :
# It is used for checking whether
# tape is full or not
sum = 0 ;
# It is used for calculating
# total retrieval time
Retrieval_Time = 0 ;
# It is used for calculating
# mean retrieval time
current = 0 ;
# vector is used because n number of
# records can insert in one tape with
# size constraint
v = [];
for i in range (nt) :
# Null vector obtained to use fresh
# vector 'v'
v.clear();
Retrieval_Time = 0 ;
# initialize variables to
# 0 for each iteration
sum = 0 ;
print ( "tape" , i + 1 , ": [ " ,end = "");
# sum is used for checking whether
# i'th tape is full or not
sum + = records[current];
# check sum less than size of tape
while ( sum < = tape[i]) :
print (records[current],end = " " );
v.append(records[current]);
# increment in j for next record
current + = 1 ;
sum + = records[current];
print ( "]" ,end = "");
# calculating total retrieval
# time
for i in range ( len (v)) :
# MRT formula
Retrieval_Time + = v[i] * ( len (v) - i);
# calculating mean retrieval time
# using formula
Mrt = Retrieval_Time / len (v);
# v.size() is function of vector is used
# to get size of vector
print ( "tMRT :" , Mrt);
# Driver Code if __name__ = = "__main__" :
records = [ 15 , 2 , 8 , 23 , 45 , 50 , 60 , 120 ];
tape = [ 25 , 80 , 160 ];
# store the size of records[]
n = len (records);
# store the size of tapes[]
m = len (tape);
# sorting of an array is required to
# attain greedy approach of
# algorithm
records.sort();
horizontalFill(records, tape, m);
# This code is contributed by AnkitRai01 |
// C# program to print Horizontal // filling using System;
using System.Collections.Generic;
class GFG
{ static void horizontalFill( int []records,
int []tape, int nt)
{ // It is used for checking whether
// tape is full or not
int sum = 0;
// It is used for calculating
// total retrieval time
int Retrieval_Time = 0;
// It is used for calculating
// mean retrieval time
double Mrt;
int current = 0;
// vector is used because n number of
// records can insert in one tape with
// size constraint
List< int > v = new List< int >();
for ( int i = 0; i < nt; i++)
{
// Null vector obtained to use fresh
// vector 'v'
v.Clear();
Retrieval_Time = 0;
// initialize variables to
// 0 for each iteration
sum = 0;
Console.Write( "tape " + (i + 1) + " : [ " );
// sum is used for checking whether
// i'th tape is full or not
sum += records[current];
// check sum less than size of tape
while (sum <= tape[i])
{
Console.Write(records[current] + " " );
v.Add(records[current]);
// increment in j for next record
current++;
sum += records[current];
}
Console.Write( "]" );
// calculating total retrieval
// time
for ( int j = 0; j < v.Count; j++)
{
// MRT formula
Retrieval_Time += v[j] * (v.Count - j);
}
// calculating mean retrieval time
// using formula
Mrt = ( double )Retrieval_Time / v.Count;
// v.Count is function of vector is used
// to get size of vector
Console.Write( "\tMRT : " + Mrt + "\n" );
}
} // Driver Code public static void Main(String[] args)
{ int []records = { 15, 2, 8, 23, 45, 50, 60, 120 };
int []tape = { 25, 80, 160 };
// store the size of records[]
int n = records.Length;
// store the size of tapes[]
int m = tape.Length;
// sorting of an array is required to
// attain greedy approach of
// algorithm
Array.Sort(records);
horizontalFill(records, tape, m);
} } // This code is contributed by 29AjayKumar |
<script> // Javascript program to print Horizontal filling
function horizontalFill(records, tape, nt)
{
// It is used for checking whether
// tape is full or not
let sum = 0;
// It is used for calculating
// total retrieval time
let Retrieval_Time = 0;
// It is used for calculating
// mean retrieval time
let Mrt;
let current = 0;
// vector is used because n number of
// records can insert in one tape with
// size constraint
let v = [];
for (let i = 0; i < nt; i++)
{
// Null vector obtained to use fresh
// vector 'v'
v = [];
Retrieval_Time = 0;
// initialize variables to
// 0 for each iteration
sum = 0;
document.write( "tape " + (i + 1) + " : [ " );
// sum is used for checking whether
// i'th tape is full or not
sum += records[current];
// check sum less than size of tape
while (sum <= tape[i])
{
document.write(records[current] + " " );
v.push(records[current]);
// increment in j for next record
current++;
sum += records[current];
}
document.write( "]" );
// calculating total retrieval
// time
for (let j = 0; j < v.length; j++)
{
// MRT formula
Retrieval_Time += v[j] * (v.length - j);
}
// calculating mean retrieval time
// using formula
Mrt = Retrieval_Time / v.length;
// v.size() is function of vector is used
// to get size of vector
if (i == 0)
{
document.write( " MRT : " + Mrt.toFixed(4) + "</br>" );
}
else {
document.write( " MRT : " + Mrt + "</br>" );
}
}
}
let records = [ 15, 2, 8, 23, 45, 50, 60, 120 ];
let tape = [ 25, 80, 160 ];
// store the size of records[]
let n = records.length;
// store the size of tapes[]
let m = tape.length;
// sorting of an array is required to
// attain greedy approach of
// algorithm
records.sort( function (a, b){ return a - b});
horizontalFill(records, tape, m);
// This code is contributed by suresh07. </script> |
tape 1 : [ 2 8 15 ] MRT : 12.3333 tape 2 : [ 23 45 ] MRT : 45.5 tape 3 : [ 50 60 ] MRT : 80
Time complexity: O(nt2), where n is the number of records and t is the number of tapes.
Space complexity: O(n),
Vertical Retrieval
Vertical Filling on tape:
- Inserting 2
1st tape : [ 2 ] 2nd tape : [ ] 3rd tape : [ ]
- Inserting 8
1st tape : [ 2 ] 2nd tape : [ 8 ] 3rd tape : [ ]
- Inserting 15
1st tape : [ 2 ] 2nd tape : [ 8 ] 3rd tape : [ 15 ]
- Inserting 23
1st tape : [ 2 23 ] 2nd tape : [ 8 ] 3rd tape : [ 15 ]
- Inserting 45
1st tape : [ 2 23 ] 2nd tape : [ 8 45 ] 3rd tape : [ 15 ]
- Inserting 50
1st tape : [ 2 23 ] 2nd tape : [ 8 45 ] 3rd tape : [ 15 50 ]
- Inserting 60
1st tape : [ 2 23 60 ] 2nd tape : [ 8 45 ] 3rd tape : [ 15 50 ]
Below is the program for Vertical Filling
// C++ program to print Vertical filling #include <bits/stdc++.h> using namespace std;
void vertical_Fill( int records[], int tape[],
int m, int n)
{ // 2D matrix for vertical insertion on
// tapes
int v[m][n] = { 0 };
// It is used for checking whether tape
// is full or not
int sum = 0;
// It is used for calculating total
// retrieval time
int Retrieval_Time = 0;
// It is used for calculating mean
// retrieval time
double Mrt;
// It is used for calculating mean
// retrieval time
int z = 0, j = 0;
// vertical insertion on tape
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < m; j++) {
// initialize variables to
// 0 for each iteration
sum = 0;
// Used for getting 'sum' sizes
// of records in tape to determine
// whether tape is full or not
for ( int k = 0; k < i; k++) {
sum += v[j][k];
}
// if tape is not full
if (sum + records[z] <= tape[j]) {
v[j][i] = records[z];
z++;
}
}
// check for ability of tapes to hold
// value
if (v[2][i] == 0) {
break ;
}
}
for ( int i = 0; i < m; i++) {
// initialize variables to 0 for each
// iteration
Retrieval_Time = 0;
// display elements of tape
cout << "tape " << i + 1 << " : [ " ;
for (j = 0; j < n; j++) {
if (v[i][j] != 0) {
cout << v[i][j] << " " ;
}
else {
break ;
}
}
cout << "]" ;
// calculating total retrieval time
for ( int k = 0; v[i][k] != 0; k++) {
// MRT formula
Retrieval_Time += v[i][k] * (j - k);
}
// calculating mean retrieval time
// using formula
Mrt = ( double )Retrieval_Time / j;
// v.size() is function of vector is used
// to get size of vector
cout << "\tMRT : " << Mrt << endl;
}
} // Driver Code int main()
{ int records[] = { 15, 2, 8, 23, 45, 50, 60, 120 };
int tape[] = { 25, 80, 160 };
// store the size of records[]
int n = sizeof (records) / sizeof (records[0]);
// store the size of tapes[]
int m = sizeof (tape) / sizeof (tape[0]);
// sorting of an array is required to
// attain greedy approach of
// algorithm
sort(records, records + n);
vertical_Fill(records, tape, m, n);
return 0;
} |
// Java program to print Vertical filling import java.util.*;
class GFG
{ static void vertical_Fill( int records[], int tape[],
int m, int n)
{ // 2D matrix for vertical insertion on
// tapes
int [][]v = new int [m][n];
// It is used for checking whether tape
// is full or not
int sum = 0 ;
// It is used for calculating total
// retrieval time
int Retrieval_Time = 0 ;
// It is used for calculating mean
// retrieval time
double Mrt;
// It is used for calculating mean
// retrieval time
int z = 0 , j = 0 ;
// vertical insertion on tape
for ( int i = 0 ; i < n; i++)
{
for (j = 0 ; j < m; j++)
{
// initialize variables to
// 0 for each iteration
sum = 0 ;
// Used for getting 'sum' sizes
// of records in tape to determine
// whether tape is full or not
for ( int k = 0 ; k < i; k++)
{
sum += v[j][k];
}
// if tape is not full
if (sum + records[z] <= tape[j])
{
v[j][i] = records[z];
z++;
}
}
// check for ability of tapes to hold
// value
if (v[ 2 ][i] == 0 )
{
break ;
}
}
for ( int i = 0 ; i < m; i++)
{
// initialize variables to 0 for each
// iteration
Retrieval_Time = 0 ;
// display elements of tape
System.out.print( "tape " + (i + 1 )+ " : [ " );
for (j = 0 ; j < n; j++)
{
if (v[i][j] != 0 )
{
System.out.print(v[i][j]+ " " );
}
else
{
break ;
}
}
System.out.print( "]" );
// calculating total retrieval time
for ( int k = 0 ; v[i][k] != 0 ; k++)
{
// MRT formula
Retrieval_Time += v[i][k] * (j - k);
}
// calculating mean retrieval time
// using formula
Mrt = ( double )Retrieval_Time / j;
// v.size() is function of vector is used
// to get size of vector
System.out.print( "\tMRT : " + Mrt + "\n" );
}
} // Driver Code public static void main(String[] args)
{ int records[] = { 15 , 2 , 8 , 23 , 45 , 50 , 60 , 120 };
int tape[] = { 25 , 80 , 160 };
// store the size of records[]
int n = records.length;
// store the size of tapes[]
int m = tape.length;
// sorting of an array is required to
// attain greedy approach of
// algorithm
Arrays.sort(records);
vertical_Fill(records, tape, m, n);
} } // This code is contributed by 29AjayKumar |
# Python3 program to print Vertical filling import numpy as np
def vertical_Fill(records, tape, m, n) :
# 2D matrix for vertical insertion on
# tapes
v = np.zeros((m, n)) ;
# It is used for checking whether tape
# is full or not
sum = 0 ;
# It is used for calculating total
# retrieval time
Retrieval_Time = 0 ;
# It is used for calculating mean
# retrieval time
Mrt = None ;
# It is used for calculating mean
# retrieval time
z = 0 ; j = 0 ;
# vertical insertion on tape
for i in range (n) :
for j in range (m) :
# initialize variables to
# 0 for each iteration
sum = 0 ;
# Used for getting 'sum' sizes
# of records in tape to determine
# whether tape is full or not
for k in range (i) :
sum + = v[j][k];
# if tape is not full
if ( sum + records[z] < = tape[j]) :
v[j][i] = records[z];
z + = 1 ;
# check for ability of tapes to hold
# value
if (v[ 2 ][i] = = 0 ) :
break ;
for i in range (m) :
# initialize variables to 0 for each
# iteration
Retrieval_Time = 0 ;
# display elements of tape
print ( "tape" , i + 1 , ": [" , end = "");
for j in range (n) :
if (v[i][j] ! = 0 ) :
print (v[i][j], end = " " );
else :
break ;
print ( "]" , end = "");
k = 0 ;
# calculating total retrieval time
while v[i][k] ! = 0 :
# MRT formula
Retrieval_Time + = v[i][k] * (j - k);
k + = 1 ;
# calculating mean retrieval time
# using formula
Mrt = Retrieval_Time / j;
# v.size() is function of vector is used
# to get size of vector
print ( "MRT :" , Mrt);
# Driver Code if __name__ = = "__main__" :
records = [ 15 , 2 , 8 , 23 , 45 , 50 , 60 , 120 ];
tape = [ 25 , 80 , 160 ];
# store the size of records[]
n = len (records);
# store the size of tape[]
m = len (tape);
# sorting of an array is required to
# attain greedy approach of
# algorithm
records.sort();
vertical_Fill(records, tape, m, n);
# This code is contributed by AnkitRai01 |
// C# program to print Vertical filling using System;
class GFG
{ static void vertical_Fill( int []records, int []tape,
int m, int n)
{ // 2D matrix for vertical insertion on
// tapes
int [,]v = new int [m, n];
// It is used for checking whether tape
// is full or not
int sum = 0;
// It is used for calculating total
// retrieval time
int Retrieval_Time = 0;
// It is used for calculating mean
// retrieval time
double Mrt;
// It is used for calculating mean
// retrieval time
int z = 0, j = 0;
// vertical insertion on tape
for ( int i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
// initialize variables to
// 0 for each iteration
sum = 0;
// Used for getting 'sum' sizes
// of records in tape to determine
// whether tape is full or not
for ( int k = 0; k < i; k++)
{
sum += v[j, k];
}
// if tape is not full
if (sum + records[z] <= tape[j])
{
v[j, i] = records[z];
z++;
}
}
// check for ability of tapes to hold
// value
if (v[2, i] == 0)
{
break ;
}
}
for ( int i = 0; i < m; i++)
{
// initialize variables to 0 for each
// iteration
Retrieval_Time = 0;
// display elements of tape
Console.Write( "tape " + (i + 1) + " : [ " );
for (j = 0; j < n; j++)
{
if (v[i, j] != 0)
{
Console.Write(v[i, j]+ " " );
}
else
{
break ;
}
}
Console.Write( "]" );
// calculating total retrieval time
for ( int k = 0; v[i, k] != 0; k++)
{
// MRT formula
Retrieval_Time += v[i, k] * (j - k);
}
// calculating mean retrieval time
// using formula
Mrt = ( double )Retrieval_Time / j;
// v.Count is function of vector is used
// to get size of vector
Console.Write( "\tMRT : " + Mrt + "\n" );
}
} // Driver Code public static void Main(String[] args)
{ int []records = { 15, 2, 8, 23, 45, 50, 60, 120 };
int []tape = { 25, 80, 160 };
// store the size of records[]
int n = records.Length;
// store the size of tapes[]
int m = tape.Length;
// sorting of an array is required to
// attain greedy approach of
// algorithm
Array.Sort(records);
vertical_Fill(records, tape, m, n);
} } // This code is contributed by 29AjayKumar |
<script> // Javascript program to print Vertical filling
function vertical_Fill(records, tape, m, n)
{
// 2D matrix for vertical insertion on
// tapes
let v = new Array(m);
for (let i = 0; i < m; i++)
{
v[i] = new Array(n);
for (let j = 0; j < n; j++)
{
v[i][j] = 0;
}
}
// It is used for checking whether tape
// is full or not
let sum = 0;
// It is used for calculating total
// retrieval time
let Retrieval_Time = 0;
// It is used for calculating mean
// retrieval time
let Mrt;
// It is used for calculating mean
// retrieval time
let z = 0, j = 0;
// vertical insertion on tape
for (let i = 0; i < n; i++)
{
for (let j = 0; j < m; j++)
{
// initialize variables to
// 0 for each iteration
sum = 0;
// Used for getting 'sum' sizes
// of records in tape to determine
// whether tape is full or not
for (let k = 0; k < i; k++)
{
sum += v[j][k];
}
// if tape is not full
if (sum + records[z] <= tape[j])
{
v[j][i] = records[z];
z++;
}
}
// check for ability of tapes to hold
// value
if (v[2][i] == 0)
{
break ;
}
}
for (let i = 0; i < m; i++)
{
// initialize variables to 0 for each
// iteration
Retrieval_Time = 0;
// display elements of tape
document.write( "tape " + (i + 1)+ " : [ " );
for (j = 0; j < n; j++)
{
if (v[i][j] != 0)
{
document.write(v[i][j]+ " " );
}
else
{
break ;
}
}
document.write( "]" );
// calculating total retrieval time
for (let k = 0; v[i][k] != 0; k++)
{
// MRT formula
Retrieval_Time += v[i][k] * (j - k);
}
// calculating mean retrieval time
// using formula
Mrt = Retrieval_Time / j;
// v.size() is function of vector is used
// to get size of vector
if (i != m - 1)
{
document.write( " MRT : " + Mrt + "</br>" );
}
else {
document.write( " MRT : " + Mrt.toFixed(4) + "</br>" );
}
}
}
let records = [ 15, 2, 8, 23, 45, 50, 60, 120 ];
let tape = [ 25, 80, 160 ];
// store the size of records[]
let n = records.length;
// store the size of tapes[]
let m = tape.length;
// sorting of an array is required to
// attain greedy approach of
// algorithm
records.sort( function (a, b){ return a - b});
vertical_Fill(records, tape, m, n);
// This code is contributed divyesh072019.
</script> |
tape 1 : [ 2 23 ] MRT : 13.5 tape 2 : [ 8 45 ] MRT : 30.5 tape 3 : [ 15 50 60 ] MRT : 68.3333
Time complexity: O(n * m2), where n is the number of records and m is the number of tapes.
Space complexity: O(m * n)
Comparing both the results we can use a particular tape filling technique which provides the best results(minimum MRT).