Fitness Function - What to do, if value of one Chromosome features is much higher than other ones - scalability

I am trying to write a Fitness Function for my Genetic Algorithm. I have got three features (F1,F2,F3 - All are numeric variables), which are taken into consideration for rating the chromosome. If all of them are equally important I can write such equation:
If their importance would be different, I can multiply features by different constants.
It will all work, if values of all three features would have the same interval.
But what if F1 and F2 could have a value from (0,10) and F3 for example(0,49)?
How could I approximately scale it? Or should I approach it differently?

Scale all your values to [0..1]
Assign a weight / importance to every value
Multiply every scaled value with its weight
Divide the sum of all values from step 3 by the sum of all weights
I don't know which language you are using, so here is some C# code:
Feature Class
public class Feature
{
public double Importance { get; set; }
public double Value { get; set; }
public double LowValue { get; set; }
public double HighValue { get; set; }
public double ScaledValue
{
get
{
// Make sure value is within bounds
double intermediate = Math.Max(Math.Min(LowValue, HighValue),
Math.Min(Math.Max(LowValue, HighValue), Value));
// Scale from 0 to 1 within defined bounds
double scaledValue = (intermediate - LowValue)/(HighValue - LowValue);
return scaledValue;
}
}
}
Example Calculation
// low importance (1), values from [20..-10] (less is better)
var f1 = new Feature
{
Importance = 1,
Value = 0,
LowValue = 20,
HighValue = -10
};
// low importance (1), values from [0..10] (more is better)
var f2 = new Feature
{
Importance = 1,
Value = 1,
LowValue = 0,
HighValue = 10
};
// high importance (5), values from [0..49]
var f3 = new Feature
{
Importance = 5,
Value = 25,
LowValue = 0,
HighValue = 49
};
var features = new[] {f1, f2, f3};
var score = features.Sum(f => f.ScaledValue*f.Importance)/features.Sum(f => f.Importance);
Debug.WriteLine(score);

Related

Get closest value in array to variable value

I have an array of int I'd like to create a function which retrieves from this array the closest value to randomInt
final myArray = [10 , 20, 14, 15, 18, 24];
final int randomInt = 21;
getClosestValueInArray(myArray, randomInt); // should return 20
int getClosestValueInArray(List<int> array, int value) {
}
You could loop through the array and check closeness for each element. E.g. in pseudo-code:
closest = myArray[0]
best_closeness = abs(myArray[0] - randomInt)
for (element in myArray) {
closeness = abs(element - randomInt)
if (closeness < best_closeness) {
closest = element
best_closeness = closeness
}
}
return closest
And in Dart (added by #julemand101)
int getClosestValueInArray(List<int> array, int value) {
int closest = array.first;
int best_closeness = (closest - value).abs();
for (int element in array.skip(1)) {
int closeness = (element - value).abs();
if (closeness < best_closeness) {
closest = element;
best_closeness = closeness;
}
}
return closest;
}
One option is to put these elements in a TreeSet and then use ts.floor(randomInt) and ts.ceil(randomInt) to check what the nearest elements to randomInt is, and pick the one with the smallest absolute difference to randomInt.
Another option is to put these values in a hashset and then search for randomInt - 1, randomInt + 1, randomInt - 2 and so on. This again has benefits and drawbacks compared to the previous approach.
There are many other ways.

Cannot assign value of type 'Int' to type 'Range<Int>' and Binary operator '*' cannot be applied to operands of type '_' and 'Float'

I got this error. Also, function range could not do this multiplication and division by g for some values that I ranged.How can i could fix this problem?
class ballShooter {
var ballShooter : Int = 0
var teta = 0 ..< 90
var v = 0 ..< 100
var g = 10
init(ballShooter:Int,teta:Int,v:Int,g:Int) {
self.ballShooter = ballShooter
self.teta = teta
self.v = v
self.g = g
}
func range(r: Int)->Int {
let r = v * v * sin(2 * teta) / g
return r
}
}
When you declare var teta = 0 ..< 90 you are telling the compiler that the variable teta (theta?) contains a half-open Int range from 0 to less than 90. Thus, your initializer needs to take a value of type Range of Int for the teta parameter.
Do you really want teta and v to contain ranges? Or are you trying to set limits to the values that callers can assign to those variables?
Edit:
If your goal is to set limits on the legal range of values for a variable, you have to implement that for yourself. Here is some sample code illustrating how you might do that:
class Foo {
// This determines the legal range of values for aVal.
public var validValRange = 50...200
public var aVal: Int {
set {
// Make sure the value is in range before updating the internal var
if validValRange ~= newValue {
_aVal = newValue
}
}
get {
// Return the previously validated value.
return _aVal
}
}
// This is a private variable that stores validated values for aVal
private var _aVal: Int = 0
}
You could test it with code like this:
let aFoo = Foo()
aFoo.aVal = 52
aFoo.aVal = 500
print(aFoo.aVal)
That would print "52" since the value 500 is out of range.

How to convert numbers to letters

I have a sheet that shows Items Cost. What I want to do instead of showing numbers i want to use the following BLACKHORSE were B = 1, L = 2, A = 3,C=4,K=5,H=6,7=O,8=R,9=S and E=0. How do i put this in a script in Google Sheets to where say cell h9 the sum of the total cost of the items it puts the letters instead of numbers
There may be many ways to calculate the values that you want. Consider this as one approach.
function so5715442701() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetname = "57154427";
var sheet = ss.getSheetByName(sheetname);
// code to find the key for a given value in a javascript key:value array
Object.prototype.getKey = function(value){
for(var key in this){
if(this[key] == value){
return key;
}
}
return null;
};
// a key:value array for BLACKHORSE
var blackhorse = {
B : 1,
L : 2,
A : 3,
C : 4,
K : 5,
H : 6,
O : 7,
R : 8,
S : 9,
E : 0
};
// get the cost value from a cell
var costprice = sheet.getRange("C15").getValue();
// convert the number to a string
var cost = costprice.toString(); // convert to string
//Logger.log("DEBUG: cost = "+cost+", length = "+cost.length);
// set a variable to accumulate the results
var costtotal="";
// loop through the characters in the cost value
for (var i = 0; i < cost.length; i++) {
var letter = cost.charAt(i);
var costkey = blackhorse.getKey(letter);
var costtotal = costtotal+costkey
}
//Logger.log("DEBUG: cost = "+cost+", Blackhourse cost = "+costtotal);
sheet.getRange("D15").setValue(costtotal);
}
CREDIT
- How can I process each letter of text using Javascript?
- How to get a key in a JavaScript object by its value?

