Commit c6774944 authored by Tong Li's avatar Tong Li

MP-将kpi设置接入,优化器

parent baed89e8
...@@ -533,7 +533,7 @@ public class MacroPlannerResultController { ...@@ -533,7 +533,7 @@ public class MacroPlannerResultController {
+ "耗时通常数秒到数分钟, 取决于数据规模。") + "耗时通常数秒到数分钟, 取决于数据规模。")
public R<Map<String, Object>> runOptimization( public R<Map<String, Object>> runOptimization(
@RequestParam("sceneId") @Parameter(description = "场景ID", required = true) String sceneId @RequestParam("sceneId") @Parameter(description = "场景ID", required = true) String sceneId
, @RequestParam("sceneId") @Parameter(description = "场景ID", required = true) Integer sceneI) { , @RequestParam("strategyId") @Parameter(description = "kpi设置", required = true) Integer strategyId) {
if (sceneId == null || sceneId.trim().isEmpty()) { if (sceneId == null || sceneId.trim().isEmpty()) {
return R.failed("sceneId不能为空"); return R.failed("sceneId不能为空");
} }
...@@ -544,7 +544,7 @@ public class MacroPlannerResultController { ...@@ -544,7 +544,7 @@ public class MacroPlannerResultController {
try { try {
// 1. 数据转换: 数据库工艺物料类 → macroplanner 实体 // 1. 数据转换: 数据库工艺物料类 → macroplanner 实体
TestDataBuilder data = macroPlannerDataConverter.convert(sid,sceneI); TestDataBuilder data = macroPlannerDataConverter.convert(sid,strategyId);
result.put("dataSummary", buildDataSummary(data)); result.put("dataSummary", buildDataSummary(data));
// 2. 数据验证 // 2. 数据验证
......
...@@ -38,7 +38,9 @@ import java.time.Duration; ...@@ -38,7 +38,9 @@ import java.time.Duration;
import java.time.DayOfWeek; import java.time.DayOfWeek;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.time.temporal.WeekFields;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
...@@ -1197,6 +1199,12 @@ public class MacroPlannerDataConverter { ...@@ -1197,6 +1199,12 @@ public class MacroPlannerDataConverter {
case "MONTH": case "MONTH":
createMonthPeriods(baseDate, periodCount, horizonEnd); createMonthPeriods(baseDate, periodCount, horizonEnd);
break; break;
case "YEAR":
createYearPeriods(baseDate, periodCount, horizonEnd);
break;
case "QUARTER":
createQuarterPeriods(baseDate, periodCount, horizonEnd);
break;
case "DAY": case "DAY":
default: default:
createDayPeriods(baseDate, periodCount); createDayPeriods(baseDate, periodCount);
...@@ -1264,7 +1272,9 @@ public class MacroPlannerDataConverter { ...@@ -1264,7 +1272,9 @@ public class MacroPlannerDataConverter {
/** DAY 维度: 每天一个 Period */ /** DAY 维度: 每天一个 Period */
private void createDayPeriods(LocalDate baseDate, int periodCount) { private void createDayPeriods(LocalDate baseDate, int periodCount) {
for (int i = 0; i < periodCount; i++) { for (int i = 0; i < periodCount; i++) {
periods.add(new Period(i, formatDayName(baseDate.plusDays(i)), 1.0, baseDate.plusDays(i))); int index = Integer.parseInt(baseDate.plusDays(i).format(DateTimeFormatter.BASIC_ISO_DATE));
periods.add(new Period(index, formatDayName(baseDate.plusDays(i)), 1.0, baseDate.plusDays(i)));
} }
} }
...@@ -1278,8 +1288,10 @@ public class MacroPlannerDataConverter { ...@@ -1278,8 +1288,10 @@ public class MacroPlannerDataConverter {
if (weekEnd.isAfter(horizonEnd)) { if (weekEnd.isAfter(horizonEnd)) {
weekEnd = horizonEnd; weekEnd = horizonEnd;
} }
int index = Integer.parseInt(ws.format(DateTimeFormatter.BASIC_ISO_DATE));
long durationDays = ChronoUnit.DAYS.between(ws, weekEnd); long durationDays = ChronoUnit.DAYS.between(ws, weekEnd);
periods.add(new Period(i, "W" + (i + 1) + "(" + ws + ")", (double) durationDays, ws)); periods.add(new Period(index, formatWeekName(ws), (double) durationDays, ws));
} }
} }
...@@ -1293,17 +1305,70 @@ public class MacroPlannerDataConverter { ...@@ -1293,17 +1305,70 @@ public class MacroPlannerDataConverter {
monthEnd = horizonEnd; monthEnd = horizonEnd;
} }
long durationDays = java.time.temporal.ChronoUnit.DAYS.between(monthStart, monthEnd); long durationDays = java.time.temporal.ChronoUnit.DAYS.between(monthStart, monthEnd);
periods.add(new Period(i, formatMonthName(monthStart), (double) durationDays, monthStart)); int index = Integer.parseInt(monthStart.format(DateTimeFormatter.BASIC_ISO_DATE));
periods.add(new Period(index, formatMonthName(monthStart), (double) durationDays, monthStart));
cursor = cursor.plusMonths(1); cursor = cursor.plusMonths(1);
} }
} }
private void createYearPeriods(LocalDate baseDate, int periodCount, LocalDate horizonEnd) {
LocalDate cursor = baseDate.withDayOfYear(1);
for (int i = 0; i < periodCount; i++) {
LocalDate monthStart = cursor;
LocalDate monthEnd = cursor.plusYears(1);
if (monthEnd.isAfter(horizonEnd)) {
monthEnd = horizonEnd;
}
long durationDays = java.time.temporal.ChronoUnit.DAYS.between(monthStart, monthEnd);
int index = Integer.parseInt(monthStart.format(DateTimeFormatter.BASIC_ISO_DATE));
periods.add(new Period(index, formatYearName(monthStart), (double) durationDays, monthStart));
cursor = cursor.plusYears(1);
}
}
private void createQuarterPeriods(LocalDate baseDate, int periodCount, LocalDate horizonEnd) {
int month = baseDate.getMonthValue();
// 计算当前属于第几季度(1~4),整数除法自动取整
int quarter = (month - 1) / 3 + 1;
// 计算该季度的首月月份
int quarterStartMonth = (quarter - 1) * 3 + 1;
// 构造季度起始日期(首月1号)
LocalDate cursor = baseDate.withMonth(quarterStartMonth).withDayOfMonth(1);
for (int i = 0; i < periodCount; i++) {
LocalDate monthStart = cursor;
LocalDate monthEnd = cursor.plusMonths(3);
if (monthEnd.isAfter(horizonEnd)) {
monthEnd = horizonEnd;
}
long durationDays = java.time.temporal.ChronoUnit.DAYS.between(monthStart, monthEnd);
int index = Integer.parseInt(monthStart.format(DateTimeFormatter.BASIC_ISO_DATE));
periods.add(new Period(index, formatQuarterName(monthStart), (double) durationDays, monthStart));
cursor = cursor.plusMonths( 3);
}
}
private static String formatDayName(LocalDate date) { private static String formatDayName(LocalDate date) {
return String.format("D%02d(%02d-%02d)", date.getDayOfYear(), date.getMonthValue(), date.getDayOfMonth()); return String.format("D-%02d(%02d-%02d)", date.getDayOfYear(), date.getMonthValue(), date.getDayOfMonth());
}
private static String formatWeekName(LocalDate date) {
WeekFields weekFields = WeekFields.ISO;
int weekNo = date.get(weekFields.weekOfMonth());
return String.format("W-%02d(%02d-%02d)", date.getDayOfYear(), date.getMonthValue(), weekNo);
} }
private static String formatMonthName(LocalDate date) { private static String formatMonthName(LocalDate date) {
return String.format("M%d-%02d", date.getYear(), date.getMonthValue()); return String.format("M-%d-%02d", date.getYear(), date.getMonthValue());
}
private static String formatYearName(LocalDate date) {
return String.format("Y-%d", date.getYear());
}
private static String formatQuarterName(LocalDate date) {
int month = date.getMonthValue();
// 计算当前属于第几季度(1~4),整数除法自动取整
int quarter = (month - 1) / 3 + 1;
return String.format("Q-%d-%d", date.getYear(),quarter);
} }
// ---------- 步骤8: SalesDemand (从订单推导) ---------- // ---------- 步骤8: SalesDemand (从订单推导) ----------
......
...@@ -724,7 +724,7 @@ public class SolutionPrinter { ...@@ -724,7 +724,7 @@ public class SolutionPrinter {
KpiLib kpi = KpiLib.ofEn(key); KpiLib kpi = KpiLib.ofEn(key);
double val= model.getKpi(key).solutionValue(); double val= model.getKpi(key).solutionValue();
writeLog(" %s: %.2f (权重%.0f × %.2f)", writeLog(" %s: %.2f (权重%.0f × %.2f)",
kpi.getCn(),val * weight, val, val); kpi.getCn(),val * weight, val, weight);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment