有点算法问题,或者可能是优化问题,或动态编程。
我们说我们要压缩N个文件。 平均压缩比为L. 文件的压缩时间取决于两个因素 - 1.当前正在处理的文件的大小,以及 2.系统中剩余的内存空间(总计= M,占用=压缩和未压缩文件的文件大小之和)
所以
t(i) = K * s(i) / (M-L*(s(1)+s(2)+....+s(i))-(s(i+1) + s(i+2) + .....+ s(n))
其中s(i)是第i个文件的大小,t(i)是压缩第i个文件所用的时间。
我要做的是计算要压缩的文件的最佳系列,以便所需的总时间最短。那么如何计算该系列呢?
答案 0 :(得分:2)
似乎最好的方法是按大小对文件进行排序并对其进行处理。这种贪婪的方法可以解释为“首先压缩小文件以避免在大文件后压缩它”。
可能的批准是:
如果我们有两个文件A,B这样大小(A)< = size(B)我们可以证明那个时间
t(A,B)< = t(B,A)
A / M + B /(M - L * A)< = B / M + B /(M - L * B)
A *(1 / M - 1 /(M - L * B))< = B *(1 / M - 1 /(M - L * A))
B / A> =(1 / M-1 /(M-L * B))/(1 / M-1 /(M-L * A))= B *(M-L * A) /(A *(M - L * B))
1> =(M-L * A)/(M-L * B)
-L * B> = -L * A
B> = A
所以这意味着第一个方程式也是正确的(如果没有在某处失败:D)
排序给我们保证A< B为每对文件。
我为N< = 10编写了O(N!)bruteforce。它为我能想到的每个测试提供了排序数组。
测试:N,L,M,K和N文件
8 0.5 80.0 1.0
7 1 6 3 4 5 6 5
结果:
0.515769
1 3 4 5 5 6 6 7
#include <iostream>
#include <algorithm>
using namespace std;
// will work bad for cnt > 10 because 10! = 3628800
int perm[] = {0,1,2,3,4,5,6,7,8,9};
int bestPerm[10];
double sizes[10];
double calc(int cnt, double L, double M, double K, double T) {
double res = 0.0, usedMemory = 0.0;
for(int i = 0; i < cnt; i++) {
int ind = perm[i];
res += K * sizes[ind] / (M - L * usedMemory - (T - usedMemory));
usedMemory += sizes[ind];
}
return res;
}
int main() {
int cnt;
double L,M,K,T = 0.0;
cin >> cnt >> L >> M >> K;
for(int i = 0; i < cnt; i++)
cin >> sizes[i], T += sizes[i];
double bruteRes = 1e16;
int bruteCnt = 1;
for(int i = 2; i <= cnt; i++)
bruteCnt *= i;
for(int i = 0; i < bruteCnt; i++) {
double curRes = calc(cnt, L, M, K, T);
if( bruteRes > curRes ) {
bruteRes = curRes;
for(int j = 0; j < cnt; j++)
bestPerm[j] = perm[j];
}
next_permutation(perm, perm + cnt);
}
cout << bruteRes << "\n";
for(int i = 0; i < cnt; i++)
cout << sizes[bestPerm[i]] << " ";
cout << "\n";
return 0;
}
已更新对于所有文件pastebin的L不同的情况的实现(看起来bruteforce更喜欢按压缩比L [i]的降序对它们进行排序并使用较小的文件首先,如果L相等)。
答案 1 :(得分:0)
假设您有一个声称最佳的计划。考虑任何文件和紧随其后处理的文件。如果您可以通过交换它们来改进计划,那么它可能不是最佳的。因此,如果您可以证明最好在大文件之前处理一个小文件,而这两个文件并排放置,那么您可以首先显示最佳日程安排的排序顺序,因为您可以改进任何其他文件时间表。
因为您只是交换两个相邻文件,所以在这两个文件之前和之后处理文件所花费的时间都没有改变 - 前后可用的内存量相同。您也可以扩展问题,以便其中一个文件大小为一个单位。假设您在第一个文件之前总共有K个单位的内存空闲,并且假设第二个文件的大小为x个单位且压缩比为1:L,则最终会得到类似1 / K + x /(K +)的内容L) - x / K - 1 /(K - xL)作为由于这对文件导致的压缩时间的差异 - 我的代数非常容易出错,但我认为这可以归结为像L ^ 2x(1- x)复杂但积极的东西,这表明对于一对文件,你总是想先压缩短文件,所以我之前说过的最好的时间表是按照最短文件的排序顺序。