📜  磁带上的最佳存储

📅  最后修改于: 2021-04-29 18:06:06             🧑  作者: Mango

给定n存储在计算机磁带上的程序以及每个程序的长度iL_i在哪里1<=i<=n ,找到应在平均检索时间(MRT为:   \frac{1}{n} \sum_{i=1}^{n} \sum_{j=1}^{i} L_j )最小化。

例子:

Input : n = 3
        L[] = { 5, 3, 10 }
Output : Order should be { 3, 5, 10 } with MRT = 29/3

先决条件:磁带数据存储

让我们首先解决问题,了解需要做什么。

磁带仅提供对数据的顺序访问。在音频磁带/盒式磁带中,与CD不同,不能直接播放磁带中的第五首歌曲。前四首歌曲的长度必须经过才能播放第五首歌曲。因此,为了访问某些数据,应该相应地放置磁带的磁头。

现在,假设磁带中分别有4首歌曲,它们的音频长度分别为5分钟,7分钟,3分钟和2分钟。为了播放第四首歌曲,我们需要遍历5 + 7 + 3 = 15分钟的音频长度,然后放置磁带头。
数据检索时间是指整个检索/访问该数据所花费的时间。因此,第四首歌曲的检索时间为15 + 2 = 17分钟。

现在,考虑到磁带中所有程序的检索均等,并且磁带头每次都指向磁带的前面,因此可以定义一个新的术语,称为平均检索时间(MRT)。

假设程序的检索时间iT_i 。所以, T_i = \sum_{j=1}^{i} L_j
捷运是所有这些的平均值T_i 。所以MRT = \frac{1}{n} \sum_{i=1}^{n} T_i , 或者MRT = \frac{1}{n} \sum_{i=1}^{n} \sum_{j=1}^{i} L_j

磁带中数据的顺序访问有一些限制。必须定义在磁带中存储数据/程序的顺序,这样才能获得最少的MRT。因此,存储顺序对于减少数据检索/访问时间非常重要。
这样,任务就减少了–定义正确的顺序,从而最小化MRT,即最小化术语\sum_{i=1}^{n} \sum_{j=1}^{i} L_i

例如,假设有3个程序,分别为长度2、5和4。因此共有3个! = 6个可能的存储顺序。

Order Total Retrieval Time Mean Retrieval Time
1 1 2 3 2 + (2 + 5) + (2 + 5 + 4) = 20 20/3
2 1 3 2 2 + (2 + 4) + (2 + 4 + 5) = 19 19/3
3 2 1 3 5 + (5 + 2) + (5 + 2 + 4) = 23 23/3
4 2 3 1 5 + (5 + 4) + (5 + 4 + 2) = 25 25/3
5 3 1 2 4 + (4 + 2) + (4 + 2 + 5) = 21 21/3
6 3 2 1 4 + (4 + 5) + (4 + 5 + 2) = 24 24/3

显然,按照存储程序的第二顺序,平均检索时间最少。

在上面的示例中,第一个程序的长度被添加了“ n”次,第二个“ n-1”次……依此类推,直到最后一个程序仅被添加了一次。因此,仔细的分析表明,为了使MRT最小化,应将长度较大的程序放在最后,以便减少总和。或者,程序的长度应按升序排序。那就是使用的贪婪算法–在每一步,我们都立即选择将程序花费最少的时间放在首位,以便逐步为问题建立最终的优化解决方案。

下面是实现:

C++
// CPP Program to find the order
// of programs for which MRT is
// minimized
#include 
  
using namespace std;
  
