math - Translate binary string to mathematical expression -
i've been experimenting genetic algorithms of late , i'd build mathematical expressions out of genomes (for easy talk, find expression matches outcome).
i have genomes consisting of genes represented bytes, 1 genome can this: {12, 127, 82, 35, 95, 223, 85, 4, 213, 228}. length predefined (although must fall in range), neither form takes. is, entry can take byte value.
now trick translate mathematical expressions. it's easy determine basic expressions, example: pick first 2 values , treat them products, pick 3rd value , pick operator ( +, -, *, /, ^ , mod ), pick 4th value product , pick 5th value operator again working on result of 3rd operator on first 2 products. (or handle postfix expression)
the complexity rises when start allowing priority rules. when example entry under index 2 represents '(', bound have ')' somewhere further on except entry 3, not entry 4
of course same goes many things, can't end operator @ end, can't end loose number etc.
now can make huge switch statement (for example) taking in possible possibilities make code unreadable. hoping if out there knows strategy of how take 1 on.
thanks in advance!
** edit **
on request: goal i'm trying achieve make application can resolve function set of numbers. example i've given in comment below: {4, 11, 30} , might come function (x ^ 3) + x
belisarius in comment gave link identical topic: algorithm permutations of operators , operands
my code:
private static double resolveexpression(byte[] genes, double valueforx) { // folowing: https://stackoverflow.com/questions/3947937/algorithm-for-permutations-of-operators-and-operands/3948113#3948113 stack<double> operandstack = new stack<double>(); (int index = 0; index < genes.length; index++) { int genesleft = genes.length - index; byte gene = genes[index]; bool createoperand; // when there enough possbile operators left, possibly add operands if (genesleft > operandstack.count) { // when there @ least 2 operands on stack if (operandstack.count >= 2) { // randomly determine wether create operand threating below 127 operand , rest operator (better / 2 due 0 values) createoperand = gene < byte.maxvalue / 2; } else { // else need operand sure since operator illigal createoperand = true; } } else { // false sure since there 2 many operands complete otherwise createoperand = false; } if (createoperand) { operandstack.push(genetooperand(gene, valueforx)); } else { double left = operandstack.pop(); double right = operandstack.pop(); double result = performoperator(gene, left, right); operandstack.push(result); } } // should 1 operand left on stack ending result return operandstack.pop(); } private static double performoperator(byte gene, double left, double right) { // there 5 options supported, namely: +, -, *, /, ^ , log (math) int code = gene % 6; switch (code) { case 0: return left + right; case 1: return left - right; case 2: return left * right; case 3: return left / right; case 4: return math.pow(left, right); case 5: return math.log(left, right); default: throw new invalidoperationexception("impossible state"); } } private static double genetooperand(byte gene, double valueforx) { // support numbers 0 - 9 , x int code = gene % 11; // value between 0 , 10 if (code == 10) { // 10 placeholder x return valueforx; } else { return code; } } #endregion // helpers }
Comments
Post a Comment