Commit ea3cc142 authored by Tong Li's avatar Tong Li

MP

parent f11971ca
...@@ -386,16 +386,16 @@ public class MacroPlannerOptimizer { ...@@ -386,16 +386,16 @@ public class MacroPlannerOptimizer {
printer.printHierarchicalSummary(levels, finalLevelValues); printer.printHierarchicalSummary(levels, finalLevelValues);
// 回写业务对象到JSON文件(预留) // 回写业务对象到JSON文件(预留)
ResultWriter rw = new ResultWriter(model, data, startTimeMs); // ResultWriter rw = new ResultWriter(model, data, startTimeMs);
OptimizationResult optimizationResult = rw.buildResult(); // OptimizationResult optimizationResult = rw.buildResult();
boolean jsonPath = rw.saveResultToFile(sceneId, optimizationResult); // boolean jsonPath = rw.saveResultToFile(sceneId, optimizationResult);
if (jsonPath) { // if (jsonPath) {
writeLog("\n[OK] 优化结果JSON已导出: " + jsonPath); // writeLog("\n[OK] 优化结果JSON已导出: " + jsonPath);
} // }
writeLog("\n=== 分层求解完成 ==="); writeLog("\n=== 分层求解完成 ===");
} else { } else {
......
...@@ -57,36 +57,39 @@ public class MultiLevelBomTestRunner { ...@@ -57,36 +57,39 @@ public class MultiLevelBomTestRunner {
ApplicationContext ctx = SpringApplication.run(ApsApplication.class, args); ApplicationContext ctx = SpringApplication.run(ApsApplication.class, args);
try { 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(); data.init();
writeLog("Data loaded: " + data.getProducts().size() + " products, "
+ data.getOperations().size() + " operations");
long startTime = System.currentTimeMillis();
MacroPlannerOptimizer optimizer = new MacroPlannerOptimizer(data); MacroPlannerOptimizer optimizer = new MacroPlannerOptimizer(data);
optimizer.buildModel(); optimizer.buildModel();
optimizer.solve("bom"); optimizer.solve(String.valueOf(scale));
// MpPispipResultPersistenceService service = // 构建结果并调用 save 入库
// ctx.getBean(MpPispipResultPersistenceService.class); ResultWriter writer = new ResultWriter(optimizer.getModel(), optimizer.getData(), startTime);
// OptimizationResult result = writer.buildResult(String.valueOf(scale));
// int scale = 10000; boolean jsonPath = writer.saveResultToFile(String.valueOf(scale), result);
// BenchmarkDataBuilder data = BenchmarkDataBuilder.forScale(scale);
// writeLog("===== TEST RUNNER START " + scale + "====="); writeLog("PISPIP result saved: ");
// int saved = service.save(String.valueOf(scale), result);
// data.init(); writeLog("PISPIP result saved: " + saved);
// writeLog("Data loaded: " + data.getProducts().size() + " products, "
// + data.getOperations().size() + " operations"); writeLog("===== TEST RUNNER END =====");
//
// 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 =====");
} catch (Exception e) { } catch (Exception e) {
} finally { } finally {
......
...@@ -140,7 +140,7 @@ public class ResultWriter { ...@@ -140,7 +140,7 @@ public class ResultWriter {
} }
public boolean saveResultToFile(String sceneId) { public boolean saveResultToFile(String sceneId) {
OptimizationResult result = buildResult(); OptimizationResult result = buildResult(sceneId);
return saveResultToFile(sceneId,result); return saveResultToFile(sceneId,result);
} }
...@@ -164,20 +164,24 @@ public class ResultWriter { ...@@ -164,20 +164,24 @@ public class ResultWriter {
} }
FlatParquetUtil parquetUtil = new FlatParquetUtil(); FlatParquetUtil parquetUtil = new FlatParquetUtil();
String periodTaskPath = getOptimizationPeriodTask(sceneId); String periodTaskPath = getOptimizationPeriodTask(sceneId);
writeLog("writePeriodTasks"); writeLog("writePeriodTasks"+result.getPeriodTasks().size());
parquetUtil.write(result.getPeriodTasks(), periodTaskPath, PeriodTaskResult.class); parquetUtil.write(result.getPeriodTasks(), periodTaskPath, PeriodTaskResult.class);
writeLog("writePeriodTasks"); writeLog("writePeriodTasks");
writeLog("writePispips"); writeLog("writePispips:"+result.getPispips().size());
String pispiPath = getOptimizationPispip(sceneId); String pispiPath = getOptimizationPispip(sceneId);
parquetUtil.write(result.getPispips(), pispiPath, PispipResult.class); parquetUtil.write(result.getPispips(), pispiPath, PispipResult.class);
writeLog("writePispips");
writeLog("writesalesDemand"); writeLog("writesalesDemand");
String salesDemandPath = getOptimizationSalesDemand(sceneId); String salesDemandPath = getOptimizationSalesDemand(sceneId);
parquetUtil.write(result.getSalesDemands(), salesDemandPath, SalesDemandResult.class); parquetUtil.write(result.getSalesDemands(), salesDemandPath, SalesDemandResult.class);
// List<PispipResult> pispips = parquetUtil.readAll(pispiPath, PispipResult.class);
writeLog("writesalesDemand"); writeLog("writesalesDemand");
writeLog("writesalesDemand"); writeLog("UnitCapacities");
String unitPath = getOptimizationUnitCapacitie(sceneId); String unitPath = getOptimizationUnitCapacitie(sceneId);
parquetUtil.write(result.getUnitCapacities(), unitPath, UnitCapacityResult.class); parquetUtil.write(result.getUnitCapacities(), unitPath, UnitCapacityResult.class);
writeLog("writesalesDemand"); writeLog("UnitCapacities");
// BOM 结构持久化 (供 getProductNetwork 按需组装) // BOM 结构持久化 (供 getProductNetwork 按需组装)
writeLog("writeBomStructure"); writeLog("writeBomStructure");
...@@ -186,58 +190,59 @@ public class ResultWriter { ...@@ -186,58 +190,59 @@ public class ResultWriter {
writeLog("writeOperationDemands"); writeLog("writeOperationDemands");
List<OperationDemandResult> opDemands = buildOperationDemandResults(); List<OperationDemandResult> opDemands = buildOperationDemandResults();
parquetUtil.write(opDemands, getOptimizationOperationDemand(sceneId), OperationDemandResult.class); 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; return true;
} catch (Exception e) { // try {
logger.error("保存文件失败,场景ID: " + sceneId, e); //
return false; // 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) { } catch (IOException ex) {
logger.error("保存文件失败,场景ID: " + sceneId, ex); logger.error("保存文件失败,场景ID: " + sceneId, ex);
return false; return false;
...@@ -440,9 +445,7 @@ public class ResultWriter { ...@@ -440,9 +445,7 @@ public class ResultWriter {
/** /**
* 收集所有结果并返回 JSON 字符串。 * 收集所有结果并返回 JSON 字符串。
*/ */
public String toJsonString() {
return toJson(buildResult());
}
private static final String LOG_DIR = "mp"; private static final String LOG_DIR = "mp";
/** LP 模型文件路径 */ /** LP 模型文件路径 */
...@@ -454,9 +457,13 @@ public class ResultWriter { ...@@ -454,9 +457,13 @@ public class ResultWriter {
{ {
FileHelper.writeFile(msg,LOG_FILE_PATH,"log.txt"); 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 ==================== // ==================== 构建 OptimizationResult ====================
public OptimizationResult buildResult() { public OptimizationResult buildResult(String sceneId) {
OptimizationResult result = new OptimizationResult(); OptimizationResult result = new OptimizationResult();
// 元数据 // 元数据
...@@ -467,7 +474,7 @@ public class ResultWriter { ...@@ -467,7 +474,7 @@ public class ResultWriter {
// 业务结果 // 业务结果
writeLog("PeriodTasks"); writeLog("PeriodTasks");
buildPeriodTasks(result); buildPeriodTasks(sceneId,result);
writeLog("SalesDemands"); writeLog("SalesDemands");
buildSalesDemands(result); buildSalesDemands(result);
writeLog("Pispips"); writeLog("Pispips");
...@@ -487,7 +494,7 @@ public class ResultWriter { ...@@ -487,7 +494,7 @@ public class ResultWriter {
// ==================== PeriodTaskResult ==================== // ==================== PeriodTaskResult ====================
private void buildPeriodTasks(OptimizationResult result) { private void buildPeriodTasks(String sceneId,OptimizationResult result) {
for (Operation op : data.getOperations()) { for (Operation op : data.getOperations()) {
for (UnitOperation uo : op.getUnitOperations()) { for (UnitOperation uo : op.getUnitOperations()) {
for (Period p : data.getPeriods()) { for (Period p : data.getPeriods()) {
......
...@@ -38,9 +38,9 @@ public class MpPispipResultPersistenceService { ...@@ -38,9 +38,9 @@ public class MpPispipResultPersistenceService {
Map<Object,String> detailIds = new IdentityHashMap<>(); Map<Object,String> detailIds = new IdentityHashMap<>();
int saved = batch.executeInTransaction(c -> { int saved = batch.executeInTransaction(c -> {
batch.batchInsert(c, parent, result.getPispips(), BATCH_SIZE, (s,p) -> bindParent(s,p,sceneId,ids)); 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); } // 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, 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); }); // 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(); return ids.size();
}); });
log.info("Saved PISPIP result: sceneId={}, parents={}, productions={}, boms={}",sceneId,ids.size(),details.size(),boms.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