动态规划法-资源分配问题

动态规划法 - 资源分配问题

问题描述

把4个份额的资源分配给3个工程,给定利润表如下表所示,写出资源的最优分配方案的求解过程。
在这里插入图片描述
4份资源分配给3个工程的利润表

步骤一:求各个阶段不同分配份额时的最大利润及分配份额

目标

我们的目标是找到在给定资源限制下,如何分配资源给不同的工程以获得最大利润。

步骤

  1. 定义子问题:我们定义 fᵢ(x) 为将 x 份资源分配给前 i 个工程时的最大利润,dᵢ(x) 为在 fᵢ(x) 最大时,分配给第 i 个工程的资源份额。
  2. 初始化:对于只有一个工程的情况,我们可以直接计算出 f₁(x)d₁(x)
  3. 迭代计算:对于更多的工程,我们使用已知的 f₋₁(x)d₋₁(x) 来计算 fᵢ(x)dᵢ(x)

1. 只分配给第1个工程

资源分配表:

x01234
f₁(x)713161719
d₁(x)01234

解释:

  • 我们首先考虑只有一个工程的情况,直接计算每个资源份额下的利润。
  • d₁(x) 表示在给定资源份额下,第1个工程的资源分配。

2. 分配给前2个工程

资源分配表:

x01234
f₂(x)1319252830
d₂(x)00/1112

计算过程:

  1. 当 x = 0 时:

    • 只有第1个工程可以使用资源,利润为 f₂(0) = f₁(0) + G₂(0) = 7 + 6 = 13
    • 资源全部分配给第1个工程,d₂(0) = 0
  2. 当 x = 1 时:

    • 比较不同分配方式的利润,选择最大的利润:
      • G₂(0) + f₁(1) = 6 + 13 = 19
      • G₂(1) + f₁(0) = 12 + 7 = 19
    • 利润相同,可以选择任意一种分配方式,d₂(1) 可以是 0 或 1。
  3. 当 x = 2 时:

    • 比较不同分配方式的利润,选择最大的利润:
      • G₂(0) + f₁(2) = 6 + 16 = 22
      • G₂(1) + f₁(1) = 12 + 13 = 25
      • G₂(2) + f₁(0) = 14 + 7 = 21
    • 选择利润最大的分配方式,d₂(2) = 1
  4. 当 x = 3 时:

    • 比较不同分配方式的利润,选择最大的利润:
      • G₂(0) + f₁(3) = 6 + 17 = 23
      • G₂(1) + f₁(2) = 12 + 16 = 28
      • G₂(2) + f₁(1) = 14 + 13 = 27
      • G₂(3) + f₁(0) = 16 + 7 = 23
    • 选择利润最大的分配方式,d₂(3) = 1
  5. 当 x = 4 时:

    • 比较不同分配方式的利润,选择最大的利润:
      • G₂(0) + f₁(4) = 6 + 19 = 25
      • G₂(1) + f₁(3) = 12 + 17 = 29
      • G₂(2) + f₁(2) = 14 + 16 = 30
      • G₂(3) + f₁(1) = 16 + 13 = 29
      • G₂(4) + f₁(0) = 18 + 7 = 25
    • 选择利润最大的分配方式,d₂(4) = 2

解释为什么这么做:

  • 我们通过比较不同分配方式下的利润,选择能够带来最大利润的分配方案。
  • 这种方法确保了在有限的资源下,我们能够获得最大的经济回报。
  • 动态规划的优势在于它避免了重复计算相同的子问题,提高了计算效率。

通过以上步骤,我们可以得到在不同资源分配下的最大利润以及各个工程的资源分配份额。

3. 分配给前3个工程

步骤

  1. 定义子问题:我们定义 f₃(x) 为将 x 份资源分配给前3个工程时的最大利润,d₃(x) 为在 f₃(x) 最大时,分配给第3个工程的资源份额。

计算过程

  1. 当 x = 0 时:

    • 只有第1和第2个工程可以使用资源,利润为 f₃(0) = f₁(0) + G₂(0) + G₃(0) = 7 + 6 + 5 = 18
    • 资源全部分配给第1和第2个工程,d₃(0) = 0
  2. 当 x = 1 时:

    • 比较不同分配方式的利润,选择最大的利润:
      • G₃(0) + f₂(1) = 5 + 19 = 24
      • G₃(1) + f₂(0) = 18 + 13 = 31
    • 选择利润最大的分配方式,d₃(1) = 1
  3. 当 x = 2 时:

    • 比较不同分配方式的利润,选择最大的利润:
      • G₃(0) + f₂(2) = 5 + 25 = 30
      • G₃(1) + f₂(1) = 18 + 19 = 37
      • G₃(2) + f₂(0) = 19 + 13 = 32
    • 选择利润最大的分配方式,d₃(2) = 1
  4. 当 x = 3 时:

    • 比较不同分配方式的利润,选择最大的利润:
      • G₃(0) + f₂(3) = 5 + 28 = 33
      • G₃(1) + f₂(2) = 18 + 25 = 43
      • G₃(2) + f₂(1) = 19 + 19 = 38
      • G₃(3) + f₂(0) = 20 + 13 = 33
    • 选择利润最大的分配方式,d₃(3) = 1
  5. 当 x = 4 时:

    • 比较不同分配方式的利润,选择最大的利润:
      • G₃(0) + f₂(4) = 5 + 30 = 35
      • G₃(1) + f₂(3) = 18 + 28 = 46
      • G₃(2) + f₂(2) = 19 + 25 = 44
      • G₃(3) + f₂(1) = 20 + 19 = 39
      • G₃(4) + f₂(0) = 22 + 13 = 35
    • 选择利润最大的分配方式,d₃(4) = 1

资源分配表:

xf₃(x)d₃(x)
0180
1311
2371
3431
4461

解释为什么这么做

  • 我们通过比较不同分配方式下的利润,选择能够带来最大利润的分配方案。
  • 这种方法确保了在有限的资源下,我们能够获得最大的经济回报。
  • 动态规划的优势在于它避免了重复计算相同的子问题,提高了计算效率。

步骤二:求各个阶段的最大利润 gᵢ 和分配份额 qᵢ

  • 最大利润

    • g₁ = 19
    • g₂ = 30
    • g₃ = 46
  • 资源分配份额

    • q₁ = 4
    • q₂ = 4
    • q₃ = 4

步骤三:计算全局的最大利润 optg、最大的工程数目 k、总的最优分配份额 optx(k)

  • 全局最大利润optg = 46
  • 最大的工程数目k = 3
  • 总的最优分配份额optx₃ = 4

步骤四: 计算各个工程的最优分配份额 optq(x)

  1. 第3个工程

    • optq₃ = d₃(optx₃) = d₃(4) = 1
    • optx₂ = optx₃ - optq₃ = 4 - 1 = 3
  2. 第2个工程

    • optq₂ = d₂(optx₂) = d₂(3) = 1
    • optx₁ = optx₂ - optq₂ = 3 - 1 = 2
  3. 第1个工程

    • optq₁ = d₁(optx₁) = d₁(2) = 2

最终决策结果

  • 分别分配给第1、2、3工程 2、1、1 份资源,可得最大利润 46。

代码

#define _CRT_NO_SECURE_WARNINGS // 忽略某些安全警告#include<stdio.h> // 包含标准输入输出库
#include<iostream> // 包含输入输出流库using namespace std; // 使用标准命名空间int main() { // 主函数开始int m = 0; // 项目数int n = 0; // 投资金额int num = 0; // 用于记录第三个项目的投资金额float q[100][100] = { 0 }; // 一个二维数组,用来存储每个项目不同投资金额下的利润float f[100] = { 0 }; // 一个一维数组,用于存储当前最大收益float a[100][100] = { 0 }; // 一个二维数组,记录当前投资利益最大时每个项目所分配的投资数float temp[100] = { 0 }; // 一个一维数组,临时记录正在计算的最大收益float gain[100] = { 0 }; // 一个一维数组,用来存储每个项目的利润(未使用)int rest = 0; // 剩余投资金额(未使用)cout << "请输入项目数:"; // 输出提示信息cin >> m; // 从键盘读取项目数cout << "请输入投资金额:"; // 输出提示信息cin >> n; // 从键盘读取投资金额cout << "请输入原始利润数据:" << endl; // 输出提示信息// 循环读取每个项目的利润数据for (int i = 1; i <= m; i++) {cout << "投资#" << i << " "; // 输出提示信息for (int j = 0; j <= n; j++) {cin >> q[i][j]; // 从键盘读取利润数据}}// 初始化第一个项目的最大利益for (int j = 0; j <= n; j++) { // 从0到n投资f[j] = q[1][j]; // 第一个项目的最大利益a[1][j] = j; // 分配给第一个项目的投资金额}// 计算后面项目的最大收益for (int k = 2; k < m; k++) { // 从第二个项目开始for (int j = 0; j <= n; j++) { // 遍历所有可能的投资金额temp[j] = q[k][j]; // 初始化临时数组a[k][j] = 0; // 初始化分配数组}for (int j = 0; j <= n; j++) { // 遍历所有可能的投资金额for (int i = 0; i <= j; i++) { // 遍历所有可能的分配方案if (f[j - i] + q[k][i] > temp[j]) { // 如果当前方案更好,则更新temp[j] = f[j - i] + q[k][i]; // 更新最大收益a[k][j] = i; // 更新分配给当前项目的投资金额}}}for (int j = 0; j <= n; j++) { // 更新当前最大收益数组f[j] = temp[j];}}// 计算最后一个项目的最大收益for (int i = 0; i <= n; i++) {temp[i] = q[m][i] + f[n - i]; // 计算最大收益}for (int j = 0; j < n; j++) { // 找到最大收益对应的投资金额if (temp[j] < temp[j + 1]) {num = j + 1; // 记录第三个项目的投资金额}}// 输出第三个项目的所有可能收益cout << "第三个项目投资收益:" << endl;for (int i = 0; i <= n; i++) {cout << temp[i] << "  "; // 输出每个可能的最大收益}cout << "\n";// 输出最优投资方案cout << "当进行如下投资是收益最大:" << endl;cout << "第一个项目投资:" << n - num - a[2][n - num] << endl; // 输出第一个项目的投资金额cout << "第二个项目投资:" << a[2][n - num] << endl; // 输出第二个项目的投资金额cout << "第三个项目投资:" << num << endl; // 输出第三个项目的投资金额cout << "最大投资效益为:" << temp[num] << endl; // 输出最大收益system("pause"); // 暂停程序,等待用户操作return 0; // 主函数结束
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/415098.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

53 mysql pid 文件的创建

前言 接上一篇文章 mysql 启动过程中常见的相关报错信息 在 mysql 中文我们在 “service mysql start”, “service mysql stop” 经常会碰到 mysql.pid 相关的错误信息 比如 “The server quit without updating PID file” 我们这里来看一下 mysql 中 mysql.pid 文件的…

微积分复习笔记 Calculus Volume 1 - 1.3Trigonometric Functions

1.3 Trigonometric Functions - Calculus Volume 1 | OpenStax

自己开发完整项目一、登录功能-05(动态权限控制)

一、上节回顾 在上一节中&#xff0c;我们介绍了如何通过数据库查询用户的权限&#xff0c;并对方法级别的接口使用注解的方式进行权限控制&#xff0c;之后通过用户携带的tocken进行解析权限&#xff0c;判断是否可以访问。 具体步骤&#xff1a; 1.在查询用户信息的时候将用户…

map和set的封装

目录 一、红黑树的改造 1.1节点的定义 二、红黑树的迭代器 2.1用节点封装迭代器 2.2迭代器的实现 2.3map和set的迭代器 三、insert的返回值 3.1insert返回值的用处 3.2operator[ ]的实现 四、key不能修改的问题 封装map和set一般分为六步&#xff1a; 封装map和set …

MFC生成dll的区别

主要分三种&#xff1a; A. 动态链接库(dll) B.具有导出项的(dll)动态链接库 C.MFC动态链接库 对比项目&#xff1a;可以根据需要选择哪种dll方便 添加自定义导出功能Demo 1. 添加导出实现接口&#xff1a; A. 导出需要具有&#xff1a;__declspec(dllexport) B. 按照C语言…

Javascript LeeCode选题(汉诺塔求解)

LeeCode选题 汉诺塔递归求解move移动函数hanoi函数main方法测试代码&#xff1a;代码实现 汉诺塔递归求解 汉诺塔介绍&#xff1a; 汉诺塔的的图形&#xff08;从上到下1&#xff0c;2&#xff0c;3个&#xff09;实现&#xff1a; 这里我们可以看到因为必须要将第n个移动到…

Spring中基于redis stream 的消息队列实现方法

本文主要介绍了消息队列的概念性质和应用场景&#xff0c;介绍了kafka、rabbitMq常用消息队列中间件的应用模型及消息队列的实现方式&#xff0c;并实战了在Spring中基于redis stream 的消息队列实现方法。 一、消息队列 消息队列是一种进程间通信或者同一个进程中不同线程间的…

uni-app 获取当前位置的经纬度以及地址信息

