投资问题
m 元钱,n 项投资,fi (x): 将 x 元投入第 i 项项目的效益
目标函数 max {f1(x1) + f2(x2) + … + fn(xn) }
约束条件 x1 + x2 + … + xn = m,xi Î N
实例:5万元钱,4个项目,效益函数如下表所示
投资问题 m 元钱,n 项投资,fi (x): 将 x 元投入第 i 项项目的效益 目标函数 max {f1(x1) + f2(x2) + … + fn(xn) } 约束条件 x1 + x2 + … + xn = m,xi Î N 实例:5万元钱,4个项目,效益函数如下表所示
标记函数xk(x)表示当Fk(x)取得最大值时应该分配给第k个项目的钱数。 将钱投入前1项目中获取的收益 F1(1)=f1(1)=11 F1(2)=f1(2)=12 F1(3)=f1(3)=13 F1(4)=f1(4)=14 F1(5)=f1(5)=15 X1(x)=x 将钱投入前2项目中获取的收益 F2(1)=max{f2(0)+F1(1),f2(1)+F1(0)}=max{0+11,0+0}=11 X2(1)=0 //把1万元投给前两个项目获得最大值时,第2个项目的投资额为0元。 F2(2)=max{f2(0)+F1(2),f2(1)+F1(1) ,f2(2)+F1(0)}=max{0+12,0+11,5+0}=12 X2(2)=0 F2(3)=max{f2(0)+F1(3),f2(1)+F1(2) ,f2(2)+F1(1) ,f2(3)+F1(0)} =max{0+13,0+12,5+11,10+0}=16 X2(3)=2 F2(4)=max{f2(0)+F1(4),f2(1)+F1(3) ,f2(2)+F1(2) ,f2(3)+F1(1) ,f2(4)+F1(0)} =max{0+14,0+13,5+12,10+11,15+0}=21 F2(5)=max{f2(0)+F1(5),f2(1)+F1(4) ,f2(2)+F1(3) ,f2(3)+F1(2) ,f2(4)+F1(1) ,f2(5)+F1(0)} =max{0+15,0+14,5+13,10+12,15+11,20+0}=26 X2(5)=4 将钱投入前3项目中获取的收益 F3(1)=max{f3(0)+F2(1), f3(1)+F2(0)}=max{0+11,2+0}=11 F3(2)=max{f3(0)+F2(2), f3(1)+F2(1) , f3(2)+F2(0)}=max{0+12,2+11,10+0}=13 F3(3)=max{f3(0)+F2(3), f3(1)+F2(2) , f3(2)+F2(1) , f3(3)+F2(0)} =max{0+16,2+12,10+11,30+0}=30 X3(3)=3 …… F4(5)=f4(1)+F3(4) F3(4)=f3(3)+F2(1) F2(1)=f2(0)+F1(1) 1项:1 2 项:0 3项:3 4项:1 实例:60万元钱,4个项目,效益函数如下表所示
Fk(y) F1(1) =0 F1(2) =1 F1(3) =1 ……. F2(2)=max{F1(2),F2(2-w2)+v2}=max{1,F2(2-3)+3} =max{1,-∞+3}=1 F2(3)=max{F1(3),F2(3-w2)+v2}=max{1,F2(0)+3}=3 F2(4)=max{F1(4),F2(4-w2)+v2}=max{2,F2(4-3)+3}=3
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
标记函数xk(x)表示当Fk(x)取得最大值时应该分配给第k个项目的钱数。
将钱投入前1项目中获取的收益
F1(1)=f1(1)=11
F1(2)=f1(2)=12
F1(3)=f1(3)=13
F1(4)=f1(4)=14
F1(5)=f1(5)=15
X1(x)=x
将钱投入前2项目中获取的收益
F2(1)=max{f2(0)+F1(1),f2(1)+F1(0)}=max{0+11,0+0}=11
X2(1)=0 //把1万元投给前两个项目获得最大值时,第2个项目的投资额为0元。
F2(2)=max{f2(0)+F1(2),f2(1)+F1(1) ,f2(2)+F1(0)}=max{0+12,0+11,5+0}=12
X2(2)=0
F2(3)=max{f2(0)+F1(3),f2(1)+F1(2) ,f2(2)+F1(1) ,f2(3)+F1(0)}
=max{0+13,0+12,5+11,10+0}=16
X2(3)=2
F2(4)=max{f2(0)+F1(4),f2(1)+F1(3) ,f2(2)+F1(2) ,f2(3)+F1(1) ,f2(4)+F1(0)}
=max{0+14,0+13,5+12,10+11,15+0}=21
F2(5)=max{f2(0)+F1(5),f2(1)+F1(4) ,f2(2)+F1(3) ,f2(3)+F1(2) ,f2(4)+F1(1) ,f2(5)+F1(0)}
=max{0+15,0+14,5+13,10+12,15+11,20+0}=26
X2(5)=4
将钱投入前3项目中获取的收益
F3(1)=max{f3(0)+F2(1), f3(1)+F2(0)}=max{0+11,2+0}=11
F3(2)=max{f3(0)+F2(2), f3(1)+F2(1) , f3(2)+F2(0)}=max{0+12,2+11,10+0}=13
F3(3)=max{f3(0)+F2(3), f3(1)+F2(2) , f3(2)+F2(1) , f3(3)+F2(0)}
=max{0+16,2+12,10+11,30+0}=30
X3(3)=3
……
F4(5)=f4(1)+F3(4)
F3(4)=f3(3)+F2(1)
F2(1)=f2(0)+F1(1)
1项:1 2 项:0 3项:3 4项:1
实例:60万元钱,4个项目,效益函数如下表所示
x | f1(x) | f2(x) | f3(x) | f4(x) |
0 | 0 | 0 | 0 | 0 |
10 | 20 | 20 | 25 | 25 |
20 | 50 | 40 | 60 | 40 |
30 | 65 | 50 | 85 | 50 |
40 | 80 | 58 | 100 | 60 |
50 | 85 | 60 | 110 | 115 |
60 | 85 | 65 | 115 | 120 |
Fk(y)
F1(1) =0
F1(2) =1
F1(3) =1
…….
F2(2)=max{F1(2),F2(2-w2)+v2}=max{1,F2(2-3)+3}
=max{1,-∞+3}=1
F2(3)=max{F1(3),F2(3-w2)+v2}=max{1,F2(0)+3}=3
F2(4)=max{F1(4),F2(4-w2)+v2}=max{2,F2(4-3)+3}=3
代码如下
#include <iostream>
#include <stdio.h>
using namespace std;
int n,m,F[100][100],x[100][100],f[100][100]=//f[j][i]: 将j元投入第i+1项项目的效益
{
{0,0,0,0},//j=0
{11,0,2,20},//j=1
{12,5,10,21},//j=2
{13,10,30,22},//j=3
{14,15,32,23},//j=4
{15,20,40,24},//j=5
};
/*
f[100][100]= //测试项2,要用这个记得把输出投资的金额乘以10
{
{0,0,0,0},//j=0
{20,20,25,25},//j=1
{50,40,60,40},//j=2
{65,50,85,50},//j=3
{80,58,100,60},//j=4
{85,60,110,115},//j=5
{85,65,115,120},//j=6
};
*/
void recall(int a,int b)//应用递归算法回溯输出运算公式,a代表剩余的钱,第b项项目
{
if(b==0) return;//输出到b==0结束输出
recall(a-x[a][b-1],b-1);//输出上一个项目的投资
if(b==n) printf("x%d = %d\n",b,x[a][b-1]);//最后一个输出不留逗号,并且换行
else printf("x%d = %d, ",b,x[a][b-1]);//其他输出用逗号隔开
}
void investment(int n,int m)
{
for(int j=1;j<=m;j++)
{
F[j][0]=f[j][0];//将j元分配给第一个项目
x[j][0]=j; //标记函数
}
for(int i=1;i<n;i++)//计算分配给前i+1个项目获得的最优效益
{
for(int a=0;a<=m;a++)//将a元分配给前i+1个项目
{
F[a][i]=f[0][i]+F[a-0][i-1];//将第一个设为最大值
x[a][i]=0;//标记函数
for(int xk=1;xk<=a;xk++)
if(f[xk][i]+F[a-xk][i-1]>F[a][i])//再逐个比较,找出最大值并标记
{
F[a][i]=f[xk][i]+F[a-xk][i-1];
x[a][i]=xk;//标记函数
}
}
}
//下面输出解的追溯表
cout<<"解的追溯:"<<endl;
cout<<" x ";//输出标识x
for(int i=0;i<n;i++)
printf(" F%d(x) x%d(x) ",i+1,i+1);//输出标识Fi+1d(x) xi+1(x)
cout<<endl;//换行
for(int j=1;j<=m;j++)
{
printf(" %-2d ",j);//输出标识数字j
for(int i=0;i<n;i++)
printf(" %-3d %-3d ",F[j][i],x[j][i]);//输出F[j][i],x[j][i]
cout<<endl;//换行
}
cout<<"分配方案为:";
recall(m,n);//应用递归算法回溯输出运算公式
cout<<"最大效益是F"<<n<<'('<<m<<")="<<F[m][n-1]<<endl;
}
int main()
{
n=4,m=5;//m元,n项投资
//n=4,m=6; //测试项2
investment(n,m);
}
运行截图