Pagini recente » Cod sursa (job #2176680) | Cod sursa (job #950448) | Cod sursa (job #2499475) | Cod sursa (job #1347906) | Cod sursa (job #458037)
Cod sursa(job #458037)
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <fstream>
/**
* Matrix chain multiplication. Given n matrices A_1, A_2, ... A_n such that
* A_i has dimension d[i-1] and d[i], what is the optimal parenthesization
* that gives the minimum number of multiplications to compute the product
* A_1 * A_2 * ... * A_n?
*
* Denote A(1, n) as the product of matrices 1 through n.
* To compute A(1, n) optimally we have to compute A(1, k) and A(k+1, n)
* optimally, for an optimal choice of k in [1, n-1].
*
* Denote m[i][j] as the optimal cost of multiplying matrices i through j. Then,
* m[i][j] = min(i <= k < j) of { m[i][k] + m[k+1][j] + d[i-1]d[k]d[j] }
*
* Base cases are m[i][i] = 0, multiplying matrices i through i requires no
* computation. And m[i][i+1] = d[i-1]d[i]d[i+1], multiplying two matrices.
*/
using namespace std;
const unsigned int MAX_MATRICES = 500;
class MatrixChainMultiplication
{
public:
MatrixChainMultiplication(unsigned long long * dimensions, unsigned int numMatrices)
: dim(dimensions), n(numMatrices)
{
for(unsigned int i = 0; i <= MAX_MATRICES; i++)
{
for(unsigned int j = 0; j <= MAX_MATRICES; j++)
{
cost[i][j] = 0;
}
}
for(unsigned int i = 0; i < MAX_MATRICES; i++)
{
cost[i][i+1] = dim[i-1]*dim[i]*dim[i+1];
}
}
public:
unsigned long long computeRecursive()
{
return recursive(1, n);;
}
unsigned long long computeIterative()
{
/**
* Compute the optimal parenthesization of matrix products of
* increasing sizes, starting at 3 (1 and 2 are trivial) and
* going up to n, which will give you the solution.
*
* So we'll compute cost[i, i + size], for i going up to n - size to stay
* within bounds.
*/
for(unsigned int size = 2; size < n; size++)
{
for(unsigned int i = 1; i <= n - size; i++)
{
unsigned int j = i + size;
cost[i][j] = ~0;
for(unsigned int k = i; k < j; k++)
{
unsigned long long cost_mult = dim[i-1] * dim[k] * dim[j];
unsigned long long current_cost = cost[i][k] + cost[k+1][j] + cost_mult;
if(cost[i][j] > current_cost)
{
cost[i][j] = current_cost;
}
}
}
}
return cost[1][n];
}
private:
/**
* Use caching for simple and easy implementation.
*/
unsigned long long recursive(unsigned int i, unsigned int j)
{
if(i == j)
return 0;
else if(cost[i][j])
return cost[i][j];
else
{
unsigned long long min_k = ~0;
for(unsigned int k = i; k < j; k++)
{
unsigned long long current_cost, cost_ik, cost_kj, cost_mult;
cost_mult = dim[i-1] * dim[k] * dim[j];
cost_ik = recursive(i, k);
cost_kj = recursive(k+1, j);
current_cost = cost_ik + cost_kj + cost_mult;
if(current_cost < min_k)
min_k = current_cost;
}
cost[i][j] = min_k;
return cost[i][j];
}
}
private:
unsigned long long * dim;
unsigned int n;
unsigned long long cost[MAX_MATRICES + 1][MAX_MATRICES + 1];
};
int main(int argc, char ** argv)
{
const char * inFile = "podm.in";
const char * outFile = "podm.out";
ifstream fin(inFile);
ofstream fout(outFile);
/**
* Read the data in.
*/
unsigned int n;
fin >> n;
unsigned long long d[n + 1];
for(unsigned int i = 0; i <= n; i++)
{
fin >> d[i];
}
fin.close();
/**
* Write out the result.
*/
MatrixChainMultiplication mcm(d, n);
fout << mcm.computeRecursive();
fout.close();
return 0;
}