vogel_s_approximation_method.sf 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #!/usr/bin/ruby
  2. #
  3. ## https://rosettacode.org/wiki/Vogel%27s_approximation_method
  4. #
  5. var costs = :(
  6. W => :(A => 16, B => 16, C => 13, D => 22, E => 17),
  7. X => :(A => 14, B => 14, C => 13, D => 19, E => 15),
  8. Y => :(A => 19, B => 19, C => 20, D => 23, E => 50),
  9. Z => :(A => 50, B => 12, C => 50, D => 15, E => 11)
  10. )
  11. var demand = :(A => 30, B => 20, C => 70, D => 30, E => 60)
  12. var supply = :(W => 50, X => 60, Y => 50, Z => 50)
  13. var cols = demand.keys.sort
  14. var res = :(); costs.each {|k| res{k} = :() }
  15. var g = :(); supply.each {|x| g{x} = costs{x}.keys.sort_by{|g| costs{x}{g} }}
  16. demand.each {|x| g{x} = costs.keys.sort_by{|g| costs{g}{x} }}
  17. while (g) {
  18. var d = demand.collect {|x|
  19. [x, var z = costs{g{x}[0]}{x}, g{x}[1] ? costs{g{x}[1]}{x}-z : z]
  20. }
  21. var s = supply.collect {|x|
  22. [x, var z = costs{x}{g{x}[0]}, g{x}[1] ? costs{x}{g{x}[1]}-z : z]
  23. }
  24. with (d.max_by { .[2] }) { |dmax|
  25. d.grep! { .[2] == dmax[2] }.min_by! { .[1] }
  26. }
  27. with (s.max_by { .[2] }) { |smax|
  28. s.grep! { .[2] == smax[2] }.min_by! { .[1] }
  29. }
  30. var (t,f) = (d[2] == s[2] ? ((s[1], d[1])) : ((d[2], s[2])))
  31. (d,s) = (t > f ? ((d[0], g{d[0]}[0])) : ((g{s[0]}[0],s[0])))
  32. var v = (supply{s} `min` demand{d})
  33. res{s}{d} := 0 += v
  34. demand{d} -= v
  35. if (demand{d} == 0) {
  36. supply.grep {|_,n| n != 0 }.each {|x| g{x}.delete(d) }
  37. g.delete(d)
  38. demand.delete(d)
  39. }
  40. supply{s} -= v
  41. if (supply{s} == 0) {
  42. demand.grep {|_,n| n != 0 }.each {|x| g{x}.delete(s) }
  43. g.delete(s)
  44. supply.delete(s)
  45. }
  46. }
  47. say("\t", cols.join("\t"))
  48. var cost = 0
  49. costs.keys.sort.each { |g|
  50. print(g, "\t")
  51. cols.each { |n|
  52. if (defined(var y = res{g}{n})) {
  53. print(y)
  54. cost += (y * costs{g}{n})
  55. }
  56. print("\t")
  57. }
  58. print("\n")
  59. }
  60. say "\n\nTotal Cost = #{cost}"
  61. assert_eq(cost, 3100)