偶然发现了去年上算法分析课程时作业题目的解答程序,发给有需要的朋友参考。
(一)动态规划法解01背包问题
01背包问题例如:某商店有n个物品,第i个物品的价值为v,重量为w。背包的容量为W。那么如何选取物品,使得背包里的物品的价值总和最大?
#include "stdafx.h"
#include <stdlib.h>
#include "iostream.h"
#include <time.h>
const int RandValue=200;
const int RandValue2=50;
int Max=0;
const int N=700;
const int W=2000;
int w[N];
int v[N];
/*
const int N=5;
const int W=17;
int w[N]={3,4,7,8,9};
int v[N]={4,5,10,11,13};
*/
int c[N+1][W+1]; //记录表
int x[N+1];
void getValue(void)
{
w[0]=1+rand()%RandValue;
v[0]=1+rand()%RandValue;
for(int i=1;i<N;i++)
{
w[i]=w[i-1]+rand()%RandValue2;
v[i]=w[i]+rand()%RandValue2;
}
}
void OutPut(int M[N])
{
for(int i=0;i<N;i++)
{
cout<<M[i]<<endl;
}
}
void OutPutC(void)
{
cout<<"c[1][1] → c["<<N<<"]["<<W<<"]"<<endl;
for(int i=1;i<N+1;i++)
{ cout<<i<<"│"<<" ";
for(int j=1;j<W+1;j++)
{int t1=c[i][j]/10;
int t2=c[i][j]/100;
if(t1==0 && t2==0){cout<<c[i][j]<<" ";}
if(t1!=0 && t2==0){cout<<c[i][j]<<" ";}
if(t1!=0 && t2!=0){cout<<c[i][j]<<" ";}
}
cout<<endl;
}
}
///Begin_RECUR
int RECUR_KNAP(int i,int temp_W) //开始i=0 (i为第i+1个物品)
{
int max=0;
for(i;i<N;i++)
{
if(temp_W-w[i]>=0)
{ int value=RECUR_KNAP(i+1,temp_W-w[i]);
if(value+v[i]>max)
{
max=value+v[i];
}
}
}
return max;
}
/End_RECUR
/Begin_KNAPSACK
void KNAPSACK_DP(int n,int temp_W)
{
for(int temp_w=0;temp_w<=temp_W;temp_w++)
{
c[0][temp_w]=0;
}
for(int i=1;i<=n;i++)
{
c[i][0]=0;
for(temp_w=1;temp_w<=temp_W;temp_w++)
{
if(w[i-1]<=temp_w)
{
if(v[i-1]+c[i-1][temp_w-w[i-1]]>c[i-1][temp_w])
{
c[i][temp_w]=v[i-1]+c[i-1][temp_w-w[i-1]];
}else
{
c[i][temp_w]=c[i-1][temp_w];
}
}else
{
c[i][temp_w]=c[i-1][temp_w];
}
}
}
}
void OUTPUT_SACK(int temp_w)
{ x[0]=0;
for(int i=N;i>=1;i--)
{
if(c[i][temp_w]==c[i-1][temp_w])
{
x[i]=0;
}
else
{
x[i]=1;
temp_w=temp_w-w[i-1];
}
}
}
///End_KNAPSACK
void OutPutX(void)
{
for(int i=1;i<=N;i++)
{
cout<<"x["<<i<<"]="<<x[i]<<endl;
}
}
/
int main(int argc, char* argv[])
{
clock_t start1, finish1,start2, finish2;
getValue(); //获取随机值
cout<<"分别用递归和动态规划算法解01背包问题/n"<<"物品个数:"<<N<<"/n"<<"背包容量:"<<W<<endl;
cout<<"/n解:/n是否打印物品重量和价值数组(Y/N)?"<<endl;
char A,B;
cin>>A;
if(A=='Y' || A=='y')
{
OutPut(w); //显示重量数组
OutPut(v); //显示价值数组
}
cout<<"运行....."<<"/n"<<endl;
start1 = clock();
Max=RECUR_KNAP(0,W); //递归算法
finish1=clock();
start2 = clock();
KNAPSACK_DP(N,W); //动态规划算法
OUTPUT_SACK(W); //计算解向量
finish2 = clock();
cout<<"递归算法:"<<endl;
cout<<"最优解:"<<Max<<endl;
cout<<"用时(ms):"<<finish1-start1<<endl;
cout<<endl;
cout<<"动态规划算法:"<<endl;
cout<<"最优解:"<<c[N][W]<<endl;
cout<<"用时(ms):"<<finish2-start2<<endl;
cout<<"是否打印辅助表(Y/N)?"<<endl;
cin>>A;
cout<<"是否打印解向量(Y/N)?"<<endl;
cin>>B;
if(A=='Y' || A=='y')
{
OutPutC(); //显示记录表
}
if(B=='Y' || B=='y')
{
OutPutX(); //显示解向量
}
if( (A=='N' ||A=='n') && (B=='N' || B=='n') )
{
return 0;
}
int u;
cin>>u;
return 0;
}
运行结果图:
(二)矩阵相乘算法对比
两个矩阵相乘,改进的矩阵乘法,用分治法。
#include "stdafx.h"
#include <stdlib.h>
#include "iostream.h"
#include <time.h>
/*
┌ ┐ ┌ ┐ ┌ ┐
│C11 C12│ │A11 A12│ │B11 B12│
│C21 C22│=│A21 A22│*│B21 B22│
└ ┘ └ ┘ └ ┘
*/
const int N=700;
int Max_Value=4;
int A11[N/2][N/2];
int A12[N/2][N/2];
int A21[N/2][N/2];
int A22[N/2][N/2];
int B11[N/2][N/2];
int B12[N/2][N/2];
int B21[N/2][N/2];
int B22[N/2][N/2];
int C11[N/2][N/2];
int C12[N/2][N/2];
int C21[N/2][N/2];
int C22[N/2][N/2];
//Temp
int Temp1[N/2][N/2];
int Temp2[N/2][N/2];
int P[N/2][N/2];
int Q[N/2][N/2];
int R[N/2][N/2];
int S[N/2][N/2];
int T[N/2][N/2];
int U[N/2][N/2];
int V[N/2][N/2];
void GetValue(int M[N/2][N/2]) //小矩阵获取随机值
{
int r,l;
for( r=0;r<N/2;r++)
{
for( l=0;l<N/2;l++)
{
M[r][l]=rand()%Max_Value;
}
}
};
void Matrix_Mul(int M1[N/2][N/2],int M2[N/2][N/2],int MR[N/2][N/2]) //矩阵乘法 MR=M1×M2
{
int i,r,l;
for(r=0;r<N/2;r++)
{
for(l=0;l<N/2;l++)
{
MR[r][l]=0;
for(i=0;i<N/2;i++)
{
MR[r][l]=MR[r][l]+M1[r][i]*M2[i][l];
}
}
}
};
void Matrix_Add(int M1[N/2][N/2],int M2[N/2][N/2],int MR[N/2][N/2]) //矩阵加法 MR=M1+M2
{
int r=0,l=0;
for( r=0;r<N/2;r++)
{
for( l=0;l<N/2;l++)
{
MR[r][l]=M1[r][l]+M2[r][l];
}
}
};
void Matrix_Sub(int M1[N/2][N/2],int M2[N/2][N/2],int MR[N/2][N/2]) //矩阵减法 MR=M1-M2
{
int r=0,l=0;
for( r=0;r<N/2;r++)
{
for( l=0;l<N/2;l++)
{
MR[r][l]=M1[r][l]-M2[r][l];
}
}
};
void OutPut(int M[N/2][N/2]) //输出小矩阵
{ int r,l;
for( r=0;r<N/2;r++)
{
for( l=0;l<N/2;l++)
{
cout<<" "<<M[r][l];
if(l==N/2-1)
{cout<<endl;}
}
}
};
void OutPutAll(char w) //输出大矩阵
{ int r,l;
if(w=='A')
{
for( r=0;r<N/2;r++)
{
for( l=0;l<N;l++)
{ if(l<N/2){cout<<" "<<A11[r][l];}
if(l>=N/2 && l!=N){cout<<" "<<A12[r][l-N/2];}
if(l==N-1){cout<<endl;}
}
}
for(r=0;r<N/2;r++)
{
for( l=0;l<N;l++)
{ if(l<N/2){cout<<" "<<A21[r][l];}
if(l>=N/2 && l!=N){cout<<" "<<A22[r][l-N/2];}
if(l==N-1){cout<<endl;}
}
}
}
if(w=='B')
{
for( r=0;r<N/2;r++)
{
for( l=0;l<N;l++)
{ if(l<N/2){cout<<" "<<B11[r][l];}
if(l>=N/2 && l!=N){cout<<" "<<B12[r][l-N/2];}
if(l==N-1){cout<<endl;}
}
}
for(r=0;r<N/2;r++)
{
for( l=0;l<N;l++)
{ if(l<N/2){cout<<" "<<B21[r][l];}
if(l>=N/2 && l!=N){cout<<" "<<B22[r][l-N/2];}
if(l==N-1){cout<<endl;}
}
}
}
if(w=='C')
{
for( r=0;r<N/2;r++)
{
for( l=0;l<N;l++)
{ if(l<N/2){cout<<" "<<C11[r][l];}
if(l>=N/2 && l!=N){cout<<" "<<C12[r][l-N/2];}
if(l==N-1){cout<<endl;}
}
}
for(r=0;r<N/2;r++)
{
for( l=0;l<N;l++)
{ if(l<N/2){cout<<" "<<C21[r][l];}
if(l>=N/2 && l!=N){cout<<" "<<C22[r][l-N/2];}
if(l==N-1){cout<<endl;}
}
}
}
};
/
int main(int argc, char* argv[])
{
cout<<"Strassen矩阵乘法"<<endl;
cout<<"┌ ┐ ┌ ┐ ┌ ┐"<<endl;
cout<<"│C│=│A│*│B│"<<endl;
cout<<"└ ┘ └ ┘ └ ┘"<<endl;
cout<<endl;
cout<<"矩阵规模N*N="<<N<<"*"<<N<<endl<<endl;
cout<<"运行....."<<endl;
clock_t start, finish;
double duration1,duration2;
///get_value
GetValue(A11);
GetValue(A12);
GetValue(A21);
GetValue(A22);
GetValue(B11);
GetValue(B12);
GetValue(B21);
GetValue(B22);
start = clock();
//
Matrix_Mul(A11,B11,Temp1);
Matrix_Mul(A12,B21,Temp2);
Matrix_Add(Temp1,Temp2,C11);
Matrix_Mul(A11,B12,Temp1);
Matrix_Mul(A12,B22,Temp2);
Matrix_Add(Temp1,Temp2,C12);
Matrix_Mul(A21,B11,Temp1);
Matrix_Mul(A22,B21,Temp2);
Matrix_Add(Temp1,Temp2,C21);
Matrix_Mul(A21,B12,Temp1);
Matrix_Mul(A22,B22,Temp2);
Matrix_Add(Temp1,Temp2,C22);
//
finish = clock();
duration1=finish-start;
/
start = clock();
//
Matrix_Add(A11,A22,Temp1);
Matrix_Add(B11,B22,Temp2);
Matrix_Mul(Temp1,Temp2,P);///P
Matrix_Add(A21,A22,Temp1);
Matrix_Mul(Temp1,B11,Q); ///Q
Matrix_Sub(B12,B22,Temp1);
Matrix_Mul(A11,Temp1,R); ///R
Matrix_Sub(B21,B11,Temp1);
Matrix_Mul(A22,Temp1,S); ///S
Matrix_Add(A11,A12,Temp1);
Matrix_Mul(Temp1,B22,T); ///T
Matrix_Sub(A21,A11,Temp1);
Matrix_Add(B11,B12,Temp2);
Matrix_Mul(Temp1,Temp2,U); ///U
Matrix_Sub(A12,A22,Temp1);
Matrix_Add(B21,B22,V); //V
Matrix_Add(P,S,Temp1);
Matrix_Sub(Temp1,T,Temp2);
Matrix_Add(Temp2,V,C11); //C11
Matrix_Add(R,T,C12); //C12
Matrix_Add(Q,S,C21); //C21
Matrix_Add(P,R,Temp1);
Matrix_Sub(Temp1,Q,Temp2);
Matrix_Add(Temp2,U,C22); //C22
//
finish = clock();
duration2=finish-start;
/
/* OutPutAll('A');
cout<<"*****************"<<endl;
OutPutAll('B');
cout<<"================="<<endl;
OutPutAll('C');
*/
cout<<"/n"<<"算法结果:"<<endl;
cout<<"没改善算法用时:"<<duration1<<" ms"<<endl;
cout<<"改善后算法用时:"<<duration2<<" ms"<<endl;
int waiting;
cin>>waiting;
return 0;
}
运行结果图:
注:运行结果图的时间数值因不同机器而不同。但改善后的算法明显比没改善的算法所用时间少。