文章目录 uni.getLocation(objc)获取经纬度和地址调试结果问题 uni-app 获取当前位置的经纬度以及地址信息 uni.getLocation(objc) uni-app官方文档定位API: uni.getLocation(OBJECT) uni.getLocation({type: wgs84,success: function (res) {console.log(当前位置的经度&…

【系统架构设计】嵌入式系统设计(1)

【系统架构设计】嵌入式系统设计&#xff08;1&#xff09; 嵌入式系统概论嵌入式系统的组成硬件嵌入式处理器总线存储器I/O 设备与接口 软件 嵌入式开发平台与调试环境交叉平台开发环境交叉编译环境调试 嵌入式系统概论 嵌入性、专用性、计算机系统是嵌入式系统的三个基本的核…

【话题讨论】VS Code:倍增编程动力,实现效率飞跃

目录 引言 一、详情介绍 功能特点 使用场景 提高工作效率 二、效率对比 2.1 高度可定制性与丰富的插件生态 2.2 智能的代码补全与导航 2.3 内置的调试器与版本控制集成 2.4 轻量级与跨平台 2.5 选择合适工具的重要性 2.6 实际案例或数据展示 三、未来趋势 3.1 编…

能见度监测站—实时监测道路能见度情况

型号&#xff1a;TH-NJD10】能见度监测站是一种专门用于自动观测和存储气象观测数据的设备&#xff0c;它通过高科技手段实时监测大气能见度的变化&#xff0c;为多个领域提供重要的数据支持。主要基于光在大气中的衰减规律。传感器系统中的发射器发出光线&#xff0c;照射到空…

shell编程--正则表达式

正则表达式 正则表达式都被置于两个正斜杠之间&#xff1b;如/l[oO]ve/ 示例 匹配数字的脚本&#xff0c;用户输入创建账号的数量 语法&#xff1a; [[ ^[0-9]$ ]] 表示必须输入数字 #!/bin/bashwhile : do read -p "输入数字&#xff1a;" numif [[ $num ~ ^[…

产品需求过程管理重要性

产品需求过程管理重要性 背景 以下都是真实事项经历回顾&#xff0c;在产品开发过程中&#xff0c;产品经理与研发团队之间的沟通至关重要。然而&#xff0c;沟通不畅或信息缺失常常导致需求无法准确传达&#xff0c;最终影响产品的成功。以下是一些常见的问题&#xff1a; 1.需…

Jmeter执行多机联合负载

1、注意事项&#xff0c;负载机必须要安装jre&#xff0c;控制机则必须安装jdk。要配置同网段ip&#xff0c;双向关闭防火墙。 每个负载机要平均承担线程数。 具体执行事项查看上面截图所示&#xff0c;控制机和负载机配置。 2、先给负载机设置ip地址&#xff0c;保持与控制…

C++项目详细分析_WebServer

前言 项目地址 项目介绍 源码详细分析 项目路径如下&#xff1a; 1.webserver.cpp 头文件和构造函数 #include "webserver.h"WebServer::WebServer() {// http_conn类对象users new http_conn[MAX_FD];// root文件夹路径char server_path[200];getcwd(server…

prometheus基于文件的服务发现

之间讲到&#xff0c;prometheus监控的对象就来自于他的配置文件里面的targets&#xff0c;如果要新增被监控对象&#xff0c;就继续往targets里面加。 但这个缺点是&#xff0c;每次修改完后都得重启prometheus。有没有什么办法&#xff0c;能在不重启的情况下增加target呢&a…

【Qt】 QComboBox | QSpinBox

文章目录 QComboBox —— 下拉框QComboBox 属性核心方法核心信号QComboBox 使用 QSpinBox —— 微调框QSpinBox 属性核心信号QSpinBox 使用 QComboBox —— 下拉框 QComboBox 属性 QComboBox —— 表示下拉框 currentText ——当前选中的文本 currentindex ——当前选中的条…

【硬件知识】从零开始认识GPU

【硬件知识】从零开始认识GPU 一、GPU的发展史简介二、GPU主要构成三、GPU与AI的关系 一、GPU的发展史简介 GPU&#xff08;图形处理器&#xff09;的发展史是一段充满创新与变革的历程&#xff0c;它不仅改变了计算机图形显示的方式&#xff0c;还推动了高性能计算、人工智能…

盘点大模型中转 API 平台,并比较费用

1. 大模型中转 API 平台集合 1.1 DevAGI DevAGI开放平台 Open AI 价格 1.2 Deepbricks 官网价格 1.3 AiHubMix AiHubMix 官网 使用教程 价格&#xff1a; 1.4 WildCard 开卡订阅 WildCard官网 价格 有3.5% 的充值手续费&#xff0c;API 价格与 Open AI 一样 2. 价…

机器学习:opencv--图像边缘检测

目录 前言 一、图像边缘检测 1.边缘检测 2.边缘检测的方法 二、Sobel算子 1.Sobel算子 2.计算 3.代码实现 4.代码步骤解析 1.导入图片 2.处理x轴和y轴的边缘并相加 三、Scharr算子 1.Scharr算子 2.计算 3.代码实现 四、Laplacian算子 1.Lapla…