diff --git a/ruoyi-modules/ruoyi-demo/pom.xml b/ruoyi-modules/ruoyi-demo/pom.xml
index a7632ff..e1a44ff 100644
--- a/ruoyi-modules/ruoyi-demo/pom.xml
+++ b/ruoyi-modules/ruoyi-demo/pom.xml
@@ -22,6 +22,12 @@
true
+
+ org.apache.commons
+ commons-math3
+ 3.4.1
+
+
org.dromara
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/test/DEAExample.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/test/DEAExample.java
new file mode 100644
index 0000000..0446a86
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/test/DEAExample.java
@@ -0,0 +1,49 @@
+package org.dromara.demo.controller.test;
+
+import java.util.List;
+
+/**
+ * DEA模型使用示例
+ */
+public class DEAExample {
+ public static void main(String[] args) {
+ // 示例:3个DMU,2个投入指标,1个产出指标
+ // 投入矩阵: 每行代表一个DMU的投入
+ // 例如: 投入可以是员工数量和资金投入
+ double[][] inputs = {
+ {2, 3}, // DMU 0的投入
+ {3, 4}, // DMU 1的投入
+ {1, 5}, // DMU 2的投入
+ {2, 3}, // DMU 3的投入
+ {3, 4}, // DMU 4的投入
+ {1, 5} // DMU 5的投入
+ };
+
+ // 产出矩阵: 每行代表一个DMU的产出
+ // 例如: 产出可以是利润
+ double[][] outputs = {
+ {5}, // DMU 0的产出
+ {6}, // DMU 1的产出
+ {4}, // DMU 2的产出
+ {5}, // DMU 0的产出
+ {6}, // DMU 1的产出
+ {4} // DMU 2的产出
+
+ };
+
+ // 计算所有DMU的效率值
+ List results = DEAUtils.calculateAllDMUs(inputs, outputs);
+
+ // 输出结果
+ for (DEAUtils.DEAResult result : results) {
+ System.out.println(result);
+ }
+
+ // 单独计算某个DMU的效率值
+ int targetDMU = 1;
+ DEAUtils.DEAResult specificResult = DEAUtils.calculateDEA(inputs, outputs, targetDMU);
+ System.out.println("\n单独评估DMU " + targetDMU + " 的详细结果:");
+ System.out.println("效率值: " + specificResult.getEfficiency());
+ System.out.println("是否DEA有效: " + specificResult.isEfficient());
+ }
+}
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/test/DEAUtils.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/test/DEAUtils.java
new file mode 100644
index 0000000..c171850
--- /dev/null
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/test/DEAUtils.java
@@ -0,0 +1,267 @@
+package org.dromara.demo.controller.test;
+
+import org.apache.commons.math3.linear.Array2DRowRealMatrix;
+import org.apache.commons.math3.linear.RealMatrix;
+import org.apache.commons.math3.optim.*;
+import org.apache.commons.math3.optim.linear.*;
+import org.apache.commons.math3.optim.nonlinear.scalar.GoalType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * DEA(数据包络分析)工具类,实现面向投入的CCR模型
+ */
+public class DEAUtils {
+
+ /**
+ * 计算指定DMU的效率值
+ *
+ * @param inputs 投入矩阵,每行代表一个DMU的所有投入,行数为DMU数量,列数为投入指标数量
+ * @param outputs 产出矩阵,每行代表一个DMU的所有产出,行数为DMU数量,列数为产出指标数量
+ * @param dmuIndex 要评估的DMU索引(从0开始)
+ * @return DEA计算结果,包含效率值和松弛变量等信息
+ * @throws IllegalArgumentException 输入数据不合法时抛出
+ */
+ public static DEAResult calculateDEA(double[][] inputs, double[][] outputs, int dmuIndex) {
+ // 验证输入数据合法性
+ validateInput(inputs, outputs, dmuIndex);
+
+ int n = inputs.length; // DMU数量
+ int m = inputs[0].length; // 投入指标数量
+ int s = outputs[0].length; // 产出指标数量
+
+ // 变量数量: n个lambda + 1个theta + m个投入松弛变量 + s个产出松弛变量
+ int varCount = n + 1 + m + s;
+
+ // 目标函数: 最小化theta(第n个变量)
+ double[] objectiveCoefficients = new double[varCount];
+ objectiveCoefficients[n] = 1.0; // theta的系数为1,其他变量系数为0
+
+ // 创建线性规划问题
+ LinearObjectiveFunction objective = new LinearObjectiveFunction(objectiveCoefficients, 0);
+
+ // 约束条件列表
+ List constraints = new ArrayList<>();
+
+ // 1. 投入约束: sum(lambda_j * x_ij) + s_i^- = theta * x_ik (i=1..m)
+ for (int i = 0; i < m; i++) {
+ double[] coefficients = new double[varCount];
+ // 设置lambda_j的系数
+ for (int j = 0; j < n; j++) {
+ coefficients[j] = inputs[j][i];
+ }
+ // 设置theta的系数
+ coefficients[n] = -inputs[dmuIndex][i];
+ // 设置投入松弛变量的系数
+ coefficients[n + 1 + i] = 1.0;
+
+ // sum(lambda_j * x_ij) - theta * x_ik + s_i^- = 0
+ constraints.add(new LinearConstraint(coefficients, Relationship.EQ, 0.0));
+ }
+
+ // 2. 产出约束: sum(lambda_j * y_rj) - s_r^+ = y_rk (r=1..s)
+ for (int r = 0; r < s; r++) {
+ double[] coefficients = new double[varCount];
+ // 设置lambda_j的系数
+ for (int j = 0; j < n; j++) {
+ coefficients[j] = outputs[j][r];
+ }
+ // 设置产出松弛变量的系数
+ coefficients[n + 1 + m + r] = -1.0;
+
+ // sum(lambda_j * y_rj) - s_r^+ = y_rk
+ constraints.add(new LinearConstraint(coefficients, Relationship.EQ, outputs[dmuIndex][r]));
+ }
+
+ // 3. 变量非负约束
+ // lambda_j >= 0 (j=1..n)
+ // theta无符号限制,但在CCR模型中通常theta <= 1
+ // s_i^- >= 0 (i=1..m)
+ // s_r^+ >= 0 (r=1..s)
+ for (int j = 0; j < n; j++) {
+ double[] coefficients = new double[varCount];
+ coefficients[j] = 1.0;
+ constraints.add(new LinearConstraint(coefficients, Relationship.GEQ, 0.0));
+ }
+
+ // 投入松弛变量非负
+ for (int i = 0; i < m; i++) {
+ double[] coefficients = new double[varCount];
+ coefficients[n + 1 + i] = 1.0;
+ constraints.add(new LinearConstraint(coefficients, Relationship.GEQ, 0.0));
+ }
+
+ // 产出松弛变量非负
+ for (int r = 0; r < s; r++) {
+ double[] coefficients = new double[varCount];
+ coefficients[n + 1 + m + r] = 1.0;
+ constraints.add(new LinearConstraint(coefficients, Relationship.GEQ, 0.0));
+ }
+
+ // 4. theta <= 1约束
+ double[] thetaCoeff = new double[varCount];
+ thetaCoeff[n] = 1.0;
+ constraints.add(new LinearConstraint(thetaCoeff, Relationship.LEQ, 1.0));
+
+ // 求解器配置
+ SimplexSolver solver = new SimplexSolver();
+ LinearOptimizer optimizer = solver;
+
+ // 求解线性规划问题
+ PointValuePair solution = optimizer.optimize(
+ new LinearConstraintSet(constraints),
+ objective,
+ GoalType.MINIMIZE,
+ new NonNegativeConstraint(false), // 已单独设置非负约束
+ new MaxIter(1000)
+ );
+
+ // 解析结果
+ double[] solutionPoint = solution.getPoint();
+ double theta = solutionPoint[n]; // 效率值
+
+ // 投入松弛变量
+ double[] inputSlacks = new double[m];
+ System.arraycopy(solutionPoint, n + 1, inputSlacks, 0, m);
+
+ // 产出松弛变量
+ double[] outputSlacks = new double[s];
+ System.arraycopy(solutionPoint, n + 1 + m, outputSlacks, 0, s);
+
+ // lambda值
+ double[] lambdas = new double[n];
+ System.arraycopy(solutionPoint, 0, lambdas, 0, n);
+
+ return new DEAResult(theta, inputSlacks, outputSlacks, lambdas, dmuIndex);
+ }
+
+ /**
+ * 计算所有DMU的效率值
+ *
+ * @param inputs 投入矩阵
+ * @param outputs 产出矩阵
+ * @return 所有DMU的DEA计算结果列表
+ */
+ public static List calculateAllDMUs(double[][] inputs, double[][] outputs) {
+ List results = new ArrayList<>();
+ for (int i = 0; i < inputs.length; i++) {
+ results.add(calculateDEA(inputs, outputs, i));
+ }
+ return results;
+ }
+
+ /**
+ * 验证输入数据的合法性
+ */
+ private static void validateInput(double[][] inputs, double[][] outputs, int dmuIndex) {
+ if (inputs == null || outputs == null) {
+ throw new IllegalArgumentException("投入和产出矩阵不能为null");
+ }
+
+ if (inputs.length != outputs.length) {
+ throw new IllegalArgumentException("投入和产出矩阵的行数(DMU数量)必须一致");
+ }
+
+ if (inputs.length == 0) {
+ throw new IllegalArgumentException("至少需要一个DMU");
+ }
+
+ int m = inputs[0].length;
+ for (double[] input : inputs) {
+ if (input.length != m) {
+ throw new IllegalArgumentException("所有DMU的投入指标数量必须一致");
+ }
+ }
+
+ int s = outputs[0].length;
+ for (double[] output : outputs) {
+ if (output.length != s) {
+ throw new IllegalArgumentException("所有DMU的产出指标数量必须一致");
+ }
+ }
+
+ if (dmuIndex < 0 || dmuIndex >= inputs.length) {
+ throw new IllegalArgumentException("DMU索引超出范围");
+ }
+ }
+
+ /**
+ * DEA计算结果封装类
+ */
+ public static class DEAResult {
+ private final double efficiency; // 效率值(theta)
+ private final double[] inputSlacks; // 投入松弛变量
+ private final double[] outputSlacks; // 产出松弛变量
+ private final double[] lambdas; // 各DMU的权重
+ private final int dmuIndex; // 对应的DMU索引
+
+ public DEAResult(double efficiency, double[] inputSlacks, double[] outputSlacks,
+ double[] lambdas, int dmuIndex) {
+ this.efficiency = efficiency;
+ this.inputSlacks = inputSlacks;
+ this.outputSlacks = outputSlacks;
+ this.lambdas = lambdas;
+ this.dmuIndex = dmuIndex;
+ }
+
+ /**
+ * 判断该DMU是否为DEA有效
+ * 当效率值=1且所有松弛变量为0时,DMU为DEA有效
+ */
+ public boolean isEfficient() {
+ if (Math.abs(efficiency - 1.0) > 1e-9) {
+ return false;
+ }
+ for (double slack : inputSlacks) {
+ if (Math.abs(slack) > 1e-9) {
+ return false;
+ }
+ }
+ for (double slack : outputSlacks) {
+ if (Math.abs(slack) > 1e-9) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // getter方法
+ public double getEfficiency() {
+ return efficiency;
+ }
+
+ public double[] getInputSlacks() {
+ return inputSlacks.clone();
+ }
+
+ public double[] getOutputSlacks() {
+ return outputSlacks.clone();
+ }
+
+ public double[] getLambdas() {
+ return lambdas.clone();
+ }
+
+ public int getDmuIndex() {
+ return dmuIndex;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("DMU ").append(dmuIndex).append(" 评估结果:\n");
+ sb.append(" 效率值: ").append(String.format("%.4f", efficiency)).append("\n");
+ sb.append(" 是否DEA有效: ").append(isEfficient()).append("\n");
+ sb.append(" 投入松弛变量: ");
+ for (double slack : inputSlacks) {
+ sb.append(String.format("%.4f ", slack));
+ }
+ sb.append("\n 产出松弛变量: ");
+ for (double slack : outputSlacks) {
+ sb.append(String.format("%.4f ", slack));
+ }
+ return sb.toString();
+ }
+ }
+}