# on linux run # ruby lp.rb # or to get an interpreter.. # [satishr@hiei rough-notes]# ruby -irb -e0 # [satishr@hiei rough-notes]# irb # irb(main):001:0> load "lp.rb" # On windows...install ruby from http://rubyinstaller.rubyforge.org/wiki/wiki.pl # Open command prompt... # either # ruby lp.rb # # or # C:\Whatever> ruby -irb -e0 # C:\Whatever> irb # irb(main):001:0> load "lp.rb" def tableau (mA,b,c) index = 0 final_n = mA.length + mA[0].length c_new = c.map{|d| -d} mA.each{|arr| 0.upto(mA.length-1){|i| if i == index then arr.push(1.0) else arr.push(0.0) end } arr.push(b[index]) index+=1 } 0.upto(mA.length){ c_new.push(0.0) } mA.push(c_new) mA end class Array def to_s result = "" self.each { |d| result += " #{d}; " } result end end def add_scaled_row(mT, scale,source_row,dest_row) # puts "Adding rows #{source_row} scaled by #{scale} to #{dest_row}" 0.upto(mT[0].length-1){|k| # puts "doing column #{k}" mT[dest_row][k] += scale*mT[source_row][k] } #puts "after adding #{mT[dest_row]}" end def pivot (mT,pivot_column,pivot_row) pivot_value = mT[pivot_row][pivot_column] 0.upto(mT[pivot_row].length- 1){|index| mT[pivot_row][index] /= pivot_value } #puts "Pivot row #{mT[pivot_row]} after scaling" 0.upto(mT.length-1){ |row| if row != pivot_row then add_scaled_row(mT,-mT[row][pivot_column]/mT[pivot_row][pivot_column],pivot_row,row) end } end def find_pivot_column(mT) small_value = -0.00001 cost_row = mT.length cost_row -=1 min_improvement = 0 min_i = -1; 0.upto(cost_row-2){|candidate_i| # puts "Checking row #{cost_row} column #{candidate_i} with value #{mT[cost_row][candidate_i]}" if (min_improvement > mT[cost_row][candidate_i]) then min_improvement = mT[cost_row][candidate_i] min_i = candidate_i end } if (min_improvement < small_value) then return min_i end end def find_pivot_row(mT,pivot_column) last_column = mT[0].length-1 large_value =100000000 min_movement = large_value output_row = -1; 0.upto(mT.length-2){|candidate_row| # mT.each{|row| puts "Tableau row is #{row}"} # puts "Checking pivot column #{pivot_column} row #{candidate_row} with value #{mT[candidate_row][pivot_column]} and ratio #{mT[candidate_row][last_column]/mT[candidate_row][pivot_column]}" if mT[candidate_row][pivot_column] > 0 then if (min_movement > mT[candidate_row][last_column]/mT[candidate_row][pivot_column]) then min_movement = mT[candidate_row][last_column]/mT[candidate_row][pivot_column] output_row = candidate_row end end } if (output_row < 0) then return nil else return output_row end end def lp(mA,b,c) mT = tableau(mA,b,c) puts "At beginning " mT.each{|row| puts "Tableau row is #{row}"} while (pivot_column = find_pivot_column(mT)) != nil pivot_row = find_pivot_row(mT,pivot_column) puts "Pivoting column #{pivot_column} and row #{pivot_row}" if (pivot_row == nil) then last end pivot(mT,pivot_column,pivot_row) puts "After pivot. Tableau" mT.each{|row| puts "Tableau row is #{row}"} end puts "Optimal value is #{mT[mT.length-1][mT[0].length-1]}, I hope." end mA = [[1.0,1.0,1.0],[2.0,1.0,2.0],[3.0,1.0,1.0],[4.0,1.0,2.0]] b = [4.0,1.0,1.0,1.0] c=[1.0,0.0,0.0] # f_sb, f_sa, f_ab, f_bt, f_a_t mA = [[1.0,0.0, 1.0, -1.0,0.0],[-1.0,0.0, -1.0, 1.0,0.0], [0.0,1.0, -1.0, 0.0,-1.0], [0.0,-1.0, 1.0, 0.0,1.0], [1.0,0.0,0.0,0.0,0.0], [0.0,1.0,0.0,0.0,0.0], [0.0,0.0,1.0,0.0,0.0], [0.0,0.0,0.0,1.0,0.0], [0.0,0.0,0.0,1.0,0.0]] b = [0.0,0.0,0.0,0.0, 1.0, 1.0, 10000000.0, 1.0, 1.0] c = [1.0,1.0,0.0,0.0,0.0] lp(mA,b,c)