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

题目描述

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

求解过程

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

表示在第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++;
        }
    }
}
时间: 2024-07-30 18:05:25

动态规划--设备最优更新策略的相关文章

Unity手游之路&lt;十三&gt;手游代码更新策略探讨

这几个月公司项目非常忙,加上家里事情也多,所以blog更新一直搁置了.最近在项目开发上线过程中遇到了一些新问题,接下来的时间和大家多多探讨学习.大家在工作中遇到技术问题,或者有什么想分享的,欢迎多多探讨 [email protected] ----------------------------------------------------------------------------------------------------------------------------------

Unity手游之路手游代码更新策略探讨

版权声明: https://blog.csdn.net/janeky/article/details/25923151 这几个月公司项目非常忙.加上家里事情也多,所以blog更新一直搁置了. 近期在项目开发上线过程中遇到了一些新问题,接下来的时间和大家多多探讨学习. 大家在工作中遇到技术问题,或者有什么想分享的,欢迎多多探讨 ken@iamcoding.com. -------------------------------------------------------------------

最优捕鱼策略问题

为了保护人类赖以生存的自然环境,可再生资源(如渔业.林业资源)的开发必须适度.一种合理.简化的策略是,在实现可持续收获的前提下,追求最大产量或最佳效益. 考虑对鳀鱼的最优捕捞策略:假设这种鱼分4个年龄组,称为1龄鱼,2龄鱼,3龄鱼,4龄鱼.各年龄组每条鱼的平均质量分别为5.07.11.55.17.86.22.99(g),各年龄组的自然死亡率为0.8(1/年),这种鱼为季节性集中产卵繁殖,平均每条4龄鱼的产卵量为1.109×1011(个),3龄鱼的产卵量为这个数的一半,2龄鱼和1龄鱼不产卵,产卵和

【腾讯Bugly干货分享】Android UI:机智的远程动态更新策略

Android UI:机智的远程动态更新策略 作者:王金波    腾讯Bugly特约撰稿人 1问题描述 做过Android开发的人都遇到过这样的问题:随着需求的变化,某些入口界面通常会出现 UI的增加.减少.内容变化.以及跳转界面发生变化等问题.每次发生变化都要手动修改代码,而入口界面通常具有未读信息提醒这样的"小红点"逻辑:一旦UI变化,"小红点"逻辑也要重新计算.如果不同的RD来维护这些代码,耦合性非常高,出错概率也很大.本文以自选股的个人页卡为例(界面如下图所

百度蜘蛛的更新策略

百度蜘蛛的更新策略:我们知道蜘蛛并不是只抓取我们网站一次,而是按一定的更新频率来抓取我们的网站,在本地进行一个"镜像"从而保证被抓取的网页参与排名时呈现给用户的是最新的(咳咳,不新也要保证差不多嘛!毕竟资源有限).那么这个更新策略跟什么有关呢? 1.用户体验:用户一般在搜索一个关键词的时候,顶多看两三页左右,基本很少看后面的页面,而搜索引擎本着优先更新大部分客户所需要内容的原则,所以搜索引擎会统计用户的搜索请求的前几页,优先进行一个更新.例如:百度搜索"年少轻狂"用

Kafka源码分析-序列2 -Producer -Metadata的数据结构与读取、更新策略

在上一篇,我们从使用方式和策略上,对消息队列做了一个宏观描述.从本篇开始,我们将深入到源码内部,仔细分析Kafka到底是如何实现一个分布式消息队列.我们的分析将从Producer端开始. 从Kafka 0.8.2开始,发布了一套新的Java版的client api, KafkaProducer/KafkaConsumer,替代之前的scala版的api.本系列的分析将只针对这套Java版的api. 多线程异步发送模型 下图是经过源码分析之后,整理出来的Producer端的架构图: 在上一篇我们讲

[unity3d]手游资源热更新策略探讨

原地址:http://blog.csdn.net/dingxiaowei2013/article/details/20079683 我们学习了如何将资源进行打包.这次就可以用上场了,我们来探讨一下手游资源的增量更新策略.注意哦,只是资源哦.关于代码的更新,我们稍后再来研究.理论上这个方案可以使用各种静态资源的更新,不仅仅是assetbundle打包的. (转载请注明原文地址http://blog.csdn.net/janeky/article/details/17666409) 原理 现在的手游

Unity手游之路&lt;十二&gt;手游资源热更新策略探讨

http://blog.csdn.net/janeky/article/details/17666409 上一次我们学习了如何将资源进行打包.这次就可以用上场了,我们来探讨一下手游资源的增量更新策略.注意哦,只是资源哦.关于代码的更新,我们稍后再来研究.理论上这个方案可以使用各种静态资源的更新,不仅仅是assetbundle打包的. (转载请注明原文地址http://blog.csdn.net/janeky/article/details/17666409) 原理 现在的手游安装有几种方式.一种

odi增量更新策略

增量更新策略:通过一个“update key”比较流数据记录与目标表中的记录比较进行数据整合.具有相同“update key”的记录当相关联列不同时将被更新:在目标表中不存在的记录将被插入.这种方式用来操作记录的变化不需要记录的时候. IKM使用面向SQL编程的方法而不是通过逐行记录比较的方法来比较记录的不同.这种策略最常用的方法为把转换后的数据整合到I$表中,步骤: ①创建I$表,增加一个叫IND_UPDATE的列,用来标识这条记录是被插入还是被更新: ②把流数据插入到I$表中,所有的源数据被