Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- def f2(n)
- return n.odd? ? (n * 3 + 1) / 2 : n / 2
- end
- def lenx(ns, p)
- l = ns.split(p)
- l = [] if (l.nil?)
- l.shift if (l[0] == '')
- return l.map { |x| x.length }
- end
- def len01x(ns)
- return lenx(ns, /0+/), lenx(ns, /1+/)
- end
- def mx01x(ns)
- l1, l0 = len01x(ns)
- return (l1 + l0).max
- end
- def count(ns, l2 = [])
- n = n1 = ns.to_i(2)
- l = [n1]
- while (n != 1 && n >= n1)
- n = f2(n)
- l << n
- end
- cg = l.size
- cm = (0...l.size).max_by { |x| l[x] }
- l1 = l[ns.length..-1]
- mx01r = (l1.nil? || l1.empty?) ? 0 : l1.map { |x| mx01x(x.to_s(2)) }.max
- nl = ns.length
- return {'ns' => ns,
- 'cm' => cm,
- 'cg' => l.size,
- 'cr' => l.size - cm,
- 'nl' => nl,
- 'mx01r' => mx01r
- }
- end
- def initd(w, m)
- d = m.to_f / w
- w2 = w - 1
- a = (0...w2).to_a
- s = '0' * w2
- (1..(d * w - 1)).map { a.delete_at(rand(a.size)) }.each { |x| s[x, 1] = '1' }
- return ('1' + s)
- end
- def initb(w, m)
- r = m.to_f / w
- return '1' + (1...w).map { rand < r ? '0' : '1' }.join
- end
- def initw(w, m)
- s = initd(w, w / 2)
- i = rand(w - m) + 1
- m = [w - i, m].max
- s[i, m] = rand(2).to_s * m
- return s
- end
- def mut(ns)
- ns = ns.dup
- i = rand(ns.length - 1) + 1
- ns[i, 1] = (ns[i, 1].to_i ^ 1).to_s
- return ns
- end
- def inner(ns1, ns2)
- a, b = [ns1, ns2].sort_by { |x| x.length }
- d = b.length - a.length
- i = rand(d + 1)
- c = b.dup
- c[i, a.length] = a
- ns1.replace(b)
- ns2.replace(c)
- end
- def mix(ns1, ns2)
- ns1 = ns1.dup
- ns2 = ns2.dup
- inner(ns1, ns2)
- return (0...ns1.length).map { |x| [ns1, ns2][rand(2)][x, 1] }.join
- end
- def cut(ns1, ns2)
- ns1 = ns1.dup
- ns2 = ns2.dup
- inner(ns1, ns2)
- i = rand(ns1.length)
- return ns1[0...i] + ns2[i..-1]
- end
- def ext(ns)
- ns = ns.dup
- (rand(3) + 1).times { ns[rand(ns.length) + 1, 0] = rand(2).to_s }
- return ns
- end
- def short(ns)
- return ns if (ns.length == 1)
- ns = ns.dup
- (rand([ns.length - 1, 3].min) + 1).times { ns[rand(ns.length - 1) + 1, 1] = '' }
- return ns
- end
- def rank(x)
- return -x['z']
- end
- def adj(x, wt, km)
- z = 0
- km.keys.each { |k| z += (x[k] - wt["#{k}_a"]) / wt["#{k}_sd"] * km[k] }
- x['z'] = z
- raise if (!z.finite?)
- return x
- end
- def out(a, d, a2 = {}, t = nil)
- fn = 'out.txt'
- k = a.keys
- if ($f1.nil?) then
- $f1 = File.open(fn, 'w')
- $f1.puts(k.join("\t"))
- f2 = File.open('gnuplot.cmd', 'w')
- st = t.nil? ? 'unset title; ' : "set title '#{t}'; "
- f2.puts("set ytics nomirror; set y2tics; set colors classic; set key top left box opaque; #{st}; plot \\")
- (a.keys - ['t']).each \
- {
- |x|
- f2.puts("'#{fn}' using (column('t')):(column('#{x}')) every #{d} with line title '#{x}' #{a2[x]}, \\")
- }
- f2.puts
- f2.close
- end
- $f1.puts(a.values_at(*k).join("\t"))
- $f1.flush
- end
- def remove(a, ks)
- a = a.dup
- ks.each { |x| a.delete(x) }
- return a
- end
- def add(bs, km, h, ns, fn, wt, t, d)
- j = ns.length
- h[j] = [] if (!h.member?(j))
- x = adj(count(ns), wt, km)
- a, b = [h[j][0], h[j][-1]]
- return if (h[j].map { |x| x['ns'] }.member?(x['ns']))
- x['t'] = t
- h[j] << x
- h[j].sort_by! { |x| rank(x) }
- h[j][bs..-1] = [] if (h[j].size > bs)
- out(remove(x, ['ns']), d, {'z' => 'axis x1y2'})
- end
- def top(h1)
- return h1[rand([h1.size / 4, h1.size].max)]
- end
- def stat(l)
- return 0, 1.0 if (l.empty?)
- t = l.inject { |a, x| a + x }
- t2 = l.inject { |a, x| a + x ** 2 }
- c = l.size
- a = t.to_f / c
- z = t2.to_f / c - a ** 2
- sd = Math.sqrt(z < 0 ? 0 : z)
- raise if (sd.nan?)
- return a, sd
- end
- def dist(km, h, wt)
- l = h.values.flatten
- km.keys.each \
- {
- |k|
- a, sd = stat(l.map { |x| x[k] })
- sd = 1.0 if (sd == 0)
- wt.merge!({"#{k}_a" => a, "#{k}_sd" => sd})
- }
- end
- def nonnil(x, y)
- return x.nil? ? y : x
- end
- def opt(km, w1, k, fn)
- h = {}
- ops = ['initd0', 'initb0', 'initw0', 'mut1', 'mix2', 'cut2']
- # ops += ['ext1', 'short1']
- bs = 50
- bc = 50
- t = 0
- n = 1e4.to_i
- d = n / 2000
- wt = {}
- n.times \
- {
- if (t % 100 == 0) then
- dist(km, h, wt)
- h.values.flatten.each { |x| adj(x, wt, km) }
- end
- opc = ops[rand(ops.size)]
- c = opc[-1..-1].to_i
- op = opc[0..-2]
- ks = h.keys.sort_by { |x| rank(h[x][0]) }
- ks = ks[0...[ks.size, ks.size / 4].max]
- case (c)
- when 0
- w = ks.empty? ? w1 : ks[rand(ks.size)]
- ns = send(op, w, rand(w))
- when 1, 2
- redo if (h.empty?)
- h.delete(ks.pop) if (ks.size > bc)
- arg = (0...c).map { ks[rand(ks.size)] }
- l = arg.map { |x| top(h[x])['ns'] }
- ns = send(op, *l)
- ns[0, 1] = '1'
- end
- if (ns.length != w1) then
- p([op, c])
- p(ns.length)
- exit
- end
- add(bs, km, h, ns, fn, wt, t, d)
- if (t % 100 == 0) then
- kmx = nonnil(h.values.flatten.max_by { |x| x[k] }, {}).dup
- h0 = nonnil(h.fetch(ks[0], [])[0], {}).dup
- msg = Hash[[['t', 'hmn', 'hmx', 'hc', 'h_0', "#{k}_0"], [t, ks.min, ks.max, h.size, h0, kmx]].transpose]
- msg['h_0'].delete('ns')
- msg["#{k}_0"].delete('ns')
- p(msg)
- # p(wt)
- end
- t += 1
- }
- end
- f = File.open('gnuplot2.cmd', 'w')
- f.puts("set title 'mx01r'; unset y2tics; set key top left; plot \\")
- ks = ['cg', 'cr', 'cm']
- ks.each \
- {
- |x|
- f.puts("'out.txt' using (column('#{x}')):(column('mx01r')) pt 5 ps 0.2,\\")
- }
- f.puts
- f.puts('pause -1')
- f.puts("set title 'mx01r log log'; unset y2tics; set key top right; plot \\")
- ks.each \
- {
- |x|
- f.puts("'out.txt' using (log(column('#{x}'))):(log(column('mx01r'))) pt 5 ps 0.2,\\")
- }
- f.close
- v = {'mx01r' => 1, 'cm' => 1, 'cg' => 1, 'cr' => 1}
- opt(v, 100, 'mx01r', fn = 'mixdb.txt')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement