Commit ea3cc142 authored by Tong Li's avatar Tong Li

MP

parent f11971ca
......@@ -386,16 +386,16 @@ public class MacroPlannerOptimizer {
printer.printHierarchicalSummary(levels, finalLevelValues);
// 回写业务对象到JSON文件(预留)
ResultWriter rw = new ResultWriter(model, data, startTimeMs);
// ResultWriter rw = new ResultWriter(model, data, startTimeMs);
OptimizationResult optimizationResult = rw.buildResult();
boolean jsonPath = rw.saveResultToFile(sceneId, optimizationResult);
// OptimizationResult optimizationResult = rw.buildResult();
// boolean jsonPath = rw.saveResultToFile(sceneId, optimizationResult);
if (jsonPath) {
writeLog("\n[OK] 优化结果JSON已导出: " + jsonPath);
}
// if (jsonPath) {
// writeLog("\n[OK] 优化结果JSON已导出: " + jsonPath);
// }
writeLog("\n=== 分层求解完成 ===");
} else {
......
......@@ -57,36 +57,39 @@ public class MultiLevelBomTestRunner {
ApplicationContext ctx = SpringApplication.run(ApsApplication.class, args);
try {
MultiLevelBomTestDataBuilder data=new MultiLevelBomTestDataBuilder();
// MultiLevelBomTestDataBuilder data=new MultiLevelBomTestDataBuilder();
// data.init();
//
// MacroPlannerOptimizer optimizer = new MacroPlannerOptimizer(data);
// optimizer.buildModel();
// optimizer.solve("bom");
MpPispipResultPersistenceService service =
ctx.getBean(MpPispipResultPersistenceService.class);
int scale = 100;
BenchmarkDataBuilder data = BenchmarkDataBuilder.forScale(scale);
writeLog("===== TEST RUNNER START " + scale + "=====");
data.init();
writeLog("Data loaded: " + data.getProducts().size() + " products, "
+ data.getOperations().size() + " operations");
long startTime = System.currentTimeMillis();
MacroPlannerOptimizer optimizer = new MacroPlannerOptimizer(data);
optimizer.buildModel();
optimizer.solve("bom");
optimizer.solve(String.valueOf(scale));
// MpPispipResultPersistenceService service =
// ctx.getBean(MpPispipResultPersistenceService.class);
//
// int scale = 10000;
// BenchmarkDataBuilder data = BenchmarkDataBuilder.forScale(scale);
// writeLog("===== TEST RUNNER START " + scale + "=====");
//
// data.init();
// writeLog("Data loaded: " + data.getProducts().size() + " products, "
// + data.getOperations().size() + " operations");
//
// long startTime = System.currentTimeMillis();
// MacroPlannerOptimizer optimizer = new MacroPlannerOptimizer(data);
// optimizer.buildModel();
// optimizer.solve(String.valueOf(scale));
//
// // 构建结果并调用 save 入库
// ResultWriter writer = new ResultWriter(optimizer.getModel(), optimizer.getData(), startTime);
// OptimizationResult result = writer.buildResult();
// int saved = service.save(String.valueOf(scale), result);
// writeLog("PISPIP result saved: " + saved);
//
// writeLog("===== TEST RUNNER END =====");
// 构建结果并调用 save 入库
ResultWriter writer = new ResultWriter(optimizer.getModel(), optimizer.getData(), startTime);
OptimizationResult result = writer.buildResult(String.valueOf(scale));
boolean jsonPath = writer.saveResultToFile(String.valueOf(scale), result);
writeLog("PISPIP result saved: ");
int saved = service.save(String.valueOf(scale), result);
writeLog("PISPIP result saved: " + saved);
writeLog("===== TEST RUNNER END =====");
} catch (Exception e) {
} finally {
......
......@@ -140,7 +140,7 @@ public class ResultWriter {
}
public boolean saveResultToFile(String sceneId) {
OptimizationResult result = buildResult();
OptimizationResult result = buildResult(sceneId);
return saveResultToFile(sceneId,result);
}
......@@ -164,20 +164,24 @@ public class ResultWriter {
}
FlatParquetUtil parquetUtil = new FlatParquetUtil();
String periodTaskPath = getOptimizationPeriodTask(sceneId);
writeLog("writePeriodTasks");
writeLog("writePeriodTasks"+result.getPeriodTasks().size());
parquetUtil.write(result.getPeriodTasks(), periodTaskPath, PeriodTaskResult.class);
writeLog("writePeriodTasks");
writeLog("writePispips");
writeLog("writePispips:"+result.getPispips().size());
String pispiPath = getOptimizationPispip(sceneId);
parquetUtil.write(result.getPispips(), pispiPath, PispipResult.class);
writeLog("writePispips");
writeLog("writesalesDemand");
String salesDemandPath = getOptimizationSalesDemand(sceneId);
parquetUtil.write(result.getSalesDemands(), salesDemandPath, SalesDemandResult.class);
// List<PispipResult> pispips = parquetUtil.readAll(pispiPath, PispipResult.class);
writeLog("writesalesDemand");
writeLog("writesalesDemand");
writeLog("UnitCapacities");
String unitPath = getOptimizationUnitCapacitie(sceneId);
parquetUtil.write(result.getUnitCapacities(), unitPath, UnitCapacityResult.class);
writeLog("writesalesDemand");
writeLog("UnitCapacities");
// BOM 结构持久化 (供 getProductNetwork 按需组装)
writeLog("writeBomStructure");
......@@ -186,58 +190,59 @@ public class ResultWriter {
writeLog("writeOperationDemands");
List<OperationDemandResult> opDemands = buildOperationDemandResults();
parquetUtil.write(opDemands, getOptimizationOperationDemand(sceneId), OperationDemandResult.class);
try {
File file = getOptimizationFile(sceneId);
File tempFile = new File(file.getParentFile(), file.getName() + ".tmp");
if (useCompression) {
try (FileOutputStream fos = new FileOutputStream(tempFile);
GZIPOutputStream gzos = new GZIPOutputStream(fos)) {
objectMapper.writeValue(gzos, result);
}
} else {
objectMapper.writeValue(tempFile, result);
}
if (tempFile.length() == 0) {
logger.error("写入的临时文件为空: {}", tempFile.getAbsolutePath());
Files.deleteIfExists(tempFile.toPath());
return false;
}
if (useCompression) {
try (FileInputStream fis = new FileInputStream(tempFile);
GZIPInputStream gzis = new GZIPInputStream(fis)) {
OptimizationResult verifyChromosome = objectMapper.readValue(gzis, OptimizationResult.class);
if (verifyChromosome == null) {
throw new IOException("验证读取失败");
}
}
} else {
try {
OptimizationResult verifyChromosome = objectMapper.readValue(tempFile, OptimizationResult.class);
if (verifyChromosome == null) {
throw new IOException("验证读取失败");
}
} catch (Exception e) {
logger.error("验证染色体文件内容失败,文件: {}", tempFile.getAbsolutePath(), e);
Files.deleteIfExists(tempFile.toPath());
return false;
}
}
if (file.exists()) {
Files.deleteIfExists(file.toPath());
}
Files.move(tempFile.toPath(), file.toPath());
logger.info("保存成功,场景ID: {}, 文件: {}", sceneId, file.getAbsolutePath());
return true;
} catch (Exception e) {
logger.error("保存文件失败,场景ID: " + sceneId, e);
return false;
}
// try {
//
// File file = getOptimizationFile(sceneId);
// File tempFile = new File(file.getParentFile(), file.getName() + ".tmp");
//
// if (useCompression) {
// try (FileOutputStream fos = new FileOutputStream(tempFile);
// GZIPOutputStream gzos = new GZIPOutputStream(fos)) {
// objectMapper.writeValue(gzos, result);
// }
// } else {
// objectMapper.writeValue(tempFile, result);
// }
//
// if (tempFile.length() == 0) {
// logger.error("写入的临时文件为空: {}", tempFile.getAbsolutePath());
// Files.deleteIfExists(tempFile.toPath());
// return false;
// }
//
// if (useCompression) {
// try (FileInputStream fis = new FileInputStream(tempFile);
// GZIPInputStream gzis = new GZIPInputStream(fis)) {
// OptimizationResult verifyChromosome = objectMapper.readValue(gzis, OptimizationResult.class);
// if (verifyChromosome == null) {
// throw new IOException("验证读取失败");
// }
// }
// } else {
// try {
// OptimizationResult verifyChromosome = objectMapper.readValue(tempFile, OptimizationResult.class);
// if (verifyChromosome == null) {
// throw new IOException("验证读取失败");
// }
// } catch (Exception e) {
// logger.error("验证染色体文件内容失败,文件: {}", tempFile.getAbsolutePath(), e);
// Files.deleteIfExists(tempFile.toPath());
// return false;
// }
// }
//
// if (file.exists()) {
// Files.deleteIfExists(file.toPath());
// }
// Files.move(tempFile.toPath(), file.toPath());
//
// logger.info("保存成功,场景ID: {}, 文件: {}", sceneId, file.getAbsolutePath());
// return true;
// } catch (Exception e) {
// logger.error("保存文件失败,场景ID: " + sceneId, e);
// return false;
// }
} catch (IOException ex) {
logger.error("保存文件失败,场景ID: " + sceneId, ex);
return false;
......@@ -440,9 +445,7 @@ public class ResultWriter {
/**
* 收集所有结果并返回 JSON 字符串。
*/
public String toJsonString() {
return toJson(buildResult());
}
private static final String LOG_DIR = "mp";
/** LP 模型文件路径 */
......@@ -454,9 +457,13 @@ public class ResultWriter {
{
FileHelper.writeFile(msg,LOG_FILE_PATH,"log.txt");
}
private static void writeLog(String msg, Object... args)
{
FileHelper.writeFile(String.format(msg,args),LOG_FILE_PATH,"log.txt");
}
// ==================== 构建 OptimizationResult ====================
public OptimizationResult buildResult() {
public OptimizationResult buildResult(String sceneId) {
OptimizationResult result = new OptimizationResult();
// 元数据
......@@ -467,7 +474,7 @@ public class ResultWriter {
// 业务结果
writeLog("PeriodTasks");
buildPeriodTasks(result);
buildPeriodTasks(sceneId,result);
writeLog("SalesDemands");
buildSalesDemands(result);
writeLog("Pispips");
......@@ -487,7 +494,7 @@ public class ResultWriter {
// ==================== PeriodTaskResult ====================
private void buildPeriodTasks(OptimizationResult result) {
private void buildPeriodTasks(String sceneId,OptimizationResult result) {
for (Operation op : data.getOperations()) {
for (UnitOperation uo : op.getUnitOperations()) {
for (Period p : data.getPeriods()) {
......
......@@ -38,9 +38,9 @@ public class MpPispipResultPersistenceService {
Map<Object,String> detailIds = new IdentityHashMap<>();
int saved = batch.executeInTransaction(c -> {
batch.batchInsert(c, parent, result.getPispips(), BATCH_SIZE, (s,p) -> bindParent(s,p,sceneId,ids));
for (PispipResult p : result.getPispips()) for (PispipResult.ProductionDetail d : p.getProductionDetails()) { details.add(d); detailIds.put(d, UUID.randomUUID().toString()); boms.addAll(d.bomConsumptions); }
batch.batchInsert(c, prod, details, BATCH_SIZE, (s,d) -> { String pid = owner(ids,d); s.setString(1,detailIds.get(d)); s.setString(2,pid); s.setString(3,sceneId); s.setString(4,d.operationId); s.setString(5,d.operationName); s.setString(6,d.unitId); s.setString(7,d.unitName); s.setDouble(8,d.quantity); s.setInt(9,d.leadTimeDays); });
batch.batchInsert(c, bom, boms, BATCH_SIZE, (s,b) -> { String did = detailIds.get(findDetail(details,b)); String pid = owner(ids,findDetail(details,b)); s.setString(1,UUID.randomUUID().toString()); s.setString(2,did); s.setString(3,pid); s.setString(4,sceneId); s.setString(5,b.inputProductId); s.setString(6,b.inputSpId); s.setString(7,b.inputSpName); s.setDouble(8,b.factor); s.setDouble(9,b.consumedQty); });
// for (PispipResult p : result.getPispips()) for (PispipResult.ProductionDetail d : p.getProductionDetails()) { details.add(d); detailIds.put(d, UUID.randomUUID().toString()); boms.addAll(d.bomConsumptions); }
// batch.batchInsert(c, prod, details, BATCH_SIZE, (s,d) -> { String pid = owner(ids,d); s.setString(1,detailIds.get(d)); s.setString(2,pid); s.setString(3,sceneId); s.setString(4,d.operationId); s.setString(5,d.operationName); s.setString(6,d.unitId); s.setString(7,d.unitName); s.setDouble(8,d.quantity); s.setInt(9,d.leadTimeDays); });
// batch.batchInsert(c, bom, boms, BATCH_SIZE, (s,b) -> { String did = detailIds.get(findDetail(details,b)); String pid = owner(ids,findDetail(details,b)); s.setString(1,UUID.randomUUID().toString()); s.setString(2,did); s.setString(3,pid); s.setString(4,sceneId); s.setString(5,b.inputProductId); s.setString(6,b.inputSpId); s.setString(7,b.inputSpName); s.setDouble(8,b.factor); s.setDouble(9,b.consumedQty); });
return ids.size();
});
log.info("Saved PISPIP result: sceneId={}, parents={}, productions={}, boms={}",sceneId,ids.size(),details.size(),boms.size());
......
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