传知代码-改进贪心算法(NGSOR)

一、算法背景及意义

(一)背包问题背景

背包问题是组合优化领域中的经典问题,具有广泛的实际应用场景,如资源分配、项目投资决策等。扩展简化折扣{0 - 1}背包问题(ESD{0 - 1}KP)是背包问题的一种变体,它在传统背包问题的基础上增加了一些复杂的约束条件,如物品的折扣系数以及每个项集中多个物品的选择情况,使得问题的求解更加困难。

(二)算法研究意义

  • 理论意义:NGSOR算法为ESD{0 - 1}KP提供了一种有效的求解方法,通过将问题转化为与多选择背包问题(MCKP)相关的形式,并结合特定的计算价值密度和选择物品的策略,丰富了背包问题的求解算法理论。
  • 实际意义:在实际应用中,能够帮助决策者在面对复杂的资源分配和项目选择问题时,更准确地找到满足约束条件且价值最大化的方案,提高决策效率和资源利用效率。

二、算法概述

原文链接

(一)总体思路

NGSOR算法主要通过计算物品的价值密度,并根据价值密度从高到低的顺序选择物品,同时考虑物品的折扣系数和背包容量限制,逐步构建满足条件的最优物品组合。

(二)关键步骤

  1. 计算价值密度
    • 对于每个项集中的物品,考虑不同的选择组合情况,计算出相应的价值和重量,进而得到价值密度。
  2. 选择物品
    • 根据价值密度对所有可能的物品选择进行排序。
    • 依次尝试选择每个物品,并检查选择后的物品组合是否满足背包容量限制。如果满足且总价值更大,则更新当前的最优物品组合。

三、算法详细步骤

(一)计算价值密度

  1. calculate_value_density函数中:
    • 首先获取物品价值系数数组P、质量系数数组W和折扣系数数组d的长度n
    • 初始化一个形状为(7*n, 2)的二维数组E,用于存储价值密度和原始索引信息。
    • 对于每个项集(索引为i0n - 1):
      • 计算所有可能的物品选择组合的价值Ps,包括单个物品选择以及不同物品组合的情况。
      • 计算相应的重量Ws,考虑了折扣系数的影响。
      • 将计算得到的价值密度Ps / Ws存储在E数组的对应行(7*i7*i + 7)的第一列,同时将原始索引i存储在第二列。
  2. 最终返回E数组,其中包含了所有物品选择组合的价值密度和原始索引信息。

(二)NGSOR算法主函数

  1. NGSOR函数中:
    • 获取物品价值系数数组P和质量系数数组W的长度n
    • 调用calculate_value_density函数计算价值密度数组E
    • E数组与一个包含从17*n的索引数组进行列拼接,得到一个新的数组,用于后续排序和索引操作。
    • 对新数组E按第一列(价值密度)进行降序排序,得到排序后的索引数组H
    • 初始化决策变量数组X为全零数组,形状为(3*n, 1),用于表示物品的选择情况。同时初始化一些变量用于记录当前最优解的总价值、总重量以及对应的物品选择数组。
  2. 然后进入循环:
    • 对于每个可能的物品选择(索引为i07*n - 1):
      • 根据排序后的索引H[i]计算物品所在项集索引t1和在项集中的选择情况索引t2,以及原始物品索引item_index
      • 复制当前决策变量数组X得到T,并根据t2的值设置对应项集中物品的选择情况selection
      • 计算选择T后的总重量Q,通过遍历每个项集,检查是否有物品被选择,如果有则计算相应的重量并累加。
      • 如果总重量Q满足背包容量限制C
        • 计算选择T后的总价值current_value,通过将对应项集中物品的价值与选择情况相乘并累加得到。
        • 如果current_value大于当前最优总价值best_value,则更新最优解相关变量,包括最优物品选择数组best_X、最优总价值best_value和最优总重量best_weight
  3. 最后返回最优总价值best_value、最优总重量best_weight和最优物品选择数组best_X

四、算法复杂度分析

(一)时间复杂度

  1. calculate_value_density函数中:
    • 有一个外层循环遍历n个项集,内部对于每个项集计算价值和重量组合需要常数时间(不考虑数组操作的时间复杂度),所以这部分时间复杂度为$O(n)$。
  2. NGSOR函数中:
    • 计算价值密度的calculate_value_density函数调用时间复杂度为$O(n)$。
    • 对价值密度数组E进行排序操作的时间复杂度通常为$O(7n log(7n))$,这里简化为$O(n log n)$(忽略常数系数)。
    • 循环部分有7n次迭代,每次迭代内部计算物品选择情况、总重量和总价值的操作时间复杂度为$O(n)$(主要是遍历项集的操作),所以循环部分时间复杂度为$O(n^2)$。
    • 综合来看,算法的时间复杂度主要由循环部分决定,为$O(n^2)$。

(二)空间复杂度

  1. calculate_value_density函数中:
    • 使用了一个形状为(7*n, 2)的数组E,所以空间复杂度为$O(n)$(忽略常数系数)。
  2. NGSOR函数中:
    • 使用了数组EHXbest_X等,其中E的大小为$O(n)$,H的大小为$O(n)$(排序后的索引数组),Xbest_X的大小为$O(n)$(因为是与项集数量相关的数组),所以空间复杂度为$O(n)$。

五、测试示例

  1. 在主函数中:
    • 使用np.random.seed(0)设置随机数种子,确保结果的可重复性。
    • 定义项集数量n5,随机生成价值系数数组P(形状为(n, 3))、质量系数数组W(形状为(n, 3))和折扣系数数组d[1, 0.8, 0.7]),以及背包最大载重C100
  2. 调用NGSOR函数并输出结果,包括最优总价值Optimal Value、最优总重量Optimal Weight和最优物品选择数组Optimal Selection(重塑为(n, 3)的形状)。

通过上述文档,可以清晰地了解NGSOR算法的复现过程,包括算法的背景意义、详细步骤、复杂度分析以及测试示例。
Description

部署方式

  • python 3.8以上
posted @ 2024-12-13 18:02  chuanzhi_tech  阅读(15)  评论(0编辑  收藏  举报