• 部分背包问题【贪心算法】


    部分背包问题是一种经典的贪心问题,物品可以取一部分,也就是可以随意拆分的物品。

    算法思路:

    1. 用列表保存每个物品的价值及总重量、平均价值(性价比)。
    2. 输入数据同时计算每种物品的平均价值。
    3. 使用自定义的compare函数以及自带的sort函数将结构体进行排序。
    4. 循环遍历从最大平均价值开始放入背包,能放肯定是全部放,不能放就放背包剩余重量。
    5. 最后控制格式输出即可。

    算法核心思想:让背包单位空间价值达到最高

    注释较为详细,此处不再赘述。

    1. from myRandom import randomint_LCG
    2. def KnaspackGreedy(weights, values, capacity):
    3. vw_ratios = [] # 各商品性价比
    4. max_value = 0 # 该背包容量下的最大价值
    5. # 计算性价比
    6. for i in range(len(weights)):
    7. vw_ratio = {} # 字典(记录比率和原索引)用于后续排序
    8. vw_ratio['ratio'] = round(values[i] / weights[i], 2) # 计算性价比(价值/重量)
    9. vw_ratio['index'] = i # 设置索引
    10. vw_ratios.append(vw_ratio) # 将计算该商品的性价比、原索引字典添加到列表中
    11. print("性价比:{}".format(vw_ratios)) # 打印计算好的各商品性价比、原索引
    12. vw_ratios.sort(key=compare, reverse=True) # 将性价比数组排序,排序依据列表每项字典中的“ratio”值
    13. print("性价比(排序):{}".format(vw_ratios)) # 打印排序好的性价比列表
    14. best_select = [] # 最佳选择的商品序列(取了全部还是部分)
    15. # 开始装填背包(从高性价比商品开始遍历)
    16. for vw_ratio in vw_ratios:
    17. # 如果该商品重量小于当前背包剩余容量
    18. if weights[vw_ratio['index']] < capacity:
    19. good = {}
    20. # 减小背包容量
    21. capacity -= weights[vw_ratio['index']]
    22. # 更新当前背包最大价值
    23. max_value += values[vw_ratio['index']]
    24. # 将该物品添加到最佳选择队列中
    25. good['index'] = vw_ratio['index']
    26. good['weights'] = weights[vw_ratio['index']]
    27. best_select.append(good)
    28. else: # 否则背包不能装下该商品全部
    29. good = {}
    30. # 将背包剩余容量全部装该商品
    31. good['weights'] = capacity
    32. good['index'] = vw_ratio['index']
    33. max_value += capacity * vw_ratio['ratio']
    34. # 背包剩余容量清零
    35. capacity = 0
    36. # 将该物品添加到最佳选择队列中
    37. good['index'] = vw_ratio['index']
    38. max_value += capacity * vw_ratio['ratio']
    39. best_select.append(good)
    40. # 如果背包剩余容量清零则终止遍历
    41. if capacity == 0:
    42. break
    43. print("最佳商品选择:{}".format(best_select))
    44. print("背包最大价值:{}".format(max_value))
    45. return best_select
    46. # 自定义排序比较方案
    47. def compare(onedict):
    48. return onedict['ratio']
    49. if __name__ == '__main__':
    50. num = 2 # 商品数量
    51. # 随机生成商品价值和重量
    52. values = randomint_LCG(num, 0, 50)
    53. print("价值:{}".format(values))
    54. weights = randomint_LCG(num, 1, 20)
    55. print("重量:{}".format(weights))
    56. # 背包最大容量(问题规模)
    57. capacity = 10
    58. print("背包容量:{}".format(capacity))
    59. KnaspackGreedy(weights, values, capacity)

     随机数生成函数(也可以使用自带的random模块改写,笔者此处是从实现随机数底层写)

    1. import time
    2. # 随机数生成器
    3. def randomint_LCG(length, start, end):
    4. """线性同余生成器。
    5. seed -- 随机数的种子
    6. a -- 线性同余生成器的常数
    7. c -- 线性同余生成器的常数
    8. x_0 -- 其实计算点
    9. length -- 要生成的随机数的数量
    10. start -- 随机数范围开始的值
    11. end -- 随机数范围结束的值
    12. """
    13. a = int(time.time()) % 54321
    14. c = int(time.time()) % 12345
    15. x_0 = int(time.time()) % 78945
    16. random_numbers = []
    17. random_numbers.append((a * x_0 + c) % (end - start) + start) # 初始化第一个随机数
    18. for i in range(1, length):
    19. random_numbers.append((random_numbers[i - 1] + c) % (end - start) + start) # 计算后续随机数
    20. return random_numbers

    运行测试:

  • 相关阅读:
    django: You may need to add ‘localhost‘ to ALLOWED_HOSTS
    MySQL 入门教程
    FineReport复杂表格软件- 决策报表数据源
    国外问卷调查赚钱靠谱吗?
    数据结构之哈希表
    助力智慧交通,开发构建道路交通场景下智能车辆检测识别系统
    QT学习总结之QObject详解
    《痞子衡嵌入式半月刊》 第 49 期
    斑马打印机二维码标签制作(.prn文件)基础简单快速上手
    【python小游戏】飞机大作战源码分享(附完整源码+图片资源可直接运行)
  • 原文地址:https://blog.csdn.net/weixin_64811333/article/details/134388994