mgmg 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/lib/mgmg/option.rb +6 -6
- data/lib/mgmg/search.rb +39 -169
- data/lib/mgmg/version.rb +1 -1
- data/reference.md +5 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79211ca6cd5422500f7dc957eadfb2c1812459c98fd39b84fc9a3ebf178174ec
|
4
|
+
data.tar.gz: efa0254194363114aee22993e78cab9359e9a7c92f454d5fffc12b1d14368e6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 822a754eeeec7b9b9e8d6f1497041c153a56b62d190da8101f798e9b78334cc64406f35167623387c346b9f2453027a7e17a3ebaefc2ec4d38cbfcbe381b01e6
|
7
|
+
data.tar.gz: f43028c621ea4025123c1ca338f46c8965d545a8f6a92569cc5bb7f5279d11ea01be0dbe6453c1ffe06c831c55be1cdf439ed66b81fa8e08a4d01ac994348e5f
|
data/CHANGELOG.md
CHANGED
@@ -184,3 +184,8 @@
|
|
184
184
|
- `Mgmg.#find_upperbound`のアルゴリズムに誤りがあり,大きく間違えた解を返していた問題を修正.
|
185
185
|
- `Mgmg::IR#attack`等において,引数が`nil`(製作Lvを指定せず,多項式を返す)の場合に,例外となっていたバグを修正.
|
186
186
|
- オブション`smith/armor/comp_max`のデフォルト値を10^9に変更.
|
187
|
+
|
188
|
+
## 1.8.0 2022/11/14
|
189
|
+
- オプション`comp_ext`を`fib_ext`に変更し,追加探索の範囲を修正.
|
190
|
+
- オプション`smith/armor/comp_max`の扱い方を修正し,デフォルト値を10^5に変更.
|
191
|
+
- `Enumerable#find_max`,`Mgmg.#find_lowerbound`のバグを修正.
|
data/lib/mgmg/option.rb
CHANGED
@@ -2,13 +2,13 @@ module Mgmg
|
|
2
2
|
class Option
|
3
3
|
Defaults = {
|
4
4
|
left_associative: true, include_system_equips: true,
|
5
|
-
smith_max:
|
6
|
-
|
5
|
+
smith_max: 100_000, armor_max: 100_000, comp_max: 100_000,
|
6
|
+
fib_ext: [4, 10]
|
7
7
|
}
|
8
8
|
def initialize(
|
9
9
|
left_associative: Defaults[:left_associative],
|
10
10
|
smith_min: nil, armor_min:nil, comp_min: nil, smith_max: Defaults[:smith_max], armor_max: Defaults[:armor_max], comp_max: Defaults[:comp_max],
|
11
|
-
|
11
|
+
fib_ext: Defaults[:fib_ext],
|
12
12
|
magdef_maximize: true,
|
13
13
|
target_weight: 0, reinforcement: [], buff: nil,
|
14
14
|
irep: nil, cut_exp: Float::INFINITY,
|
@@ -21,7 +21,7 @@ module Mgmg
|
|
21
21
|
@smith_max = smith_max
|
22
22
|
@armor_max = armor_max
|
23
23
|
@comp_max = comp_max
|
24
|
-
@
|
24
|
+
@fib_ext = fib_ext
|
25
25
|
@magdef_maximize = magdef_maximize
|
26
26
|
@target_weight = target_weight
|
27
27
|
@reinforcement = reinforcement
|
@@ -37,7 +37,7 @@ module Mgmg
|
|
37
37
|
@include_system_equips = include_system_equips
|
38
38
|
@system_equips_checked = false
|
39
39
|
end
|
40
|
-
attr_accessor :left_associative, :smith_min, :armor_min, :comp_min, :smith_max, :armor_max, :comp_max, :
|
40
|
+
attr_accessor :left_associative, :smith_min, :armor_min, :comp_min, :smith_max, :armor_max, :comp_max, :fib_ext
|
41
41
|
attr_accessor :magdef_maximize, :target_weight, :reinforcement, :irep, :cut_exp, :include_system_equips, :system_equips_checked
|
42
42
|
def initialize_copy(other)
|
43
43
|
@left_associative = other.left_associative
|
@@ -47,7 +47,7 @@ module Mgmg
|
|
47
47
|
@smith_max = other.smith_max
|
48
48
|
@armor_max = other.armor_max
|
49
49
|
@comp_max = other.comp_max
|
50
|
-
@
|
50
|
+
@fib_ext = other.fib_ext.dup
|
51
51
|
@magdef_maximize = other.magdef_maximize
|
52
52
|
@target_weight = other.target_weight
|
53
53
|
@reinforcement = other.reinforcement.dup
|
data/lib/mgmg/search.rb
CHANGED
@@ -34,7 +34,7 @@ class String
|
|
34
34
|
if target <= opt.irep.para_call(para, smith, opt.comp_min)
|
35
35
|
return opt.comp_min
|
36
36
|
elsif opt.irep.para_call(para, smith, opt.comp_max) < target
|
37
|
-
raise Mgmg::SearchCutException
|
37
|
+
raise Mgmg::SearchCutException, "given comp_max=#{opt.comp_max} does not satisfies the target"
|
38
38
|
end
|
39
39
|
while 1 < opt.comp_max - opt.comp_min do
|
40
40
|
comp = (opt.comp_max - opt.comp_min).div(2) + opt.comp_min
|
@@ -71,7 +71,12 @@ class String
|
|
71
71
|
def search(para, target, opt: Mgmg::Option.new)
|
72
72
|
opt = opt.dup.set_default(self)
|
73
73
|
opt_nocut = opt.dup; opt_nocut.cut_exp = Float::INFINITY
|
74
|
-
|
74
|
+
begin
|
75
|
+
opt.comp_min = comp_search(para, target, opt.smith_max, opt:)
|
76
|
+
rescue Mgmg::SearchCutException
|
77
|
+
foo = opt.irep.para_call(para, opt.smith_max, opt.comp_max)
|
78
|
+
raise Mgmg::SearchCutException, "#{self} could not reach target=#{target} until (smith_max, comp_max)=(#{opt.smith_max}, #{opt.comp_max}), which yields #{foo.comma3}"
|
79
|
+
end
|
75
80
|
opt.smith_max = smith_search(para, target, opt.comp_min, opt: opt_nocut)
|
76
81
|
opt.smith_min = smith_search(para, target, opt.comp_max, opt: opt_nocut)
|
77
82
|
raise Mgmg::SearchCutException if opt.cut_exp < Mgmg.exp(opt.smith_min, opt.comp_min)
|
@@ -104,7 +109,8 @@ class String
|
|
104
109
|
end
|
105
110
|
end
|
106
111
|
exp_best = opt.cut_exp
|
107
|
-
|
112
|
+
diff = values.max-values.min
|
113
|
+
opt.cut_exp = exp_best + diff*opt.fib_ext[0]
|
108
114
|
(comps[0]-1).downto(opt.comp_min) do |comp|
|
109
115
|
exp_best, ret = fine(exp_best, ret, para, target, comp, opt, eo)
|
110
116
|
rescue Mgmg::SearchCutException
|
@@ -170,7 +176,8 @@ class String
|
|
170
176
|
values = [values[1], values[2], cur, values[3]]
|
171
177
|
end
|
172
178
|
end
|
173
|
-
|
179
|
+
diff = values.max-values.min
|
180
|
+
th = max - diff*opt.fib_ext[1]
|
174
181
|
(comps[0]-1).downto(opt.comp_min) do |comp|
|
175
182
|
next if ( eo & (2**(comp&1)) == 0 )
|
176
183
|
cur, smith = eval_comp_fm(para, comp, eo, opt, max, max_exp)
|
@@ -292,7 +299,7 @@ module Enumerable
|
|
292
299
|
if target <= opt.irep.para_call(para, smith, armor, opt.comp_min)
|
293
300
|
return opt.comp_min
|
294
301
|
elsif opt.irep.para_call(para, smith, armor, opt.comp_max) < target
|
295
|
-
raise
|
302
|
+
raise Mgmg::SearchCutException, "given comp_max=#{opt.comp_max} does not satisfies the target"
|
296
303
|
end
|
297
304
|
while 1 < opt.comp_max - opt.comp_min do
|
298
305
|
comp = (opt.comp_max - opt.comp_min).div(2) + opt.comp_min
|
@@ -304,152 +311,6 @@ module Enumerable
|
|
304
311
|
end
|
305
312
|
opt.comp_max
|
306
313
|
end
|
307
|
-
private def eval_comp_a(para, target, comp, opt, eo)
|
308
|
-
return [nil, Float::INFINITY] if (comp < opt.comp_min or opt.comp_max < comp)
|
309
|
-
comp -= 1 if ( opt.comp_min<comp and eo & (2**(comp&1)) == 0 )
|
310
|
-
armor = armor_search(para, target, -1, comp, opt:)
|
311
|
-
exp = Mgmg.exp(armor, comp)
|
312
|
-
[[-1, armor, comp], exp]
|
313
|
-
rescue Mgmg::SearchCutException
|
314
|
-
[nil, Float::INFINITY]
|
315
|
-
end
|
316
|
-
private def fine_a(exp_best, ret, para, target, comp, opt, eo)
|
317
|
-
return [exp_best, ret] if eo & (2**(comp&1)) == 0
|
318
|
-
armor = armor_search(para, target, -1, comp, opt:)
|
319
|
-
exp = Mgmg.exp(armor, comp)
|
320
|
-
if exp < exp_best
|
321
|
-
exp_best, ret = exp, [-1, armor, comp]
|
322
|
-
elsif exp == exp_best
|
323
|
-
if ret.nil? or opt.irep.para_call(para, *ret) < opt.irep.para_call(para, -1, armor, comp) then
|
324
|
-
ret = [-1, armor, comp]
|
325
|
-
end
|
326
|
-
end
|
327
|
-
[exp_best, ret]
|
328
|
-
end
|
329
|
-
private def search_aonly(para, target, opt: Mgmg::Option.new)
|
330
|
-
opt_nocut = opt.dup; opt_nocut.cut_exp = Float::INFINITY
|
331
|
-
opt.armor_max = armor_search(para, target, -1, opt.comp_min, opt: opt_nocut)
|
332
|
-
opt.armor_min = armor_search(para, target, -1, opt.comp_max, opt: opt_nocut)
|
333
|
-
raise Mgmg::SearchCutException if opt.cut_exp < Mgmg.exp(opt.armor_min, opt.comp_min)
|
334
|
-
opt.comp_max = comp_search(para, target, -1, opt.armor_min, opt:)
|
335
|
-
ret = nil
|
336
|
-
exp = Mgmg.exp(opt.armor_min, opt.comp_max)
|
337
|
-
opt.cut_exp, ret = exp, [-1, opt.armor_min, opt.comp_max] if exp <= opt.cut_exp
|
338
|
-
exp = Mgmg.exp(opt.armor_max, opt.comp_min)
|
339
|
-
opt.cut_exp, ret = exp, [-1, opt.armor_max, opt.comp_min] if ( exp < opt.cut_exp || (ret.nil? && exp==opt.cut_exp) )
|
340
|
-
eo = opt.irep.eo_para(para)
|
341
|
-
comps = Mgmg.fib_init(opt.comp_min, opt.comp_max)
|
342
|
-
values = comps.map do |comp|
|
343
|
-
r, e = eval_comp_a(para, target, comp, opt_nocut, eo)
|
344
|
-
opt.cut_exp, ret = e, r if e < opt.cut_exp
|
345
|
-
e
|
346
|
-
end
|
347
|
-
while 3 < comps[3]-comps[0]
|
348
|
-
if values[1] <= values[2]
|
349
|
-
comp = comps[0] + comps[2]-comps[1]
|
350
|
-
comps = [comps[0], comp, comps[1], comps[2]]
|
351
|
-
r, e = eval_comp_a(para, target, comp, opt_nocut, eo)
|
352
|
-
opt.cut_exp, ret = e, r if e < opt.cut_exp
|
353
|
-
values = [values[0], e, values[1], values[2]]
|
354
|
-
else
|
355
|
-
comp = comps[1] + comps[3]-comps[2]
|
356
|
-
comps = [comps[1], comps[2], comp, comps[3]]
|
357
|
-
r, e = eval_comp_a(para, target, comp, opt_nocut, eo)
|
358
|
-
opt.cut_exp, ret = e, r if e < opt.cut_exp
|
359
|
-
values = [values[1], values[2], e, values[3]]
|
360
|
-
end
|
361
|
-
end
|
362
|
-
exp_best = opt.cut_exp
|
363
|
-
opt.cut_exp = exp_best + (exp_best*opt.comp_ext[0]).to_i.clamp(opt.comp_ext[1], opt.comp_ext[2])
|
364
|
-
(comps[0]-1).downto(opt.comp_min) do |comp|
|
365
|
-
exp_best, ret = fine_a(exp_best, ret, para, target, comp, opt, eo)
|
366
|
-
rescue Mgmg::SearchCutException
|
367
|
-
break
|
368
|
-
end
|
369
|
-
(comps[3]+1).upto(opt.comp_max) do |comp|
|
370
|
-
exp_best, ret = fine_a(exp_best, ret, para, target, comp, opt, eo)
|
371
|
-
rescue Mgmg::SearchCutException
|
372
|
-
break
|
373
|
-
end
|
374
|
-
if ret.nil?
|
375
|
-
max = opt.irep.para_call(para, *find_max(para, opt.cut_exp, opt:))
|
376
|
-
raise Mgmg::SearchCutException, "the maximum output with given cut_exp=#{opt.cut_exp.comma3} is #{max.comma3}, which does not reach given target=#{target.comma3}"
|
377
|
-
end
|
378
|
-
ret
|
379
|
-
end
|
380
|
-
private def eval_comp_s(para, target, comp, opt, eo)
|
381
|
-
return [nil, Float::INFINITY] if (comp < opt.comp_min or opt.comp_max < comp)
|
382
|
-
comp -= 1 if ( opt.comp_min<comp and eo & (2**(comp&1)) == 0 )
|
383
|
-
smith = smith_search(para, target, -1, comp, opt:)
|
384
|
-
exp = Mgmg.exp(smith, comp)
|
385
|
-
[[smith, -1, comp], exp]
|
386
|
-
rescue Mgmg::SearchCutException
|
387
|
-
[nil, Float::INFINITY]
|
388
|
-
end
|
389
|
-
private def fine_s(exp_best, ret, para, target, comp, opt, eo)
|
390
|
-
return [exp_best, ret] if eo & (2**(comp&1)) == 0
|
391
|
-
smith = smith_search(para, target, -1, comp, opt:)
|
392
|
-
exp = Mgmg.exp(smith, comp)
|
393
|
-
if exp < exp_best
|
394
|
-
exp_best, ret = exp, [smith, -1, comp]
|
395
|
-
elsif exp == exp_best
|
396
|
-
if ret.nil? or opt.irep.para_call(para, *ret) < opt.irep.para_call(para, smith, -1, comp) then
|
397
|
-
ret = [smith, -1, comp]
|
398
|
-
end
|
399
|
-
end
|
400
|
-
[exp_best, ret]
|
401
|
-
end
|
402
|
-
private def search_sonly(para, target, opt: Mgmg::Option.new)
|
403
|
-
opt_nocut = opt.dup; opt_nocut.cut_exp = Float::INFINITY
|
404
|
-
opt.smith_max = smith_search(para, target, -1, opt.comp_min, opt: opt_nocut)
|
405
|
-
opt.smith_min = smith_search(para, target, -1, opt.comp_max, opt: opt_nocut)
|
406
|
-
raise Mgmg::SearchCutException if opt.cut_exp < Mgmg.exp(opt.smith_min, opt.comp_min)
|
407
|
-
opt.comp_max = comp_search(para, target, opt.smith_min, -1, opt:)
|
408
|
-
ret = nil
|
409
|
-
exp = Mgmg.exp(opt.smith_min, opt.comp_max)
|
410
|
-
opt.cut_exp, ret = exp, [opt.smith_min, -1, opt.comp_max] if exp <= opt.cut_exp
|
411
|
-
exp = Mgmg.exp(opt.smith_max, opt.comp_min)
|
412
|
-
opt.cut_exp, ret = exp, [opt.smith_max, -1, opt.comp_min] if ( exp < opt.cut_exp || (ret.nil? && exp==opt.cut_exp) )
|
413
|
-
eo = opt.irep.eo_para(para)
|
414
|
-
comps = Mgmg.fib_init(opt.comp_min, opt.comp_max)
|
415
|
-
values = comps.map do |comp|
|
416
|
-
r, e = eval_comp_s(para, target, comp, opt_nocut, eo)
|
417
|
-
opt.cut_exp, ret = e, r if e < opt.cut_exp
|
418
|
-
e
|
419
|
-
end
|
420
|
-
while 3 < comps[3]-comps[0]
|
421
|
-
if values[1] <= values[2]
|
422
|
-
comp = comps[0] + comps[2]-comps[1]
|
423
|
-
comps = [comps[0], comp, comps[1], comps[2]]
|
424
|
-
r, e = eval_comp_s(para, target, comp, opt_nocut, eo)
|
425
|
-
opt.cut_exp, ret = e, r if e < opt.cut_exp
|
426
|
-
values = [values[0], e, values[1], values[2]]
|
427
|
-
else
|
428
|
-
comp = comps[1] + comps[3]-comps[2]
|
429
|
-
comps = [comps[1], comps[2], comp, comps[3]]
|
430
|
-
r, e = eval_comp_s(para, target, comp, opt_nocut, eo)
|
431
|
-
opt.cut_exp, ret = e, r if e < opt.cut_exp
|
432
|
-
values = [values[1], values[2], e, values[3]]
|
433
|
-
end
|
434
|
-
end
|
435
|
-
exp_best = opt.cut_exp
|
436
|
-
opt.cut_exp = exp_best + (exp_best*opt.comp_ext[0]).to_i.clamp(opt.comp_ext[1], opt.comp_ext[2])
|
437
|
-
(comps[0]-1).downto(opt.comp_min) do |comp|
|
438
|
-
exp_best, ret = fine_s(exp_best, ret, para, target, comp, opt, eo)
|
439
|
-
rescue Mgmg::SearchCutException
|
440
|
-
break
|
441
|
-
end
|
442
|
-
(comps[3]+1).upto(opt.comp_max) do |comp|
|
443
|
-
exp_best, ret = fine_s(exp_best, ret, para, target, comp, opt, eo)
|
444
|
-
rescue Mgmg::SearchCutException
|
445
|
-
break
|
446
|
-
end
|
447
|
-
if ret.nil?
|
448
|
-
max = opt.irep.para_call(para, *find_max(para, opt.cut_exp, opt:))
|
449
|
-
raise Mgmg::SearchCutException, "the maximum output with given cut_exp=#{opt.cut_exp.comma3} is #{max.comma3}, which does not reach given target=#{target.comma3}"
|
450
|
-
end
|
451
|
-
ret
|
452
|
-
end
|
453
314
|
private def eval_comp_sa(para, target, comp, opt, eo)
|
454
315
|
return [nil, Float::INFINITY] if (comp < opt.comp_min or opt.comp_max < comp)
|
455
316
|
comp -= 1 if ( opt.comp_min<comp and eo & (2**(comp&1)) == 0 )
|
@@ -474,10 +335,15 @@ module Enumerable
|
|
474
335
|
end
|
475
336
|
def search(para, target, opt: Mgmg::Option.new)
|
476
337
|
opt = opt.dup.set_default(self)
|
477
|
-
|
338
|
+
begin
|
339
|
+
opt.comp_min = comp_search(para, target, opt.smith_max, opt.armor_max, opt:)
|
340
|
+
rescue Mgmg::SearchCutException
|
341
|
+
foo = opt.irep.para_call(para, opt.smith_max, opt.armor_max, opt.comp_max)
|
342
|
+
raise Mgmg::SearchCutException, "#{self} could not reach target=#{target} until (smith_max, armor_max, comp_max)=(#{opt.smith_max}, #{opt.armor_max}, #{opt.comp_max}), which yields #{foo.comma3}"
|
343
|
+
end
|
478
344
|
opt_nocut = opt.dup; opt_nocut.cut_exp = Float::INFINITY
|
479
|
-
opt.smith_max = smith_search(para, target, opt.armor_min, opt.comp_min, opt: opt_nocut) rescue (
|
480
|
-
opt.armor_max = armor_search(para, target, opt.smith_min, opt.comp_min, opt: opt_nocut) rescue (
|
345
|
+
opt.smith_max = smith_search(para, target, opt.armor_min, opt.comp_min, opt: opt_nocut) rescue ( opt.smith_max )
|
346
|
+
opt.armor_max = armor_search(para, target, opt.smith_min, opt.comp_min, opt: opt_nocut) rescue ( opt.armor_max )
|
481
347
|
opt.smith_min = smith_search(para, target, opt.armor_max, opt.comp_max, opt: opt_nocut)
|
482
348
|
opt.armor_min = armor_search(para, target, opt.smith_max, opt.comp_max, opt: opt_nocut)
|
483
349
|
raise Mgmg::SearchCutException if opt.cut_exp < Mgmg.exp(opt.smith_min, opt.armor_min, opt.comp_min)
|
@@ -507,7 +373,8 @@ module Enumerable
|
|
507
373
|
end
|
508
374
|
end
|
509
375
|
exp_best = opt.cut_exp
|
510
|
-
|
376
|
+
diff = values.max-values.min
|
377
|
+
opt.cut_exp = exp_best + diff*opt.fib_ext[0]
|
511
378
|
(comps[0]-1).downto(opt.comp_min) do |comp|
|
512
379
|
exp_best, ret = fine_sa(exp_best, ret, para, target, comp, opt, eo)
|
513
380
|
rescue Mgmg::SearchCutException
|
@@ -539,13 +406,15 @@ module Enumerable
|
|
539
406
|
end
|
540
407
|
private def eval_arm(para, armor, comp, eo, opt, ret, max, max_exp)
|
541
408
|
smith = Mgmg.invexp3(max_exp, armor, comp)
|
409
|
+
exp = Mgmg.exp(smith, armor, comp)
|
410
|
+
return [-Float::INFINITY, ret, max] if max_exp < exp
|
542
411
|
cur = opt.irep.para_call(para, smith, armor, comp)
|
543
412
|
smith = minimize_smith(para, smith, armor, comp, cur, opt) if max <= cur
|
544
|
-
ret, max = [smith, armor, comp], cur if ( max < cur || ( max == cur &&
|
413
|
+
ret, max = [smith, armor, comp], cur if ( max < cur || ( max == cur && exp < Mgmg.exp(*ret) ) )
|
545
414
|
[cur, ret, max]
|
546
415
|
end
|
547
416
|
private def eval_comp_fm(para, comp, eo, opt, ret, max, max_exp)
|
548
|
-
return [-Float::INFINITY,
|
417
|
+
return [-Float::INFINITY, ret, max] if (comp < opt.comp_min or opt.comp_max < comp)
|
549
418
|
comp -= 1 if ( opt.comp_min<comp and ( eo & (2**(comp&1)) == 0 ) )
|
550
419
|
cur = -Float::INFINITY
|
551
420
|
a_max = [opt.armor_max, Mgmg.invexp3(max_exp, opt.smith_min, comp)].min
|
@@ -569,7 +438,8 @@ module Enumerable
|
|
569
438
|
cur = cur_i if cur < cur_i
|
570
439
|
end
|
571
440
|
end
|
572
|
-
|
441
|
+
diff = a_vals.max-a_vals.min
|
442
|
+
th = max - diff*opt.fib_ext[1]
|
573
443
|
(arms[0]-1).downto(opt.armor_min) do |armor|
|
574
444
|
cur_i, ret, max = eval_arm(para, armor, comp, eo, opt, ret, max, max_exp)
|
575
445
|
break if cur_i < th
|
@@ -608,7 +478,8 @@ module Enumerable
|
|
608
478
|
values = [values[1], values[2], cur, values[3]]
|
609
479
|
end
|
610
480
|
end
|
611
|
-
|
481
|
+
diff = values.max-values.min
|
482
|
+
th = max - diff*opt.fib_ext[1]
|
612
483
|
(comps[0]-1).downto(opt.comp_min) do |comp|
|
613
484
|
next if ( eo & (2**(comp&1)) == 0 )
|
614
485
|
cur, ret, max = eval_comp_fm(para, comp, eo, opt, ret, max, max_exp)
|
@@ -670,28 +541,27 @@ module Mgmg
|
|
670
541
|
loop do
|
671
542
|
foo = a.find_max(para, eb, opt: opt_a)
|
672
543
|
break if sca == foo
|
673
|
-
|
544
|
+
bar = opt_a.irep.para_call(para, *foo)
|
545
|
+
break if bar < pa
|
546
|
+
sca, pa = foo, bar
|
674
547
|
scb = b.search(para, pa, opt: opt_b)
|
675
548
|
foo = Mgmg.exp(*scb)
|
676
549
|
break if eb == foo
|
677
550
|
eb = foo
|
678
551
|
end
|
679
552
|
ea = Mgmg.exp(*sca)
|
680
|
-
|
681
|
-
tag = pa + Eighth
|
682
|
-
raise Mgmg::SearchCutException, "given recipes are never reversed from start target=#{start.comma3} until term target=#{term.comma3}" if term < tag
|
683
|
-
sca, scb = a.search(para, tag, opt: opt_a), b.search(para, tag, opt: opt_b)
|
684
|
-
ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
|
685
|
-
pa, pb = opt_a.irep.para_call(para, *sca), opt_b.irep.para_call(para, *scb)
|
686
|
-
break if ea == eb && pa < pb
|
687
|
-
end
|
688
|
-
if eb < ea || ( ea == eb && pa < pb )
|
553
|
+
if (eb <= ea and pa <= pb and (eb+pa)!=(ea+pb)) or (eb < ea and sca == a.search(para, pb, opt: opt_a)) then
|
689
554
|
until ea < eb || ( ea == eb && pb < pa )
|
690
555
|
sca = a.find_max(para, ea-1, opt: opt_a)
|
691
556
|
ea, pa = Mgmg.exp(*sca), opt_a.irep.para_call(para, *sca)
|
692
557
|
end
|
693
558
|
return [pa, pb]
|
694
559
|
end
|
560
|
+
tag = pa + Eighth
|
561
|
+
raise Mgmg::SearchCutException, "given recipes are never reversed from start target=#{start.comma3} until term target=#{term.comma3}" if term < tag
|
562
|
+
sca, scb = a.search(para, tag, opt: opt_a), b.search(para, tag, opt: opt_b)
|
563
|
+
ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
|
564
|
+
pa, pb = opt_a.irep.para_call(para, *sca), opt_b.irep.para_call(para, *scb)
|
695
565
|
end
|
696
566
|
raise UnexpectedError
|
697
567
|
end
|
data/lib/mgmg/version.rb
CHANGED
data/reference.md
CHANGED
@@ -130,9 +130,9 @@
|
|
130
130
|
`opt`は,`comp_min`,`comp_max`,`left_associative`,`reinforcement`,`irep`を使用します.
|
131
131
|
|
132
132
|
## `String#search(para, target, opt: Mgmg.option())`
|
133
|
-
合計経験値が最小となる鍛冶・防具製作Lvと道具製作Lvの組を探索します.道具製作Lvを決定変数として,`smith_search`の返り値との合計経験値を最小化する道具製作Lvをフィボナッチ探索で探索した後,得られた解 c
|
133
|
+
合計経験値が最小となる鍛冶・防具製作Lvと道具製作Lvの組を探索します.道具製作Lvを決定変数として,`smith_search`の返り値との合計経験値を最小化する道具製作Lvをフィボナッチ探索で探索した後,得られた解 c の前後を探索し,最適化します.このとき,道具製作Lv c における合計経験値`exp`,及びフィボナッチ探索で得られた最後の4点の経験値の最大値`exp2`に対して,`exp+(exp2-exp)*opt.fib_ext[0]`を超えない範囲を探索します.この目的関数は単峰ではないため,フィボナッチ探索のみでは最適解が得られないことがあります.
|
134
134
|
|
135
|
-
その他は`String#smith_seach`と同様で,`opt`は,`String#smith_search`または`String#comp_search`で使われるすべてのパラメータと,`
|
135
|
+
その他は`String#smith_seach`と同様で,`opt`は,`String#smith_search`または`String#comp_search`で使われるすべてのパラメータと,`fib_ext`を使用します.
|
136
136
|
|
137
137
|
## `Enumerable#search(para, target, opt: Mgmg.option())`
|
138
138
|
複数装備の組について,`para`の値が`target`以上となる最小経験値の`[鍛冶Lv,防具製作Lv,道具製作Lv]`を返します.
|
@@ -145,7 +145,7 @@
|
|
145
145
|
## `String#find_max(para, max_exp, opt: Mgmg.option())`
|
146
146
|
経験値の合計が`max_exp`以下の範囲で,`para`の値が最大となる鍛冶・防具製作Lvと道具製作Lvからなる配列を返します.`para`の値が最大となる組が複数存在する場合,経験値が小さい方が優先されます.
|
147
147
|
|
148
|
-
`String#search`と同様に,道具製作Lvをフィボナッチ探索で探索した後,得られた解 c の前後を探索し,最適化します.道具製作Lv c における最大の`para`値`p_c`に対して,`p_c-(p_c*opt.
|
148
|
+
`String#search`と同様に,道具製作Lvをフィボナッチ探索で探索した後,得られた解 c の前後を探索し,最適化します.道具製作Lv c における最大の`para`値`p_c`,及びフィボナッチ探索で得られた最後の4点の`para`値の最小値`p_min`に対して,`p_c-(p_c-p_min)*opt.fib_ext[1]`を下回らない範囲を探索します.
|
149
149
|
|
150
150
|
## `Enumerable#find_max(para, max_exp, opt: Mgmg.option())`
|
151
151
|
複数装備の組について,経験値の合計が`max_exp`以下の範囲で,`para`の値が最大となる鍛冶Lv,防具製作Lv,道具製作Lvからなる配列を返します.`para`の値が最大となる組が複数存在する場合,経験値が小さい方が優先されます.
|
@@ -454,8 +454,8 @@ alias として`*`があるほか`scalar(1.quo(value))`として`quo`,`/`,`s
|
|
454
454
|
|smith_min|`recipe.min_level(target_weight)`|非対応|鍛冶Lvに関する探索範囲の最小値|`String#search`など|
|
455
455
|
|armor_min|`recipe.min_level(*target_weight)[1]`|非対応|防具製作Lvに関する探索範囲の最小値|`Enumerable#search`など.`String`系では代わりに`smith_min`を使う|
|
456
456
|
|comp_min|`recipe.min_comp`|非対応|道具製作Lvに関する探索範囲の最小値|`String#search`など|
|
457
|
-
|smith_max, armor_max, comp_max|`
|
458
|
-
|
|
457
|
+
|smith_max, armor_max, comp_max|`100_000`|対応|各製作Lvの探索範囲の最大値|`String#search`など|
|
458
|
+
|fib_ext|`[4, 10]`|対応|フィボナッチ探索後に追加探索を行う範囲|`String#search`など|
|
459
459
|
|target_weight|`0`|非対応|`smith_min`のデフォルト値計算に使う目標重量|`String#search`など|
|
460
460
|
|magdef_maximize|`true`|非対応|目標を魔防最大(真)かコスト最小(偽)にするためのスイッチ|`String#phydef_optimize`|
|
461
461
|
|reinforcement|`[]`|非対応|[前述](#mgmgequipreinforcearg)の`Mgmg::Equip#reinforce`による強化リスト|一部を除くすべてのメソッド|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mgmg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- KAZOON
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-11-
|
11
|
+
date: 2022-11-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|