Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I don't understand the Ruby reference relationship of arrays variables (best and vector) with the return of the functions (fitness or bitstring for example).
Concidere this case:
best[:fitness]
At where best is array and fitness is a function, what will be required of the variable ? and what will be referenced by the function ?
See the complete code:
def objective_function(vector)
return vector.inject(0.0) {|sum, x| sum + (x ** 2.0)}
end
def random_bitstring(num_bits)
return (0...num_bits).inject(""){|s,i| s<<((rand<0.5) ? "1" : "0")}
end
def decode(bitstring, search_space, bits_per_param)
vector = []
search_space.each_with_index do |bounds, i|
off, sum = i*bits_per_param, 0.0
param = bitstring[off...(off+bits_per_param)].reverse
param.size.times do |j|
sum += ((param[j].chr=='1') ? 1.0 : 0.0) * (2.0 ** j.to_f)
end
min, max = bounds
vector << min + ((max-min)/((2.0**bits_per_param.to_f)-1.0)) * sum
end
return vector
end
def fitness(candidate, search_space, param_bits)
candidate[:vector]=decode(candidate[:bitstring], search_space, param_bits)
candidate[:fitness] = objective_function(candidate[:vector])
end
def binary_tournament(pop)
i, j = rand(pop.size), rand(pop.size)
j = rand(pop.size) while j==i
return (pop[i][:fitness] < pop[j][:fitness]) ? pop[i] : pop[j]
end
def point_mutation(bitstring, rate=1.0/bitstring.size)
child = ""
bitstring.size.times do |i|
bit = bitstring[i].chr
child << ((rand()<rate) ? ((bit=='1') ? "0" : "1") : bit)
end
return child
end
def crossover(parent1, parent2, rate)
return ""+parent1 if rand()>=rate
child = ""
parent1.size.times do |i|
child << ((rand()<0.5) ? parent1[i].chr : parent2[i].chr)
end
return child
end
def reproduce(selected, pop_size, p_cross, p_mut)
children = []
selected.each_with_index do |p1, i|
p2 = (i.modulo(2)==0) ? selected[i+1] : selected[i-1]
p2 = selected[0] if i == selected.size-1
child = {}
child[:bitstring] = crossover(p1[:bitstring], p2[:bitstring], p_cross)
child[:bitstring] = point_mutation(child[:bitstring], p_mut)
children << child
break if children.size >= pop_size
end
return children
end
def bitclimber(child, search_space, p_mut, max_local_gens, bits_per_param)
current = child
max_local_gens.times do
candidate = {}
candidate[:bitstring] = point_mutation(current[:bitstring], p_mut)
fitness(candidate, search_space, bits_per_param)
current = candidate if candidate[:fitness] <= current[:fitness]
end
return current
end
def search(max_gens, search_space, pop_size, p_cross, p_mut, max_local_gens, p_local, bits_per_param=16)
pop = Array.new(pop_size) do |i| {:bitstring=>random_bitstring(search_space.size*bits_per_param)}
end
pop.each{|candidate| fitness(candidate, search_space, bits_per_param) }
gen, best = 0, pop.sort{|x,y| x[:fitness] <=> y[:fitness]}.first
max_gens.times do |gen|
selected = Array.new(pop_size){|i| binary_tournament(pop)}
children = reproduce(selected, pop_size, p_cross, p_mut)
children.each{|cand| fitness(cand, search_space, bits_per_param)}
pop = []
children.each do |child|
if rand() < p_local
child = bitclimber(child, search_space, p_mut, max_local_gens, bits_per_param)
end
pop << child
end
pop.sort!{|x,y| x[:fitness] <=> y[:fitness]}
best = pop.first if pop.first[:fitness] <= best[:fitness]
puts ">gen=#{gen}, f=#{best[:fitness]}, b=#{best[:bitstring]}"
end
return best
end
if __FILE__ == $0
# problem configuration
problem_size = 3
search_space = Array.new(problem_size) {|i| [-5, +5]}
# algorithm configuration
max_gens = 100
pop_size = 100
p_cross = 0.98
p_mut = 1.0/(problem_size*16).to_f
max_local_gens = 20
p_local = 0.5
# execute the algorithm
best = search(max_gens, search_space, pop_size, p_cross, p_mut, max_local_gens, p_local)
puts "done! Solution: f=#{best[:fitness]}, b=#{best[:bitstring]}, v=#{best[:vector].inspect}"
end
ps: This code is an implementation of a Memetic Algorithms , which in turn is a variation of an Evolutionary Algorithm.
A Memetic Altorithms technically search the best solution to a problem in a number of solutions from an integrated global search results to an optimization every cycle / generation that selects variations of a good solution from a local search results.
My goal is to translate the code to Matlab programming.
Related
Climbing the Leaderboard. Terminated due to timeout :(
A HackerRank challenge of algorithm category.
My approach: To reduce the overhead when large arrays as input, I used map() and a Binar search function with it. No luck. I got 7/11 test cases passed. Can I ask for some help to improve my code. The code below is my solution so far. I need help to improve it.
Problem description
class Score_board:
def climbingLeaderboard(self, scores, alice):
self.boardScores = sorted(set(scores), reverse=True)
alice_rank = list(map(self.rankBoard,alice))
return alice_rank
def rankBoard(self, current):
score_bank = self.boardScores
midIndex = len(score_bank)//2
while midIndex > 0:
if current in score_bank:
return(self.boardScores.index(current)+1)
elif current < score_bank[midIndex]:
score_bank = score_bank[midIndex:]
midIndex = len(score_bank)//2
elif current > score_bank[midIndex]:
score_bank = score_bank[:midIndex]
midIndex = len(score_bank)//2
else:
boardIndex = self.boardScores.index(score_bank[0])
if current in score_bank:
return(self.boardScores.index(current)+1)
elif current > score_bank[0] and boardIndex == 0:
return(1)
elif current < score_bank[0] and boardIndex == (len(self.boardScores)-1):
return(boardIndex + 2)
elif current > score_bank[0]:
return(boardIndex)
elif current < score_bank[0]:
return(boardIndex + 2)
if __name__ == '__main__':
scores_count = int(input())
scores = list(map(int, input().rstrip().split()))
alice_count = int(input())
alice = list(map(int, input().rstrip().split()))
coord = Score_board()
result = coord.climbingLeaderboard(scores, alice)
print('\n'.join(map(str, result)))
print('\n')
I have several classes with a lot of methods and functions, which normally handles mx1 arrays. For a given class:
S1.x=randn(m,1);
S1+2*randn(m,1); % Plus Override
S1.smooth; % Class Methods
S1.detrend;
Now i wish to handle class arrays for the same given class, on a way like this;
S=[S1 S2 S3 S4];
S.smooth; % Methods for Class Array
S.detrend;
Question:
Is there a simple way for doing this, without rewritting all the functions implementing the class properties and methods?
I am looking for some specific addition, redefinition, piece of code, trick, etc. in order to do that in a clean way. The purpose of this is code functionality, not performance -the few performance critical functions are already vectorized-.
Greetings,
How about that:
classdef TestClass
methods
function smooth(obj)
if numel(obj) == 1
disp('Hello')
else
for i=1:numel(obj)
obj(i).smooth;
end
end
end
end
end
Called as follow:
>> t1 = TestClass;
>> t1.smooth
Hello
>> t2 = [TestClass TestClass TestClass];
>> t2.smooth
Hello
Hello
Hello
If you really wanted to you should also be able to overload the subsref operator to automatically do that on all your methods (it gives you access to the . operator) . However in my experience overloading subsref correctly is not straight forward and might be more effort than what is worth.
Here is an example of this idea. It's simplistic and you will likely will need further refinement on your part but should get you started. Note the cheer amount of hackery :)
classdef TestClass
properties
Value
end
methods
function obj = TestClass(x)
obj.Value = x;
end
function smooth(obj)
fprintf('I am %d\n', obj.Value)
end
function res = opposite(obj)
res = -obj.Value;
end
function [res1,res2,res3] = test(obj)
res1 = obj.Value;
res2 = res1*res1;
res3 = res2*res1;
end
function varargout = subsref(A,S)
if numel(A) > 1 && strcmp(S(1).type, '.')
if nargout == 0
feval(S.subs, A(1));
else
nout = nargout(['TestClass>TestClass.' S.subs]);
if nout < 0
nout = -nout;
end
if nout == 0
arrayfun(#(x)feval(S.subs, x), A);
varargout = cell(1, nargout);
else
for i=1:nargout
[output{1:nout}] = feval(S.subs, A(i));
varargout{i} = output;
output = {};
end
end
end
else
if nargout == 0
builtin('subsref', A, S);
else
varargout{:} = builtin('subsref', A, S);
end
end
end
end
Example of use:
>> t1 = TestClass(5);
>> t1.smooth;
I am 5
>> t2 = [TestClass(1) TestClass(2) TestClass(3)];
>> t2(2).smooth;
I am 2
>> t2.smooth;
I am 1
I am 2
I am 3
>> t2(1:2).smooth
I am 1
I am 2
>> t2(2:3).smooth
I am 2
I am 3
>> t2([1 3]).smooth
I am 1
I am 3
>> t2.test
ans =
[1] [1] [1]
ans =
[2] [4] [8]
ans =
[3] [9] [27]
I am setting up an optimization in OpenMDAO v0.13 using several components that are used many times. My assembly seems to be working just fine with the default driver, but when I run with an optimizer it does not solve. The optimizer simply runs with the inputs given and returns the answer using those inputs. I am not sure what the issue is, but I would appreciate any insights. I have included a simple code mimicking my structure that reproduces the error. I think the problem is in the connections, summer.fs does not update after initialization.
from openmdao.main.api import Assembly, Component
from openmdao.lib.datatypes.api import Float, Array, List
from openmdao.lib.drivers.api import DOEdriver, SLSQPdriver, COBYLAdriver, CaseIteratorDriver
from pyopt_driver.pyopt_driver import pyOptDriver
import numpy as np
class component1(Component):
x = Float(iotype='in')
y = Float(iotype='in')
term1 = Float(iotype='out')
a = Float(iotype='in', default_value=1)
def execute(self):
x = self.x
a = self.a
term1 = a*x**2
self.term1 = term1
print "In comp1", self.name, self.a, self.x, self.term1
def list_deriv_vars(self):
return ('x',), ('term1',)
def provideJ(self):
x = self.x
a = self.a
dterm1_dx = 2.*a*x
J = np.array([[dterm1_dx]])
print 'In comp1, J = %s' % J
return J
class component2(Component):
x = Float(iotype='in')
y = Float(iotype='in')
term1 = Float(iotype='in')
f = Float(iotype='out')
def execute(self):
y = self.y
x = self.x
term1 = self.term1
f = term1 + x + y**2
self.f = f
print "In comp2", self.name, self.x, self.y, self.term1, self.f
class summer(Component):
total = Float(iotype='out', desc='sum of all f values')
def __init__(self, size):
super(summer, self).__init__()
self.size = size
self.add('fs', Array(np.ones(size), iotype='in', desc='f values from all cases'))
def execute(self):
self.total = sum(self.fs)
print 'In summer, fs = %s and total = %s' % (self.fs, self.total)
class assembly(Assembly):
x = Float(iotype='in')
y = Float(iotype='in')
total = Float(iotype='out')
def __init__(self, size):
super(assembly, self).__init__()
self.size = size
self.add('a_vals', Array(np.zeros(size), iotype='in', dtype='float'))
self.add('fs', Array(np.zeros(size), iotype='out', dtype='float'))
print 'in init a_vals = %s' % self.a_vals
def configure(self):
# self.add('driver', SLSQPdriver())
self.add('driver', pyOptDriver())
self.driver.optimizer = 'SNOPT'
# self.driver.pyopt_diff = True
#create this first, so we can connect to it
self.add('summer', summer(size=len(self.a_vals)))
self.connect('summer.total', 'total')
print 'in configure a_vals = %s' % self.a_vals
# create instances of components
for i in range(0, self.size):
c1 = self.add('comp1_%d'%i, component1())
c1.missing_deriv_policy = 'assume_zero'
c2 = self.add('comp2_%d'%i, component2())
self.connect('a_vals[%d]' % i, 'comp1_%d.a' % i)
self.connect('x', ['comp1_%d.x'%i, 'comp2_%d.x'%i])
self.connect('y', ['comp1_%d.y'%i, 'comp2_%d.y'%i])
self.connect('comp1_%d.term1'%i, 'comp2_%d.term1'%i)
self.connect('comp2_%d.f'%i, 'summer.fs[%d]'%i)
self.driver.workflow.add(['comp1_%d'%i, 'comp2_%d'%i])
self.connect('summer.fs[:]', 'fs[:]')
self.driver.workflow.add(['summer'])
# set up main driver (optimizer)
self.driver.iprint = 1
self.driver.maxiter = 100
self.driver.accuracy = 1.0e-6
self.driver.add_parameter('x', low=-5., high=5.)
self.driver.add_parameter('y', low=-5., high=5.)
self.driver.add_objective('summer.total')
if __name__ == "__main__":
""" the result should be -1 at (x, y) = (-0.5, 0) """
import time
from openmdao.main.api import set_as_top
a_vals = np.array([1., 1., 1., 1.])
test = set_as_top(assembly(size=len(a_vals)))
test.a_vals = a_vals
print test.a_vals
test.x = 2.
test.y = 2.
tt = time.time()
test.run()
print "Elapsed time: ", time.time()-tt, "seconds"
print 'result = ', test.summer.total
print '(x, y) = (%s, %s)' % (test.x, test.y)
print test.fs
I played around with your model, and found that the following line caused problems:
#self.connect('summer.fs[:]', 'fs[:]')
When I commented it out, I got the optimization to move.
I am not sure what is happening there, but the graph transformations sometimes have some issues with component input nodes that are promoted as outputs on the assembly boundary. If you still want those values to be available on the assembly, you could try promoting the outputs from the comp2_n components instead.
I'm looking for a Gremlin version of a customizable PageRank algorithm. There are a few old versions out there, one (from: http://www.infoq.com/articles/graph-nosql-neo4j) is pasted below. I'm having trouble fitting the flow into the current GremlinGroovyPipeline-based structure. What is the modernized equivalent of this or something like it?
$_g := tg:open()
g:load('data/graph-example-2.xml')
$m := g:map()
$_ := g:key('type', 'song')[g:rand-nat()]
repeat 2500
$_ := ./outE[#label='followed_by'][g:rand-nat()]/inV
if count($_) > 0
g:op-value('+',$m,$_[1]/#name, 1.0)
end
if g:rand-real() > 0.85 or count($_) = 0
$_ := g:key('type', 'song')[g:rand-nat()]
end
end
g:sort($m,'value',true())
Another version is available on slide 55 of http://www.slideshare.net/slidarko/gremlin-a-graphbased-programming-language-3876581. The ability to use the if statements and change the traversal based on them is valuable for customization.
many thanks
I guess I'll answer it myself in case somebody else needs it. Be warned that this is not a very efficient PageRank calculation. It should only be viewed as a learning example.
g = new TinkerGraph()
g.loadGraphML('graph-example-2.xml')
m = [:]
g.V('type','song').sideEffect{m[it.name] = 0}
// pick a random song node that has 'followed_by' edge
def randnode(g) {
return(g.V('type','song').filter{it.outE('followed_by').hasNext()}.shuffle[0].next())
}
v = randnode(g)
for(i in 0..2500) {
v = v.outE('followed_by').shuffle[0].inV
v = v.hasNext()?v.next():null
if (v != null) {
m[v.name] += 1
}
if ((Math.random() > 0.85) || (v == null)) {
v = randnode(g)
}
}
msum = m.values().sum()
m.each{k,v -> m[k] = v / msum}
println "top 10 songs: (normalized PageRank)"
m.sort {-it.value }[0..10]
Here's a good reference for a simplified one-liner:
https://groups.google.com/forum/m/#!msg/gremlin-users/CRIlDpmBT7g/-tRgszCTOKwJ
(as well as the Gremlin wiki: https://github.com/tinkerpop/gremlin/wiki)
I have an array:
step1 = [0,0;
0,1;
1,1;
2,3;
3,4;
3,5;
3,6;
3,7;
4,7;
5,7;
6,7;
6,6;
6,5;
6,4;
6,3;
6,2;
5,1];
I want to step through this array and create new arrays for the row and column that increment by 0.1 from one row to another. This is what I did:
z=1;
u=length(step1);
step_b4X = zeros(u,1);
step_b4Y = zeros(u,1);
while z <= length(step1)
step_b4X = step_presentX;
step_presentX(z,1) = step1(z,1);
step_b4Y = step_presentX;
step_presentY(z,1) = step1(z,2);
pathX = step_b4X:0.1:step_presentX;
pathY = step_b4Y:0.1:step_presentY;
z = z+1;
end
I get zeros.
I want pathX = 0:0.1:0....pathY = 0:0.1:1
next pathX = 0:0.1:1....pathY = 1:0.1:1... and so on
If you do
start:increment:end
where start == end, you'll get a scalar equal to start (which is logical).
If you want pathX and pathY to have the same length at each iteration, you'll have to do this:
z = 1;
while z <= length(step1)
currentX = step(z,1); nextX = step(z+1,1);
currentY = step(z,2); nextY = step(z+1,2);
pathX = currentX : 0.1 : nextX;
pathY = currentY : 0.1 : nextY;
if numel(pathX) == 1
pathX = repmat(pathX, numel(pathY),1); end
if numel(pathY) == 1
pathY = repmat(pathY, numel(pathX),1); end
z = z+1;
end
Now you'll have the right arrays at each iteration, that you'll use directly or save in a cell-array for later. If you want everything in one big array, add this to the end of the loop:
pathX_final = [pathX_final; pathX];
pathY_final = [pathY_final; pathY];
and initialize them as empty before the loop, of course.
Alternatively (much cleaner and possibly a bit faster), ditch the whole loop and use interp1:
x = step1(:,1);
y = step1(:,2);
xx = interp1(1:numel(x), x, 1:0.1:numel(x));
yy = interp1(1:numel(y), y, 1:0.1:numel(y));