71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
# File 'lib/mgmg/search.rb', line 71
def search(para, target, opt: Mgmg::Option.new)
org_cut_exp = opt.cut_exp
opt = opt.dup.set_default(self)
opt_nocut = opt.dup; opt_nocut.cut_exp = Float::INFINITY
begin
opt.comp_min = comp_search(para, target, opt.smith_max, opt:)
rescue Mgmg::SearchCutException
foo = opt.irep.para_call(para, opt.smith_max, opt.comp_max)
raise Mgmg::SearchCutException, "#{self} could not reach target=#{target} until (smith_max, comp_max)=(#{opt.smith_max}, #{opt.comp_max}), which yields #{foo.comma3}"
end
opt.smith_max = smith_search(para, target, opt.comp_min, opt: opt_nocut)
opt.smith_min = smith_search(para, target, opt.comp_max, opt: opt_nocut)
raise Mgmg::SearchCutException if opt.cut_exp < Mgmg.exp(opt.smith_min, opt.comp_min)
opt.comp_max = comp_search(para, target, opt.smith_min, opt:)
ret = nil
exp = Mgmg.exp(opt.smith_min, opt.comp_max)
opt.cut_exp, ret = exp, [opt.smith_min, opt.comp_max] if exp <= opt.cut_exp
exp = Mgmg.exp(opt.smith_max, opt.comp_min)
opt.cut_exp, ret = exp, [opt.smith_max, opt.comp_min] if ( exp < opt.cut_exp || (ret.nil? && exp==opt.cut_exp) )
eo = opt.irep.eo_para(para)
comps = Mgmg.fib_init(opt.comp_min, opt.comp_max)
values = comps.map do |comp|
r, e = eval_comp(para, target, comp, opt_nocut, eo)
opt.cut_exp, ret = e, r if e < opt.cut_exp
e
end
while 3 < comps[3]-comps[0]
if values[1] <= values[2]
comp = comps[0] + comps[2]-comps[1]
comps = [comps[0], comp, comps[1], comps[2]]
r, e = eval_comp(para, target, comp, opt_nocut, eo)
opt.cut_exp, ret = e, r if e < opt.cut_exp
values = [values[0], e, values[1], values[2]]
else
comp = comps[1] + comps[3]-comps[2]
comps = [comps[1], comps[2], comp, comps[3]]
r, e = eval_comp(para, target, comp, opt_nocut, eo)
opt.cut_exp, ret = e, r if e < opt.cut_exp
values = [values[1], values[2], e, values[3]]
end
end
exp_best = opt.cut_exp
values = values.filter(&:finite?)
diff = values.max-values.min
if 0 < diff
opt.cut_exp = exp_best + diff*opt.fib_ext[0]
(comps[0]-1).downto(opt.comp_min) do |comp|
exp_best, ret = fine(exp_best, ret, para, target, comp, opt, eo)
rescue Mgmg::SearchCutException
break
end
(comps[3]+1).upto(opt.comp_max) do |comp|
exp_best, ret = fine(exp_best, ret, para, target, comp, opt, eo)
rescue Mgmg::SearchCutException
break
end
end
if ret.nil?
max = opt.irep.para_call(para, *find_max(para, org_cut_exp, opt:))
raise Mgmg::SearchCutException, "the maximum output with given cut_exp=#{org_cut_exp.comma3} is #{max.comma3}, which does not reach given target=#{target.comma3}"
end
ret
end
|