// This functions outputs the required
// order and Minimum Retrieval Time
void findOrderMRT(int L[], int n)
{
    // Here length of i'th program is L[i]
    sort(L, L + n);
  
    // Lengths of programs sorted according to increasing
    // lengths. This is the order in which the programs
    // have to be stored on tape for minimum MRT
    cout << "Optimal order in which programs are to be"
            "stored is: ";
    for (int i = 0; i < n; i++)
        cout << L[i] << " ";
    cout << endl;
  
    // MRT - Minimum Retrieval Time
    double MRT = 0;
    for (int i = 0; i < n; i++) {
        int sum = 0;
        for (int j = 0; j <= i; j++)
            sum += L[j];
        MRT += sum;
    }
    MRT /= n;
    cout << "Minimum Retrieval Time of this"
           " order is " << MRT;
}
  
// Driver Code to test above function
int main()
{
    int L[] = { 2, 5, 4 };
    int n = sizeof(L) / sizeof(L[0]);
    findOrderMRT(L, n);
    return 0;
}


Java
// Java Program to find the order
// of programs for which MRT is
// minimized
import java.io.*;
import java .util.*;
  
class GFG 
{
  
// This functions outputs 
// the required order and 
// Minimum Retrieval Time
static void findOrderMRT(int []L, 
                         int n)
{
    // Here length of 
    // i'th program is L[i]
    Arrays.sort(L);
  
    // Lengths of programs sorted 
    // according to increasing lengths.
    // This is the order in which 
    // the programs have to be stored
    // on tape for minimum MRT
    System.out.print("Optimal order in which " + 
              "programs are to be stored is: ");
    for (int i = 0; i < n; i++)
        System.out.print(L[i] + " ");
        System.out.println();
  
    // MRT - Minimum Retrieval Time
    double MRT = 0;
    for (int i = 0; i < n; i++) 
    {
        int sum = 0;
        for (int j = 0; j <= i; j++)
            sum += L[j];
        MRT += sum;
    }
    MRT /= n;
    System.out.print( "Minimum Retrieval Time" + 
                    " of this order is " + MRT);
}
  
// Driver Code
public static void main (String[] args) 
{
    int []L = { 2, 5, 4 };
    int n = L.length;
    findOrderMRT(L, n);
}
}
  
// This code is contributed
// by anuj_67.


C#
// C# Program to find the 
// order of programs for 
// which MRT is minimized
using System;
  
class GFG 
{
  
// This functions outputs 
// the required order and 
// Minimum Retrieval Time
static void findOrderMRT(int []L, 
                         int n)
{
    // Here length of 
    // i'th program is L[i]
    Array.Sort(L);
  
    // Lengths of programs sorted 
    // according to increasing lengths.
    // This is the order in which 
    // the programs have to be stored
    // on tape for minimum MRT
    Console.Write("Optimal order in " +   
                  "which programs are" + 
                  " to be stored is: ");
    for (int i = 0; i < n; i++)
        Console.Write(L[i] + " ");
        Console.WriteLine();
  
    // MRT - Minimum Retrieval Time
    double MRT = 0;
    for (int i = 0; i < n; i++) 
    {
        int sum = 0;
        for (int j = 0; j <= i; j++)
            sum += L[j];
        MRT += sum;
    }
    MRT /= n;
    Console.WriteLine("Minimum Retrieval " + 
                  "Time of this order is " + 
                                       MRT);
}
  
// Driver Code
public static void Main () 
{
    int []L = { 2, 5, 4 };
    int n = L.Length;
    findOrderMRT(L, n);
}
}
  
// This code is contributed
// by anuj_67.


输出:

Optimal order in which programs are to be stored are: 2 4 5 
Minimum Retrieval Time of this order is 6.33333

上面程序的时间复杂度是排序的时间复杂度,即O(n lgn) (因为std :: sort()在O(n lgn) )如果您使用冒泡排序而不是std :: sort(),它将需要 O(n^2)

您可能会认为上述特定代码的时间复杂度应归因于“ mrt”计算中的两个循环,也就是说, O(n^2) ,但请记住,从直观上讲,也可以以这种方式对使用的for循环进行编码,以避免两个循环:

for (int i = 0; i < n; i++)
    MRT += (n - i) * L[i];