示例#1
0
        private Func <decimal, decimal, decimal> GetOperation(EOperations operation)
        {
            switch (operation)
            {
            case EOperations.Add:
                return((left, right) => left + right);

            case EOperations.Divide:
                return((left, right) => left / right);

            case EOperations.Multiply:
                return((left, right) => left * right);

            case EOperations.Subtract:
                return((left, right) => left - right);
            }
            return(null);
        }
        private MathOperation GetOperation(EOperations operation)
        {
            switch (operation)
            {
            case EOperations.Add:
                return(delegate(decimal left, decimal right) { return left + right; });

            case EOperations.Divide:
                return(delegate(decimal left, decimal right) { return left / right; });

            case EOperations.Multiply:
                return(delegate(decimal left, decimal right) { return left * right; });

            case EOperations.Subtract:
                return(delegate(decimal left, decimal right) { return left - right; });
            }
            return(null);
        }
        /// <summary>
        ///  Evaluates an operation with two operands
        /// </summary>
        /// <param name="a"> The first operand</param>
        /// <param name="b"> The second operand</param>
        /// <param name="op"> The operation to perform</param>
        /// <returns></returns>
        private static float EvalBinaryOperation(float a, float b, EOperations op)
        {
            switch (op)
            {
            case EOperations.Addition: return(a + b);

            case EOperations.Subtraction: return(a - b);

            case EOperations.Multiplication: return(a * b);

            case EOperations.Division: return(a / b);

            case EOperations.Exponent: return((float)Math.Pow(a, b));

            default: Debug.LogError(String.Format("Unkown Operation requested in Math Parser: {0}", (char)op)); break;
            }

            return(int.MaxValue);
        }
示例#4
0
        private MathOperation GetOperation(EOperations operation)
        {
            switch (operation)
            {
            case EOperations.Add:
                return(Add);

            case EOperations.Divide:
                return(Divide);

            case EOperations.Multiply:
                return(Multiply);

            case EOperations.Subtract:
                return(Subtract);

            default:
                return(null);
            }
        }
        public IndividualRunResults(Individual tester, int result, int differenceFromTarget, HashSet<int> mutatedOperationIndexes)
        {
            this.tester = tester;
            this.result = result;
            this.differenceFromTarget = differenceFromTarget;
            this.mutatedOperationIndexes = mutatedOperationIndexes;

            bool[] operations = tester.UnMutatedOperations;
            operationsSequence = new string[Individual.AmountOfEntriesInResults];
            operationsSequence[0] = $"{tester.InitialValue}";
            int index = 0;

            int operationsCount = operations.Length;
            int operationsUsed = 1;
            Dictionary<EOperations, int> operationCounters = new Dictionary<EOperations, int>();
            for (int i = 0; i < operationsCount; i += 2)
            {
                index++;
                bool doNextOperation = operations[i];
                bool useFirstOperation = operations[i + 1];
                bool mutatedResult = false;

                if (mutatedOperationIndexes.Contains(i))
                {
                    doNextOperation = !doNextOperation;
                    mutatedResult = true;
                }

                if (mutatedOperationIndexes.Contains(i + 1))
                {
                    useFirstOperation = !useFirstOperation;
                    mutatedResult = true;
                }

                EOperations nextOperation = EOperations.DoNothing;

                if (doNextOperation)
                {
                    if (operationsUsed % 5 == 0)
                    {
                        nextOperation = EOperations.SquareOrSquareRoot;
                        operationsUsed = 0;
                    }
                    else if (operationsUsed % 2 == 0)
                    {
                        nextOperation = EOperations.MultiplyOrDivide;
                    }
                    else
                    {
                        nextOperation = EOperations.AddOrSubtract;
                    }
                }
                operationsUsed++;

                string resultString = string.Empty;
                try
                {
                    switch (nextOperation)
                    {
                        case EOperations.DoNothing: operationsSequence[index] = "Ignorada " + (mutatedResult ? "(Mutación)" : string.Empty); continue;
                        case EOperations.AddOrSubtract:
                            char asSign = useFirstOperation ? '+' : '-';
                            resultString += $"{asSign}{operationCounters.GetNextMagnitude(EOperations.AddOrSubtract)}";
                            break;
                        case EOperations.MultiplyOrDivide:
                            char mdSign = useFirstOperation ? '*' : '/';
                            resultString +=
                                $"{mdSign}{operationCounters.GetNextMagnitude(EOperations.MultiplyOrDivide)}";
                            break;
                        case EOperations.SquareOrSquareRoot:
                            string ssSign = useFirstOperation ? "^2" : "Raíz Cuadrada";
                            resultString += $"{ssSign}";
                            break;
                        default:
                            throw new NotImplementedException(
                                $@"It was attempted to execute an unsupported operation type: {nextOperation}");
                    }

                    if (mutatedResult)
                    {
                        resultString += " (Mutación)";
                    }

                    operationsSequence[index] = resultString;
                }
                catch { continue; }
            }

            string sign = tester.Sign ? "*1 (Signo)" : "*-1 (Signo)";

            operationsSequence[operationsSequence.Length - 2] = sign;
            operationsSequence[operationsSequence.Length - 1] = $"{result}";

            chromosomeStates = this.tester.CurrentChromosomeStates;
        }
        /// <summary>
        /// Evaluate a simple mathematical expression
        /// Recognizes +, -, *, /, ^,and ()
        /// Uses the Dijkstra Shunting-yard algorithm
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="variables"></param>
        /// <returns></returns>
        public static float Evaluate(string exp, Dictionary <string, float> variables)
        {
            float sum = 0;

            Stack <float>       vals = new Stack <float>();
            Stack <EOperations> ops  = new Stack <EOperations>();
            string s = "";

            for (int i = 0; i < exp.Length; ++i)
            {
                // Parenthesis logic
                if (exp[i] == '(')
                {
                    ops.Push(EOperations.LeftParenthesis);
                    continue;
                }

                if (exp[i] == ')')
                {
                    while (ops.Peek() != EOperations.LeftParenthesis)
                    {
                        EOperations op     = ops.Pop();
                        float       val1   = vals.Pop();
                        float       val2   = vals.Pop();
                        float       result = EvalBinaryOperation(val1, val2, op);

                        vals.Push(result);
                    }

                    ops.Pop(); // remove left parenthesis
                    continue;
                }

                // Operator logic
                if (isOperator(exp[i]))
                {
                    // Perform higher priority operations already recorded
                    while (ops.Count > 0 &&
                           OperationPriority[ops.Peek()] > OperationPriority[(EOperations)(exp[i])])
                    {
                        EOperations op     = ops.Pop();
                        float       val1   = vals.Pop();
                        float       val2   = vals.Pop();
                        float       result = EvalBinaryOperation(val1, val2, op);

                        vals.Push(result);
                    }

                    ops.Push((EOperations)exp[i]);
                    continue;
                }
                else
                {
                    // Operand logic
                    while (i < exp.Length && !isOperator(exp[i]))
                    {
                        // captures the next character after special characters
                        if (exp[i] == 'e' || exp[i] == '.')
                        {
                            s += exp[i++];
                        }

                        s += exp[i++];
                        continue;
                    }

                    // Check if the operand is a variable or a numerical value
                    float num   = 0;
                    bool  isNum = float.TryParse(s, out num);

                    // If this operand is a variable, substitute the value from the variable dictionary
                    if (!isNum)
                    {
                        if (!variables.ContainsKey(s))
                        {
                            Debug.LogError(String.Format("Math Parser Error: An unrecognized variable was used in an expression {0}", s));
                        }
                        num = variables[s];
                    }

                    vals.Push(num);
                    s = "";
                    --i;
                }
            }

            while (ops.Count > 0)
            {
                EOperations op   = ops.Pop();
                float       val1 = vals.Pop();
                float       val2 = vals.Pop();

                float result = EvalBinaryOperation(val1, val2, op);

                vals.Push(result);
            }

            sum = vals.Pop();
            return(sum);
        }