码迷,mamicode.com
首页 > 其他好文 > 详细

动态规划--设备最优更新策略

时间:2015-12-02 14:35:52      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:

题目描述

某公司针对某项目进行为期五年的规划,该项目使用某种设备,该公司有一台已经使用了两年的该型设备。每年年初该公司都有两种选择,一是更新设备,二是继续使用。设备在使用过程中会产生维修费用。设备更新、维修费用由下表给出,求解该公司如何更新设备可以获得最大利润。

技术分享

求解过程

在规划之前,先引入几个符号。

技术分享表示在第i年使用第t年买的设备所得的毛利润;

技术分享表示在第i年使用第t年买的设备所需的维修费用;

技术分享表示第i年使用第t年买的设备所需的更新费用;

技术分享表示第i年使用第t年买的设备所获得的阶段总利润;

技术分享表示第i年初的设备是第t年买得话,所做的策略,true表示更新,false表示继续使用。

应用动态规划的方法,我们可以采用逆序求解的方式,从第五年年初设备状态开始求取,并且我们第五年年底,无论设备状态如何,第六年利润都为0。

首先,我们来推导利润的求解。

假设在第i年年初,拥有的设备是第t年买的。这时,我们有两个选择,更新当前设备,或者继续使用当前设备。

因此技术分享

对于第五年年初,我们的设备状态可能有五种:第0年的设备,第一年的设备,第二年的设备,第三年的设备,第四年的设备。

根据表格,,我们可以求得技术分享

依次可以求得技术分享

对于每一种状态,若求得结果时,选择更新的利润大,置技术分享为true,否则置为false。

照此方法,对于第一年年初,设备状态只有一种:第0年的设备。

更新的利润为32,继续使用的话是50,因此第一步我们要选择继续使用。

此时,我们再反过来查看每一步的选择。第一步我们选择了继续使用,第二步的状态就是使用第0年的设备,更新利润为36,继续为37,因此选择继续使用;第三步初始状态也为使用第0年设备,更新利润为27,继续使用为21,因此选择更新;第四步初始状态为使用第三年设备,继续使用为18,更新为13,选择继续使用;第五步初始状态为使用第三年设备,继续使用为14,更新为-4,因此为继续使用。

基于此,我们得到了最优的更新策略,第一年第二年不更新,第三年更新,第四年第五年不更新,最大利润为50。

代码

/* 
算法设计与分析作业 
    ---设备最优更新策略 
*/ 
#include<iostream>

void accept(int **a, int years); 
int max(int a, int b) { return  a > b ? a : b; } 
int main() { 
    using std::cin; 
    using std::cout; 
    using std::endl;

    cout << "请输入决策年数(i):" << endl; 
    int temp; 
    while (!(cin >> temp)||temp < 0) { 
        cout << "请输入一个正整数:" << endl; 
        cin.clear(); 
        while (cin.get() != \n); 
    } 
    int years = temp + 1; 
    
    //第i年买的设备在第t年能产生的利润 
    int **exProfit = new int*[years];//0-n年买的设备 
    for (int i = 0; i < years; i++) { 
        exProfit[i] = new int[years];//0-n年买的设备在第i年的利润 
    } 
    cout << "请依次输入利润:" << endl; 
    accept(exProfit, years); 
    //第i年买的设备在第t年产生的维修费用 
    int **fix = new int *[years]; 
    for (int i = 0; i < years; i++){ 
        fix[i] = new int[years]; 
    } 
    cout << "请依次输入维修费用:" << endl; 
    accept(fix, years); 
    //第i年买的设备在第t年更新时的费用 
    int **update = new int *[years]; 
    for (int i = 0; i < years; i++){ 
        update[i] = new int[years]; 
    } 
    cout << "请依次输入更新费用:" << endl; 
    accept(update, years); 
    //最优更新策略,true代表更新,false代表继续使用 
    bool **choice = new bool *[years]; 
    for (int i = 0; i < years; i++) { 
        choice[i] = new bool[years]; 
    } 
    for (int i = 0; i < years; i++){ 
        for (int j = 0; j < years; j++) 
            choice[i][j] = false; 
    } 
    //最终利润,决策年数之后的一年利润全部置0 
    int **profit = new int*[years]; 
    for (int i = 0; i < years; i++) { 
        profit[i] = new int[years + 1]; 
    } 
    for (int i = 0; i < years; i++) 
    { 
        for (int j = 0; j < years + 1; j++) 
            profit[i][j] = 0; 
    } 
    //倒序进行计算,第i年,可以使用的设备要么就是之前一直没更新,要么就是第j年买的设备 
    //例如,第三年,设备的状态就有三种选择,一是使用第0年的设备,二是在第一年进行了更新,三是第二年进行了更新 
    //分别对每个状态进行选择更新或者继续使用 
    //第i年,有两种选择,要么更新,要么继续使用 
    //分别计算更新和继续使用的利润,选择两者中比较大的。 
    for (int  i = temp; i >0 ; i--) 
    { 
        for (int j = 0; j < i; j++) 
        { 
            int keep = exProfit[j][i] - fix[j][i] + profit[j][i + 1]; 
            int refresh = exProfit[i][i] - fix[i][i] - update[j][i] + profit[i][i + 1]; 
            profit[j][i] = max(keep, refresh); 
            if (keep < refresh) { 
                choice[i][j] = true; 
            } 
        } 
    } 
    int j = 0; 
    for (int i = 1; i < years; i++) 
    { 
        if (choice[i][j]) { 
            j = i; 
            std::cout <<""<<i<< "年更新"<<std::endl; 
            continue; 
        } 
            std::cout << "" << i << "年继续使用" << std::endl;    
    } 
    cout << "利润最大为:" << profit[0][1]; 
    delete[]profit; 
    for (int i = 0; i < years; i++) { 
        delete[] fix[i]; 
    } 
    delete[]fix; 
    for (int i = 0; i < years; i++) { 
        delete[] exProfit[i]; 
    } 
    delete[]exProfit; 
    for (int i = 0; i < years; i++) { 
        delete[] update[i]; 
    } 
    delete[]update; 
    for (int i = 0; i < years; i++) { 
        delete[] choice[i]; 
    } 
    delete[]choice; 
}

void accept(int **a ,int years) { 
    for (int i = 0; i < years; i++) { 
        std::cout << ""<<i<<"年:"; 
        int j = 0; 
        a[i][j] = 0; 
        j++; 
        while (j < years) 
        { 
            if (j < i) 
                a[i][j] = 0; 
            else { 
                while (!(std::cin >> a[i][j])||a[i][j] < 0) { 
                    if(i == 0) 
                        std::cout << "请从第" <<j<<"个数重新输入"<< std::endl; 
                    else 
                        std::cout << "请从第" << j-i+1 << "个数重新输入" << std::endl; 
                    std::cout << "请输入正整数"; 
                    std::cin.clear(); 
                    while (std::cin.get() != \n); 
                } 
            } 
            j++; 
        } 
    } 
}

动态规划--设备最优更新策略

标签:

原文地址:http://www.cnblogs.com/aguoshaofang/p/5012751.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!