Analizador de ecuaciones de álgebra para java
equation algebra (4)
Podrías hacer uso de las capacidades de scripting de Java 1.6:
import javax.script.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
Map<String, Object> vars = new HashMap<String, Object>();
vars.put("x", 2);
vars.put("y", 1);
vars.put("z", 3);
System.out.println("result = "+engine.eval("x + y + z", new SimpleBindings(vars)));
}
}
que produce:
result = 6.0
Para expresiones más complejas, JEP es una buena opción.
Necesito una biblioteca para poder analizar una ecuación y darme el resultado de las entradas.
Por ejemplo algo como esto:
String equation = "x + y + z";
Map<String, Integer> vars = new HashMap<String, Integer>();
vars.add("x", 2);
vars.add("y", 1),
vars.add("z", 3);
EquationSolver solver = new EquationSolver(equation, vars);
int result = solver.getResult();
System.out.println("result: " + result);
Y evalúa a: 6
¿Hay algún tipo de biblioteca para Java que pueda hacer eso por mí?
Gracias
Pruebe mXparser , a continuación encontrará un ejemplo de uso:
import org.mariuszgromada.math.mxparser.*;
...
...
String equation = "x + y + z";
Argument x = new Argument("x = 2");
Argument y = new Argument("y = 1");
Argument z = new Argument("z = 3");
Expression solver = new Expression(equation, x, y, z);
double result1 = solver.calculate();
System.out.println("result 1: " + result1);
x.setArgumentValue(3);
y.setArgumentValue(4);
z.setArgumentValue(5);
double result2 = solver.calculate();
System.out.println("result 2: " + result2);
Resultado:
result 1: 6.0
result 2: 12.0
Aquí, la ventaja de mXparser es que mXparser precompila la expresión solo una vez, y luego, después de cambiar los valores de los argumentos, el cálculo se realiza muy rápido.
Siga el tutorial mXparser , la colección matemática mXparser , mXparser API .
Saludos
Si desea un alto rendimiento, desaconsejo el uso de exp4j ya que las clases de CogitoLearning son aproximadamente 2600 veces más rápidas que exp4j (probadas en iteraciones de 1 millón), sí, lo han leído bien.
A menudo, las expresiones simples serán suficientes para aplicaciones de negocios. Por lo tanto, la biblioteca creada por CogitoLearning es probablemente una mejor opción.
Resultados de referencia:
1000000 iterations to evaluate 200*(1+(pi/2))^2
Time Exp4J: 1.041117999977863E-5
Time JavaScript:4.532046999924487E-5 - 0.2297235664138545x slower than Exp4j
Time ExpCogit: 4.0000000000000036E-9 - 2602.794999944655x faster than Exp4j
Para la biblioteca de Cogito, consulte http://cogitolearning.co.uk/docs/cogpar/index.html
Tenga en cuenta que: el caso de prueba no es del todo puro para evaluar el rendimiento de JavaScript, ya que no usé una expresión precompilada para ese caso.
Código de referencia utilizado:
public class TestParser {
private static String exprStr = "200*(1+(pi/2))^2";
/**
* Exp4j
*/
private static ExpressionBuilder eb = new ExpressionBuilder(exprStr);
/**
* Cogit
*/
private static Parser parser = new Parser();
private static ExpressionNode expr = parser.parse(exprStr);
/**
* JavaScript
*/
private static ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
private static Map<String, Object> vars = new HashMap<String, Object>();
public static void main(String[] args) throws UnknownFunctionException, UnparsableExpressionException, ScriptException {
int n = 1000000;
double t1 = 0d;
for(int i=1; i!=n; i++) {
t1+=getCalcTimeExp4J();
}
double r1=t1/n;
double t2 = 0d;
for(int i=1; i!=n; i++) {
t2+=getCalcTimeCogit();
}
double r2=t2/n;
double t3 = 0d;
for(int i=1; i!=n; i++) {
t3+=getCalcTimeJavaScriptEngine();
}
double r3=t3/n;
System.out.println(n + " iterations to evaluate " + exprStr);
System.out.println("Time Exp4J:/t" + r1);
System.out.println("Time JavaScript:" + r3 + " - " + r1/r3 + "x slower than Exp4j");
System.out.println("Time ExpCogit:/t" + r2 + " - " + r1/r2 + "x faster than Exp4j");
}
private static double getCalcTimeJavaScriptEngine() throws ScriptException {
long t = Util.nanotime();
vars.put("pi", Math.PI);
//Note that we''re actually not using a pre-build expression here.
engine.eval(exprStr, new SimpleBindings(vars));
return(Util.nanotimeToSeconds(t));
}
private static double getCalcTimeCogit() {
long t = Util.nanotime();
expr.accept(new SetVariable("pi", Math.PI));
double r = expr.getValue();
return(Util.nanotimeToSeconds(t));
}
private static double getCalcTimeExp4J() throws UnknownFunctionException, UnparsableExpressionException {
long t = Util.nanotime();
Calculable calc = eb.withVariable("pi", Math.PI).build();
double r = calc.calculate();
return(Util.nanotimeToSeconds(t));
}
}
También está exp4j , un evaluador de expresiones basado en Shunting Yard de Dijkstra. Está disponible de forma gratuita y se puede redistribuir bajo la Licencia Apache 2.0, solo tiene un tamaño de 25 kb y es bastante fácil de usar.
Calculable calc = new ExpressionBuilder("3 * sin(y) - 2 / (x - 2)")
.withVariable("x", varX)
.withVariable("y", varY)
.build()
double result1=calc.calculate();
También hay una facilidad para usar funciones personalizadas en exp4j .
¡que te diviertas!