`
Mr.Chris
  • 浏览: 84070 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

0/1背包问题动态规划的Ruby实现

    博客分类:
  • Ruby
阅读更多

 

# encoding:utf-8 
# ruby1.9是用ASCII编码来读源码的, http://zires.info/2011/03/17/invalid-multibyte-char-us-ascii-ruby1-9/

class KnapSack
  attr_reader :weight, :value
  attr_writer :weight, :value
  
  def initialize(weight, value)
    @weight = weight
    @value = value 
  end
  
  def to_s
    "{weight:#{weight}, value:#{value}}"
  end
end

class KnapsackProblem
  attr_writer :bags, :total_weight
  attr_reader :bags, :total_weight, :best_value, :best_values, :best_solutions
  
  def initialize(bags, total_weight)
    @bags = bags
    @total_weight = total_weight
    @n = bags.length
    @best_values = Array.new(@n + 1) { Array.new(@total_weight + 1) } 
    @best_solutions = Array.new
  end
  
  def solve
    puts '给定背包:'
    bags.each do |bag|
      puts bag.to_s
    end
    
    puts '给定总称重: ' + @total_weight.to_s
    
    (0..@total_weight).each do |j| 
      (0..@n).each do |i| 
        if i == 0 || j == 0
          @best_values[i][j] = 0
        else
          if j < @bags[i - 1].weight
            @best_values[i][j] = @best_values[i - 1][j]
          else
            iweight = @bags[i - 1].weight
            ivalue = @bags[i - 1].value
            @best_values[i][j] = [@best_values[i - 1][j], ivalue + @best_values[i - 1][j - iweight]].max
          end
        end
      end
    end  
    
    temp_weight = @total_weight
    @n.downto(1).each do |i|
      if @best_values[i][temp_weight] > @best_values[i - 1][temp_weight]
        @best_solutions.push(@bags[i - 1])
        temp_weight -= @bags[i - 1].weight
        if temp_weight == 0
          break
        end
      end
      @best_value = @best_values[@n][@total_weight]
    end  
  end
end

require "test/unit"
class TestKnapSack < Test::Unit::TestCase
  def test_solve
    bags = [KnapSack.new(2, 13), KnapSack.new(1, 10), KnapSack.new(3, 24), KnapSack.new(2, 15), 
            KnapSack.new(4, 28), KnapSack.new(5, 33), KnapSack.new(3, 20), KnapSack.new(1, 8)]
    total_weight = 12
    kp = KnapsackProblem.new(bags, total_weight)
    kp.solve
    puts " -------- 该背包问题实例的解: --------- "
    puts "最优值:#{kp.best_value}"
    puts "最优解【选取的背包】: "
    print kp.best_solutions, "\n"
    puts "最优值矩阵:"
    best_values = kp.best_values
    best_values.each  do |r|
      r.each do |c|
        printf("%-5d", c) 
      end
      puts
    end
  end
end 

 

关于算法解释,可以参看这篇文章:01背包问题动态规划详解

分享到:
评论

相关推荐

    Ruby算法和数据结构。C扩展_Ruby_C_下载.zip

    4. **动态规划**:解决具有重叠子问题和最优子结构的复杂问题,如斐波那契序列、背包问题、最短路径等。 5. **递归与回溯**:在解决组合问题,如八皇后问题、N皇后问题、迷宫问题时常见。 6. **数据结构实现**:如...

    背包客,旅游社交应用backpacker.zip

    JavaScript:用于在网页上实现交互性和动态效果的脚本语言。 React:一个流行的JavaScript库,用于构建用户界面。 Angular:一个用于构建Web应用的前端框架。 Vue.js:一个渐进式JavaScript框架,用于构建交互式界面...

    ruby_data_structures:Ruby中的数据结构和算法实践

    Ruby可以轻松实现动态规划算法,如背包问题、最长公共子序列等。 十二、字符串操作 Ruby的字符串类提供了丰富的操作,如查找子串、替换、连接等,可以进行复杂的文本处理。 在实践中,理解并熟练掌握这些数据结构...

    leetcode分类-leetcode-challenges:Ruby和Python3中的LeetCode解决方案

    5. 动态规划:通过构建状态转移方程解决多阶段决策问题,常见应用包括背包问题、最长公共子序列、矩阵链乘法等。 6. 排序与搜索:熟练运用不同排序算法,理解其时间复杂性和稳定性;掌握二分查找及其变体,提升查找...

    project_euler

    例如,找到最长递增子序列、背包问题等Project Euler题目可以用动态规划解决。 3. **数学公式和算法**:Ruby可以方便地处理数学运算,如开方、指数、对数等,并且可以用于实现复杂的数学算法,如欧几里得算法求最大...

    algorithm_design_manual:Skiena 算法设计手册的解决方案和内容

    4. **动态规划**:动态规划是一种解决复杂问题的有效方法,如背包问题、最长公共子序列、矩阵链乘法等。Ruby的元编程特性可以方便地构造动态规划的解决方案。 5. **字符串处理**:书中探讨了模式匹配、后缀数组、...

    Personal-algorithm-question

    4. **动态规划**:动态规划是解决复杂问题的有效手段,例如背包问题、最长公共子序列等。Ruby的动态数组和闭包特性使得状态转移方程的实现更为简洁。 5. **回溯法**:适用于解决组合优化问题,如八皇后问题、N皇后...

    study_algorithm

    4. **动态规划**:通过解决背包问题、最长公共子序列、斐波那契数列等经典问题,学习如何利用动态规划来优化问题的解决方案,降低时间复杂度。 5. **数据结构**:数组、链表、栈、队列、哈希表、树等基础数据结构的...

    算法

    5. **动态规划**:解决最优化问题时,动态规划是一种强大工具,例如计算最长公共子序列、背包问题等。Ruby的哈希表可以有效地存储中间状态,以避免重复计算。 6. **贪心算法**:贪心算法在每一步选择局部最优解,...

    algorithm:使用 JavaScriptRubyC++ 实现常用算法

    4. 动态规划:背包问题、最长公共子序列、斐波那契数列。 5. 树算法:二叉搜索树、AVL树、红黑树。 6. 字符串处理:KMP算法(模式匹配)、Rabin-Karp算法(滚动哈希)。 在实际项目中,理解并能够灵活运用这些算法...

    竞赛程序员手册(CompProgHandbook)

    - 求解最大子数组和问题是一个经典的动态规划问题。 - Kadane 算法是一种高效的解决方案,时间复杂度为 O(n)。 - 该问题不仅出现在竞赛中,也在实际应用中有着广泛的用途。 #### 3. 排序 **排序理论:** - 排序算法...

    ruby:一个工程项目,重点是我应该购买的现成打印机

    Ruby设计我最初的设计目标是使它更具视觉吸引力,但更重要的是将其封闭,以便可以在上面打印要求更高/挑剔的材料,例如ABS,ASA,PC等。特征激光切割不锈钢框架(理想情况下为400系列)使用FEA设计的定制设计印刷...

    leetcode285-OJProjects:我的OJProjects解决方案,包括Leetcode、googleOJ

    在LeetCode中,动态规划问题涉及数组、背包问题、最短路径等。 2. **树结构**:树是一种非线性的数据结构,常用于表示层次关系。在LeetCode中,涉及树的问题可能包括二叉搜索树、二叉树遍历、最小生成树等。 3. **...

    PinyonsPines:Pinyons和Pines Bikepacking比赛的网站

    1. **Bikepacking**:Bikepacking是一种结合了山地骑行和长途背包旅行的运动,参与者通常在非铺装道路上骑行,并携带必要的露营装备。PinyonsPines比赛是专门为这种户外探险活动设立的,旨在挑战参赛者的体力、耐力...

    ac-library.cr:ac-library到Crystal编程语言的移植

    - **动态规划**:解决最优化问题,如斐波那契数列、背包问题、最长公共子序列等。 - **贪心算法**:局部最优解来寻找全局最优解,如活动选择问题、最小生成树算法。 - **回溯**:用于解决组合优化问题,如八皇后...

    mhw:一个简单的 Rails LMS 在 MIT 许可下可用

    1. **Ruby on Rails 基础**:理解 Ruby 语言的基础语法和 Rails 框架的架构,如路由、控制器、模型、视图、助手方法等。 2. **数据库设计**:LMS 可能会涉及到用户表、课程表、作业表、成绩表等,需要了解如何使用 ...

    RMVX自带的RGSS2的汉化教程

    4. move_toward_point() / move_away_from_point():在Game_Character类中,这两个函数用于控制角色或事件向指定点移动,实现角色移动的逻辑。 5. create_rect():在Graphics类中,用于创建矩形,常用于绘制图形和...

    RPG Maker XP脚本

    脚本是RPG Maker XP的强大工具之一,它基于Ruby语言,使开发者能够定制游戏的各种行为,包括战斗系统、对话、物品管理和游戏逻辑等。本文将详细介绍RPG Maker XP脚本中的一些关键知识点,帮助游戏开发者更好地理解和...

Global site tag (gtag.js) - Google Analytics