# Ruby 一道题解

luikore · 2020年02月24日 · 最后由 lithium4010 回复于 2020年02月26日 · 5700 次阅读

``````var x0;
var x1;
var x2;
var x3;
s.t. c1: 1*x0 + 1*x1 + 0*x2 + 0*x3 <= -0.1;
s.t. c2: 0*x0 + 1*x1 + 1*x2 + 0*x3 <= -0.1;
s.t. c3: 0*x0 + 0*x1 + 1*x2 + 1*x3 <= -0.1;
s.t. c4: 1*x0 + 1*x1 + 1*x2 + 1*x3 >= 0.1;
solve;
display x0,x1,x2,x3;
end;
``````

``````def feasible? vars, args
problem = []
vars.each do |v|
problem << "var #{v};"
end
n = 0
args.each do |(coe, rgt)|
n += 1
lft = coe.zip(vars).map{|(c, v)| "#{c}*#{v}" }.join " + "
problem << "s.t. c#{n}: #{lft} #{rgt};"
end
problem << "solve;"
problem << "display #{vars.join ','};"
problem << "end;"

File.open 'problem.mod', 'w' do |f|
f.puts problem
end
res = `glpsol --math problem.mod`
if \$?.exitstatus != 0
puts res
raise "problem failed"
end
!!res['OPTIMAL LP SOLUTION FOUND']
end

long = 11
short = 7
last_feasible = nil

(long..).each do |i|
vars = (0...i).to_a
args = []

# short consecutives: <= -0.1
vars.each_cons short do |vs|
row = Array.new i, 0
vs.each do |j|
row[j] = 1
end
args << [row,  '<= -0.1']
end

# positive long consecutives: >= 0.1
vars.each_cons long do |vs|
row = Array.new i, 0
vs.each do |j|
row[j] = 1
end
args << [row, '>= 0.1']
end

var_names = vars.map{|j| "x#{j}"}
if feasible?(var_names, args)
puts "Feasible: #{i}"
last_feasible = i
else
break
end
end
puts "Longest sequence: #{last_feasible}"
``````

``````Feasible: 11
Feasible: 12
Feasible: 13
Feasible: 14
Feasible: 15
Feasible: 16
Longest sequence: 16
``````