当前位置:   article > 正文

资源分配 (c实现)_请使用c语言动态规划策略编写算法,实现资源分配问题。要求:输入资源个数与资金金

请使用c语言动态规划策略编写算法,实现资源分配问题。要求:输入资源个数与资金金

1. 适用于动态规划解决问题得特征

  1. 最优化原理

    是指一个问题的最优解,包括其子问题的最优解,或一个最优化策略的子策略总时最优的

  2. 无后向行

    及某个阶段的状态一旦确定,求不受这个状态以后策略的影响

  3. 子问题重叠

    即:子问题之间是不独立的,一个子问题在下一个阶段的决策中可能被多次使用到;

2. 动态规划的基本思想

1. 将求解的问题分成多个阶段或多个子问题,然后按顺序求解各子问题;前一子问题的解为后一子问题的解提供了有用的信息;

2. 在求解任意子问题时,列出各种可能的局部解,通过决策表六那些有可能达到最优的局部解,丢弃其他的局部解

3. 由于动态规划解决的问题多数有重叠子问题这个特点,为了减少重复计算,对每一个子问题只求解一次,将其不同阶段的不同状态保存搭配一个二维数组中

3. 设计动态规划的步骤

  1. 划分阶段

  2. 选择状态

  3. 确定决策并写出状态转移方程

4. 资源分配问题

1. 题目: 

设有资源n,(n为整数),分配给m各项目,gi(x)为第i各项目分得资源x(x为整数)所得到得利润;求总利润最大得资源分配方案,也就是求下面问题

max z = g1(x1) + g2(x2) + ....+ gm(xm)

x1 + x2 + x3 + .... + xm = n, 0<= xi <= n ,且xi为整数,i = 1,2,3 ...,m

2. 算法设计

  1. 划分阶段

    将该问题划分为A,B,C三个阶段

  2. 选择状态

    例:第一阶段A 有8种情况 分别是 x1(x1表示给A分配得钱数) =0,1,2,....,7、

    第二个阶段(A,B)有8中情况,分别是x2(x2表示给A,B分得得钱数) = 0,1,2,.....,7

  3. 决定决策并写出状态转移方程

    状态转移方程 max{ p(x) + f(n-x)} 解释一下:x表示在该阶段 i ,给 i 阶段(A,B,或C)的钱,n表示总的投资金额

    f(n-x)表示 i - 1阶段的最优子结构

  4. 算法实现程序

    以下图片就是a中所能存储的数据,但是要注意:这个算法真的很神奇,就是实现之后,你如果手头有5万元,而不仅仅是7万元,你也可以求出最优解

    解释一下a(以这个题为例讲解),a中所存储的是一、二、三 阶段 的最优解,而不仅仅是A、B、C的最优解,重要的是 阶段

    阶段:第一节段最优解是指给A投资的最优解

    第二阶段最优解是指给A、B投资的最优解

    第三阶段最优解是指给A、B、C投资的最优解

    所以可以由a中得出,投资 总额每个 项目所投资的数的关系,不要被着题给限制住了,这个算法十分强大,不仅仅可以求解投资总额为7的最优解,也可以求解投资总额为1,.....,6的解,当然你也可以进行算法改进求投资总额为100万元的都没问题,不过由于题目信息的限制,题中只给出了给A,B,C投资1~7的利润值

  1. #include<stdio.h>
  2. void main() {
  3. //主方法要尽可能的简化
  4. //a中存放每一状态的最优的解,p中存放每A,B,C的利润,f记录当前项目的最大利润
  5. //m表示项目数,n表示总的投资额
  6. /*
  7. * m = 3;n = 7
  8. A:0 0.11 0.13 0.15 0.21 0.24 0.30 0.35
  9. B:0 0.12 0.16 0.21 0.23 0.25 0.24 0.34
  10. C:0 0.08 0.12 0.20 0.24 0.26 0.30 0.35
  11. */
  12. //起始下标均为0,也可以自己设置为1
  13. int a[3][8],m,n,rest,gain[9],t;
  14. float p[8], f[8], temp[8];
  15. printf("请输入项目数:"); scanf_s("%d", &m);
  16. printf("请输入总的投资金额:"); scanf_s("%d", &n);
  17. //初始化状态一的
  18. printf("请输入A的利润:");
  19. for (int i = 0; i <= n; i++) {
  20. scanf_s("%f", &p[i]);
  21. f[i] = p[i];
  22. }
  23. for (int i = 0; i <= n; i++) {
  24. a[0][i] = i;
  25. }
  26. //开始解决剩余的m-1各项目,先对这n-1项进行初始化
  27. for (int k = 1; k < m; k++) {
  28. printf("请输入第%d个项目的利润:",k+1);
  29. for (int j = 0; j <= n; j++) {
  30. temp[j] = 0;
  31. scanf_s("%f", &p[j]);
  32. a[k][j] = 0;
  33. }
  34. //我愿称之为精髓
  35. for (int i = 0; i <= n; i++) {//i表示给这个阶段投的总钱数
  36. for (int j = 0; j <= i; j++) {//j表示给这个阶段的比较主体投的钱数(即第一阶段的比较主体为A;第二阶段的比较主体为B;第三阶段的比较主体为C)
  37. //以下的比较思想尤为重要
  38. //1. p[j] + f[i-j] 状态转移方程
  39. //2. temp[i]中存放该阶段中,当投资总额为i时的最优子结构,起始的时候,将temp设置为0,保证temp中最终存放的数为该阶段中最优的解
  40. if (p[j] + f[i-j] > temp[i]) {//通过这筛选条件我们可以得出该阶段中,投资总额为i时得最优解
  41. temp[i] = f[i-j] + p[j];
  42. a[k][i] = j;//标号k表示, 第k个项目 ;i表示为该阶段投的总的钱数,j表示给这个阶段的主体所投的钱数
  43. }
  44. }
  45. }
  46. for (int j = 0; j <= n; j++) {
  47. f[j] = temp[j];
  48. }
  49. for (int i = 0; i < 8; i++) {
  50. printf("%f\t", f[i]);
  51. }
  52. printf("\n");
  53. }
  54. /*printf("C:%d", a[2][n]); t = 7 - a[2][n];//还剩下t钱
  55. printf("B:%d", a[1][t]); t = t - a[1][t];
  56. printf("A:%d", a[0][t]);*/
  57. t = n;
  58. for (int i = m-1; i >=0 ; i--) {
  59. gain[i] = a[i][t];//gain中装载回溯之后 所有项目实际投资的金额
  60. t = t - a[i][t];//表示上一阶段回溯后,后阶段所剩的钱数
  61. }
  62. for (int i = 0; i < m; i++) {
  63. printf("第%d个项目的投资额:%d", i+1, gain[i]);
  64. printf("\n");
  65. }
  66. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/785065
推荐阅读
相关标签
  

闽ICP备14008679号