Подтвердить что ты не робот

Метод оценки математических выражений в Java

В одном из моих проектов я хочу добавить функцию, которую пользователь может предоставить в формуле, например

sin (x + pi)/2 + 1

который я использую в своем приложении Java

/**
 * The formula provided by the user
 */
private String formula; // = "sin (x + pi)/2 + 1"

/*
 * Evaluates the formula and computes the result by using the
 * given value for x
 */
public double calc(double x) {
    Formula f = new Formula(formula);
    f.setVar("x", x);
    return f.calc();
    // or something similar
}

Как я могу оценить математические выражения?

4b9b3361

Ответ 1

Также есть exp4j, оценщик выражений, основанный на Dijkstra Shunting Yard. Он свободно доступен и распространяется по лицензии Apache License 2.0, его размер составляет всего около 25 КБ, и он довольно прост в использовании:

Calculable calc = new ExpressionBuilder("3 * sin(y) - 2 / (x - 2)")
        .withVariable("x", varX)
        .withVariable("y", varY)
        .build()
double result1=calc.calculate();

При использовании более новой версии API, например 0.4.8:

Expression calc = new ExpressionBuilder("3 * sin(y) - 2 / (x - 2)")
    .variable("x", x)
    .variable("y", y)
    .build();
double result1 = calc.evaluate();

Также есть возможность использовать пользовательские функции в exp4j.

Ответ 2

Это зависит от того, насколько сложны выражения, которые вы хотите оценить, но для простых, java имеет механизм javascript, который работает очень хорошо:

import javax.script.*;
public class EvalScript {
public static void main(String[] args) throws Exception {
    // create a script engine manager
    ScriptEngineManager factory = new ScriptEngineManager();
    // create a JavaScript engine
    ScriptEngine engine = factory.getEngineByName("JavaScript");
    // evaluate JavaScript code from String
    Object obj = engine.eval("1+2");
    System.out.println( obj );
    }
}

Ответ 3

Чтобы расширить список, я тоже закончил его:

https://github.com/uklimaschewski/EvalEx

EvalEx - удобный анализатор выражений для Java, который позволяет оценивать простые математические и булевы выражения.

Основные характеристики:

  • Использует BigDecimal для вычисления и результата
  • Реализация одного класса, очень компактная
  • Никаких зависимостей от внешних библиотек
  • Режим точности и округления может быть установлен
  • Поддерживает переменные
  • Стандартные булевские и математические операторы
  • Стандартные базовые математические и булевы функции
  • Пользовательские функции и операторы могут быть добавлены во время выполнения

Примеры:

BigDecimal result = null;

Expression expression = new Expression("1+1/3");
result = expression.eval():
expression.setPrecision(2);
result = expression.eval():

result = new Expression("(3.4 + -4.1)/2").eval();

result = new Expression("SQRT(a^2 + b^2").with("a","2.4").and("b","9.253").eval();

BigDecimal a = new BigDecimal("2.4");
BigDecimal b = new BigDecimal("9.235");
result = new Expression("SQRT(a^2 + b^2").with("a",a).and("b",b).eval();

result = new Expression("2.4/PI").setPrecision(128).setRoundingMode(RoundingMode.UP).eval();

result = new Expression("random() > 0.5").eval();

result = new Expression("not(x<7 || sqrt(max(x,9)) <= 3))").with("x","22.9").eval();

Ответ 4

Хороший математический анализатор, содержащий широкую математическую коллекцию - mXparser - пожалуйста, ознакомьтесь с примерами:

Пример 1:

import org.mariuszgromada.math.mxparser.*;
...
...
Argument x = new Argument("x = pi");
Expression e = new Expression("sin(x + pi)/2 + 1", x);
mXparser.consolePrintln("Res 1: " + e.getExpressionString() + " = " + e.calculate());
x.setArgumentValue(2);
mXparser.consolePrintln("Res 2: " + e.getExpressionString() + " = " + e.calculate());

Результат:

[mXparser-v.4.0.0] Res 1: sin(x + pi)/2 + 1 = 1.0
[mXparser-v.4.0.0] Res 2: sin(x + pi)/2 + 1 = 0.545351286587159

Пример 2:

import org.mariuszgromada.math.mxparser.*;
...
...
Function f = new Function("f(x) = sin(x + pi)/2 + 1");
Expression e = new Expression("f(pi)", f);
mXparser.consolePrintln("Res: " + e.getExpressionString() + " = " + e.calculate());

Результат:

[mXparser-v.4.0.0] Res: f(pi) = 1.0

Для лучшего понимания следуйте учебник mXparser и mXparser math collection.

С наилучшими пожеланиями

Ответ 5

Добавив еще один вариант в список, я написал Jep Java, который приобрел большую популярность как проект с открытым исходным кодом на sourceforge.

Он поддерживает все основные общие задачи синтаксического анализа выражений. Но это также добавляет много расширяемости, если вы хотите его настроить. Многие пользователи похвалили библиотеку за то, что она особенно хорошо написана и проста в использовании. См. Отзывы в sourceforge!

Вот простой пример с одной переменной:

import com.singularsys.jep.Jep;

Jep jep = new Jep();
jep.addVariable("x", 10);
jep.parse("x+1");
Object result = jep.evaluate();
System.out.println("x + 1 = " + result);

Это напечатает "x + 1 = 11". Вы можете изменить значение переменных и быстро оценить выражение снова.

Затем я также предоставил библиотеку доступную с коммерческой лицензией на веб-сайте Singular Systems.

Ответ 6

У меня есть небольшой, но очень способный математический оценщик, который полностью не обременен.

Основные функции

  • Основные математические операторы с предполагаемым приоритетом (+ - * × / ÷ % ^).
  • Явный приоритет с круглыми скобками.
  • Неявное умножение заключенных в скобки подвыражений.
  • Правильная правая ассоциативность экспонент (оператор мощности).
  • Прямая поддержка шестнадцатеричных чисел с префиксом 0x.
  • Константы и переменные.
  • Расширяемые функции.
  • Расширяемые операторы.
  • Крошечный отпечаток 20 Киб.

Вот простой пример, который вычисляет средний столбец подраздела текстового дисплея (смещенный слева).

MathEval            math=new MathEval();

math.setVariable("Top",    5);
math.setVariable("Left",  20);
math.setVariable("Bottom",15);
math.setVariable("Right", 60);

System.out.println("Middle: "+math.evaluate("floor((Right+1-Left)/2)"));                        // 20

Ответ 7

Я уже писал подобный ответ здесь. Я просто хотел сказать, что я работал над небольшой библиотекой, которая поддерживает математическое, логическое и строковое выражение. Вот небольшой пример:

String expression = "EXP(var)";
ExpressionEvaluator evaluator = new ExpressionEvaluator();
evaluator.putVariable(new Variable("var", VariableType.NUMBER, new BigDecimal(20)));

System.out.println("Value of exp(var) : " + evaluator.evaluate(expression).getValue());

Если вас это интересует, он доступен здесь.