How to get price of Chart HLine objects and calculate Fibonacci levels

Three part question:
How to find 2 user created horizontal lines on a chart by name and return the price of each.
Then determine which HLine was crossed by the price most recently to determine trend direction.
Calculate Fibonacci levels based on prices and direction
double value = ObjectGetDouble(0,nameOfHLine,OBJPROP_PRICE1);
this is your value if you have name of the object, if you dont have it - need to loop over all objects:
string name;
for(int i=ObjectsTotal()-1;i>=0;i--){
name = ObjectName(i);
if(ObjectType(name)!=OBJ_HLINE) continue;
}
Working example of Fibonacci object that can be edited by the user and printing of fibonacci levels.
#include <ChartObjects/ChartObjectsFibo.mqh>
CChartObjectFibo *Fibo;
int OnInit()
{
Fibo = new CChartObjectFibo();
#Create object and set some defaults
if(!Fibo.Create(0,"Fibonacci",0,Time[5],Open[5],Time[0],Open[0]))
{
return(INIT_FAILED);
}
# Allow user to drag object
Fibo.Selectable(true);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
delete Fibo;
}
void OnTick()
{
string level_description;
double level_value;
string printString="Fibonacci Levels - ";
# Get the two anchor prices
double p1 = Fibo.GetDouble(OBJPROP_PRICE,0);
double p2 = Fibo.GetDouble(OBJPROP_PRICE,1);
# Calculate range
double range=MathAbs(p1-p2);
for(int i=0;i<Fibo.LevelsCount();i++)
{
level_description=Fibo.LevelDescription(i);
# Calculate price of level
level_value=(p2>p1)?p2-range*Fibo.LevelValue(i):p2+range*Fibo.LevelValue(i);
printString=StringFormat("%s %s:%.5f",printString,level_description,level_value);
}
Print(printString);
}
Difficult to understand exactly what you are after, not sure if you are trying to find the graphical objects or just calculate levels based on the prices. Assuming you have the price of the two horizontal lines, the following structure and function can be used to calculate Fibonacci levels. (price 1 is earlier in time than price 2).
Calculation based on formula found here
struct FibLevel {
double retrace38;
double retrace50;
double retrace61;
double extension61;
double extension100;
double extension138;
double extension161;
};
void FibLevel(double price1, double price2,FibLevel &fiblevel)
{
double range = MathAbs(price1-price2);
fiblevel.retrace38 =(price1<price2)?price2-range*0.382:price1+range*0.382;
fiblevel.retrace50 =(price1<price2)?price2-range*0.500:price1+range*0.500;
fiblevel.retrace61 =(price1<price2)?price2-range*0.618:price1+range*0.618;
fiblevel.extension61 =(price1<price2)?price2+range*0.618:price1-range*0.618;
fiblevel.extension100=(price1<price2)?price2+range :price1-range;
fiblevel.extension138=(price1<price2)?price2+range*1.382:price1-range*1.382;
fiblevel.extension161=(price1<price2)?price2+range*1.618:price1-range*1.618;
}

Ordered sequential text matching

I want to match the strings and get a score in the following manner,
string 1: 4556677, string 2: 2556677, score: 0
string 1: 123345873009, string 2: 123345873112, score: 9
string 1: 22334567, string 2: 22334500, score: 6
So the score represents common first n digits, from left to right.
I have a list of 100K string 1 and 30M string 2, I would like to filter down all the pairs (string 1 and 2) with a score greater than 'x'.
Is there an algorithm available to do this task instead of brutal force sequential matching? I have tables stored in apache hive/hbase and would like to implement the approach either in spark or java mapreduce. Any help is much appreciated.
I conclude that your "score" represents the leftmost character position at which the strings differed.
Never mind "mapreduce," plain-Jane Java can do this very easily.
**
public int score( String string1, String string2 ) {
char sbuf1[] = string1.toCharArray();
char sbuf2[] = string2.toCharArray();
int complen = sbuf1.length;
if( sbuf2.length < complen ) {
complen = sbuf2.length;
}
for(
int i = 0; i < complen; i++ ) {
if( sbuf1[ i ] !=
sbuf2[ i ] ) {
return
i;
}
}
return -1; //
indicates no mismatch detected before one string exhausted
}
**

Resources