Skip to content

Instantly share code, notes, and snippets.

@happyrobots
Created February 19, 2012 07:50
Show Gist options
  • Save happyrobots/1862508 to your computer and use it in GitHub Desktop.
Save happyrobots/1862508 to your computer and use it in GitHub Desktop.
#define SuperRandom (arc4random() % ((unsigned)RAND_MAX + 1))
float objectiveFunction(NSArray *vector) {
float result = 0.0;
for (id element in vector) {
result += [element floatValue];
}
return result;
}
float randomVariable(NSArray *minmax) {
float min = [[minmax objectAtIndex:0] floatValue];
float max = [[minmax objectAtIndex:1] floatValue];
return min + ((max - min) * SuperRandom);
}
// ngga bisa assign default argument value di objective c
float randomGaussian(float mean, float stdev) {
float u1 = 0, u2 = 0, u3 = 0;
do {
u1 = 2 * SuperRandom() - 1;
u2 = 2 * SuperRandom() - 1;
s = u1*u1 + u2*u2;
} while (w >= 1);
w = sqrt((-2.0 * log(w)) / w);
return mean + (u2*w) * stdev;
}
NSDictionary* generateSample(NSArray *searchSpace, NSArray *means, NSArray *stdevs) {
NSMutableArray *vector = [NSMutableArray array];
for (int i = 0; i < searchSpace.count; ++i) {
float element = randomGaussian([[means objectAtIndex:i] floatValue], [[stdevs objectAtIndex:i] floatValue];
float searchSpace0 = [[[searchSpace objectAtIndex:i] objectAtIndex:0] floatValue];
float searchSpace1 = [[[searchSpace objectAtIndex:i] objectAtIndex:1] floatValue];
if (element < searchSpace0) {
element = searchSpace0;
}
if (element > searchSpace1) {
element = searchSpace1;
}
[vector addObject:[NSNumber numberWithFloat:element]];
}
return [NSDictionary dictionaryWithObjectsAndKeys:vector, @"vector"];
}
float meanAttr(NSArray *samples, int i) {
float sum = 0.0;
for (NSDictionary *sample in samples) {
sum += [[sample objectForKey:@"vector"] objectAtIndex:i];
}
return sum / (float)samples.count;
}
float stdevAttr(NSArray *samples, float mean, int i) {
float sum = 0.0;
for (NSDictionary *sample in samples) {
float squared = [[sample objectForKey:@"vector"] objectAtIndex:i];
squared *= squared;
sum += squared;
}
return sum / (float)samples.count;
}
void updateDistribution(NSArray *samples, float alpha, NSMutableArray *means, NSMutableArray *stdevs) {
for (int i = 0; i < means.count; ++i) {
[means replaceObjectAtIndex:i withObject:[NSNumber numberWithFloat:
(alpha* [[means objectAtIndex:i] floatValue] + ((1.0-alpha)*meanAttr(samples, i)))]];
[stdevs replaceObjectAtIndex:i withObject:[NSNumber numberWithFloat:
(alpha* [[stdevs objectAtIndex:i] floatValue] + ((1.0-alpha)*stdevAttr(samples, [[means objectAtIndex:i] floatValue], i)))]];
}
}
NSDictionary *search(NSArray *bounds, int maxIter, int numSamples, int numUpdate, float learningRate) {
NSMutableArray *means = [NSMutableArray array];
NSMutableArray *stdevs = [NSMutableArray array];
for (int i = 0; i < bounds.count; ++i) {
[means addObject:[NSNumber numberWithFloat:randomVariable([bounds objectAtIndex:i])]];
[stdevs addObject:[NSNumber numberWithFloat:[[[bounds objectAtIndex:i] objectAtIndex:1] floatValue]-[[[bounds objectAtIndex:i] objectAtIndex:1] floatValue]]];
}
NSDictionary *best = nil;
for (int i = 0; i < maxIter; ++i) {
NSMutableArray *samples = [NSMutableArray array];
for (int j = 0; j < numSamples; ++j) {
NSMutableDictionary *s = [generateSample(bounds, means, stdevs) mutableCopy];
[s setObject:[NSNumber numberWithFloat:objectiveFunction([s objectForKey:@"vector"])] forKey:@"cost"];
[samples addObject:s];
}
// sort sampe berdasarkan cost
if (!best || [[samples objectAtIndex:0] objectForKey:@"cost"] < [best objectForKey:@"cost"]) {
best = [samples objectAtIndex:0];
}
// etc...
}
return best;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment