投资问题的算法实现

问题描述

m元钱,投资 n 个项目。效益函数 fi (x) 表示第 i 个项目投 x 元的效益( i =1, 2, …, n)。求如何分配每个项目的钱数使得总效益最大?

实例

5 万元,投资给 4 个项目,效益函数:
Alt

问题建模

输入:项目总数x;投资金额y;效益函数fi(k)
输出:最大利润maxProfit

算法

暴力求解

算法思想

对所有项目进行循环,通过限定条件:总投资金额=y,得到所有符合的答案,从中选取最大值,即为所求。

代码

使用C++语言实现:

#include<iostream>
using namespace std;
    //投资问题的暴力解法
int main(){
    int profitMatrix[4][6]={0,11,12,13,14,15,   //收益矩阵
                            0,0,5,10,15,20,
                            0,2,10,30,32,40,
                            0,20,21,22,23,24
    };
    int x1,x2,x3,x4,x;
    int sum=0,maxProfit=0;
    int a[4]={0}; //输出最优向量
    for(x1=0;x1<6;x1++){
        for(x2=0;x2<6;x2++){
            for(x3=0;x3<6;x3++){
                for(x4=0;x4<6;x4++){
                   x=x1+x2+x3+x4;
                   if(x==5){ //限定条件,投资5万元
                        sum=profitMatrix[0][x1]+profitMatrix[1][x2]+
                            profitMatrix[2][x3]+profitMatrix[3][x4];
                        if(sum>maxProfit){
                            maxProfit=sum;
                            a[0]=x1;
                            a[1]=x2;
                            a[2]=x3;
                            a[3]=x4;
                        }
                   }
                }
            }
        }
    }
    cout<<"最大利润为:"<<maxProfit<<endl;
    cout<<"最优投资方案为:( ";
    for(int i=0;i<4;i++){
        cout<<a[i]<<" ";
    }
    cout<<")";
}

使用Python语言实现:

if __name__ == '__main__':
    profitMatrix=[[0,11,12,13,14,15],
                  [0,0,5,10,15,20],
                  [0,2,10,30,32,40],
                  [0,20,21,22,23,24]]
    a=[0,0,0,0] #存放最优投资方案
    maxProfit=0
    sumMoney=0
    for x1 in range(6):
        for x2 in range(6):
            for x3 in range(6):
                for x4 in range(6):
                    x=x1+x2+x3+x4
                    if x==5:
                        sumMoney=profitMatrix[0][x1]+profitMatrix[1][x2]+profitMatrix[2][x3]+profitMatrix[3][x4]
                    if sumMoney>maxProfit:
                        maxProfit=sumMoney
                        a[0]=x1
                        a[1]=x2
                        a[2]=x3
                        a[3]=x4
    print("最大利润为:"+str(maxProfit))
    print("最优投资方案为:"+str(a))

动态规划

算法思想

假设第x个项目投资m万元,则将x个项目的y万元投资问题分解为前x-1个项目投资y-m万元和第x个项目投资m万元。这样就可以将问题规模减小,直至仅有一个项目,此时的最佳投资方案就是其本身。
令outspace[x][y]表示前x个项目投资y万元得到的最大利润,令
profitMatrix[i][m]=fi(m),则动态方程为:
outspace[x][y]=profitMatrix[x][m]+outspace[x-1][y-m]
限定边界为outspace[0][k]=profitMatrix[0][k]

代码

使用C++语言实现:

#include<iostream>
using namespace std;

int getProfit(int outspace[4][6],int profitMatrix[4][6],int maxProfit){
    for(int i=0;i<=5;i++){
    //当仅有一个项目时,此项目的收益即为最优,分开赋值是为了避免下面出现 -1 行
        outspace[0][i]=profitMatrix[0][i];
    }
    for(int i=1;i<4;i++){ //逐次加入第2,3,4个项目
        for(int j=0;j<=5;j++){//投资金额
                for(int m=0;m<=j;m++){//m代表最后一个项目投资金额
                    if(outspace[i][j]<profitMatrix[i][m]+outspace[i-1][j-m]){
                        outspace[i][j]=profitMatrix[i][m]+outspace[i-1][j-m];
                        if(outspace[i][j]>maxProfit)
                            maxProfit=outspace[i][j];

                    }
                }
        }
    }
    return maxProfit;
}
int main()
{
    int maxProfit = 0;
    int outspace[4][6]={0};//初始化最大利润矩阵
    int profitMatrix[4][6]={0,11,12,13,14,15,   //收益矩阵
                            0,0,5,10,15,20,
                            0,2,10,30,32,40,
                            0,20,21,22,23,24
    };
    int a=getProfit(outspace,profitMatrix,maxProfit);
    cout<<"最大收益为:"<<a<<endl;
    return 0;
}

使用Python语言实现:

def getProfit(profitMatrix,outspace,maxProfit):
    for i in range(6):
        outspace[0][i]=profitMatrix[0][i]
    for i in range(1,4):
        for j in range(6):
            for m in range(j+1):
                if outspace[i][j]<profitMatrix[i][m]+outspace[i-1][j-m]:
                    outspace[i][j]=profitMatrix[i][m]+outspace[i-1][j-m]
                if maxProfit<outspace[i][j]:
                    maxProfit=outspace[i][j]
    return maxProfit
                
if __name__ =='__main__':
    profitMatrix=[[0,11,12,13,14,15],
                  [0,0,5,10,15,20],
                  [0,2,10,30,32,40],
                  [0,20,21,22,23,24]]
    outspace=[]
    for i in range(4):
        outspace.append([])
        for j in range(6):
            outspace[i].append(0)
    maxProfit=0
    a=getProfit(profitMatrix,outspace,maxProfit)
    print("最大利润为:"+str(a))

输出

请添加图片描述

总结

令m为投资金额,n为项目数
则投资问题的暴力算法时间复杂度为O(mn) 空间复杂度为O(mn)
动态规划算法时间复杂度为O(nm2) 空间复杂度为O(mn)

  • 5
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值