Commit 27a394e0 authored by Tong Li's avatar Tong Li

or_tools

parent aed82397
......@@ -111,6 +111,12 @@
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
<!-- OR-Tools CP-SAT 约束规划求解器 -->
<dependency>
<groupId>com.google.ortools</groupId>
<artifactId>ortools-java</artifactId>
<version>9.7.2996</version>
</dependency>
</dependencies>
<build>
......
......@@ -74,6 +74,13 @@ public class ScheduleParams {
return populationSize;
}
/// <summary>
/// 种群规模
/// </summary>
public void setPopulationSize(int populationSize) {
populationSize=populationSize;
}
/// <summary>
/// 最大迭代次数
/// </summary>
......
......@@ -64,6 +64,11 @@ public class Entry {
*/
private String mainId;
/**
* 拆分来源ID:当state=1时,记录原始工序的id,用于识别同一原始工序的拆分子工序
*/
private transient Integer splitSourceId;
/**
* 离散参数
*/
......
This diff is collapsed.
This diff is collapsed.
......@@ -597,7 +597,7 @@ public class GeneticDecoder {
//存储锚点时间
if(isJit)
{
orderSchedulingInfo.put(order.getId(), new AbstractMap.SimpleEntry<>(false, end));
orderSchedulingInfo.put(order.getId(), new AbstractMap.SimpleEntry<>(true, end));
}else {
orderSchedulingInfo.put(order.getId(), new AbstractMap.SimpleEntry<>(false, 0));
......
......@@ -117,7 +117,9 @@ public class HybridAlgorithm {
// 步骤1:使用构造启发式算法生成初始种群
FileHelper.writeLogFile("构造启发式初始化-----------开始-------");
List<Chromosome> population = initialization.generateHeuristicInitialPopulation(param);
// List<Chromosome> population = initialization.generateHeuristicInitialPopulation(param);
List<Chromosome> population = initialization.generateHybridInitialPopulation(param);
FileHelper.writeLogFile("构造启发式初始化-----------结束-------");
......
package com.aps.service.Algorithm;
import com.aps.common.util.FileHelper;
import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.Chromosome;
import com.aps.entity.Algorithm.GlobalOperationInfo;
......@@ -1069,6 +1070,167 @@ public class Initialization {
return shuffled;
}
/**
* HybridAlgorithm 专用混合初始种群
* 先用 CP-SAT 生成高质量种子,剩余用原有构造启发式补足
*/
public List<Chromosome> generateHybridInitialPopulation(ScheduleParams param) {
int populationSize = param.getPopulationSize();
this.baseTime = param.getBaseTime();
List<GlobalOperationInfo> sharedGlobalOpList = generateGlobalOpList();
List<Chromosome> population = new ArrayList<>(populationSize);
int cpSatTarget = Math.min(Math.max(populationSize / 5, 2), 6);
int timeBudgetSec = Math.max(populationSize * 2, 15);
CpSatInitializer cpSatInit = new CpSatInitializer(
allOperations, machines, orders, param.getBaseTime());
List<Chromosome> cpSatResults = cpSatInit.generate(
sharedGlobalOpList, cpSatTarget, timeBudgetSec);
if (!cpSatResults.isEmpty()) {
for (Chromosome chromo : cpSatResults) {
chromo.setOrders(new CopyOnWriteArrayList<>(orders));
chromo.setGlobalOpList(deepCopyGlobalOpList(sharedGlobalOpList));
PriorityCheckResult r = Initialization.checkPriorityOrder(chromo);
// if (r.isPerfect()) {
// population.add(chromo);
//
// }
}
population.addAll(cpSatResults);
FileHelper.writeLogFile(
"[Hybrid初始化] CP-SAT贡献 " + cpSatResults.size() + " 个高质量种子");
}
int remaining = populationSize - population.size();
if (remaining > 0) {
ScheduleParams subParam = new ScheduleParams();
subParam.setPopulationSize(remaining);
subParam.setBaseTime(param.getBaseTime());
List<Chromosome> heuristicPopulation =
generateHeuristicInitialPopulation(subParam);
for (Chromosome chromo : heuristicPopulation) {
chromo.setOrders(new CopyOnWriteArrayList<>(orders));
}
population.addAll(heuristicPopulation);
}
long cpSatCount = population.stream()
.filter(c -> c.getGsOrls() == 4).count();
FileHelper.writeLogFile(String.format(
"[Hybrid初始化] 总种群=%d, CP-SAT=%d, 启发式=%d",
population.size(), cpSatCount,
population.size() - cpSatCount));
return population;
}
private List<GlobalOperationInfo> deepCopyGlobalOpList(
List<GlobalOperationInfo> source) {
List<GlobalOperationInfo> copy = new ArrayList<>(source.size());
for (GlobalOperationInfo info : source) {
GlobalOperationInfo newInfo = new GlobalOperationInfo();
newInfo.setGlobalOpId(info.getGlobalOpId());
newInfo.setGroupId(info.getGroupId());
newInfo.setSequence(info.getSequence());
newInfo.setOp(info.getOp());
copy.add(newInfo);
}
return copy;
}
/**
* 检查染色体的operationSequencing是否遵守Priority排序
* Priority值越小优先级越高(1最先排,99最后排)
*
* @param chromo 待检查的染色体
* @return PriorityCheckResult 包含违反次数、严重度、详细报告
*/
public static PriorityCheckResult checkPriorityOrder(Chromosome chromo) {
List<GlobalOperationInfo> globalOpList = chromo.getGlobalOpList();
List<Integer> os = chromo.getOperationSequencing();
if (os == null || os.isEmpty() || globalOpList == null || globalOpList.isEmpty()) {
return new PriorityCheckResult(0, 0, 0, "无数据");
}
Map<Integer, Double> groupPriority = new HashMap<>();
Map<Integer, List<Entry>> groupOps = new HashMap<>();
for (GlobalOperationInfo info : globalOpList) {
int gid = info.getGroupId();
groupPriority.putIfAbsent(gid, info.getOp().getPriority());
groupOps.computeIfAbsent(gid, k -> new ArrayList<>()).add(info.getOp());
}
int violationCount = 0;
int totalSeverity = 0;
double maxSingleSeverity = 0;
StringBuilder detail = new StringBuilder();
for (int i = 0; i < os.size() - 1; i++) {
int gidA = os.get(i);
int gidB = os.get(i + 1);
if (gidA == gidB) continue;
double priA = groupPriority.getOrDefault(gidA, Double.MAX_VALUE);
double priB = groupPriority.getOrDefault(gidB, Double.MAX_VALUE);
if (priA > priB) {
double severity = priA - priB;
violationCount++;
totalSeverity += severity;
maxSingleSeverity = Math.max(maxSingleSeverity, severity);
if (detail.length() < 800) {
detail.append(String.format(
" [%d→%d] groupId=%d(优先级%d) 排在 groupId=%d(优先级%d) 之前,差距=%d\n",
i, i + 1, gidA, priA, gidB, priB, severity));
}
}
}
String report = String.format(
"Priority检查: 违反次数=%d, 总严重度=%d, 最大单次差距=%f, " +
"工序组数=%d, 不同优先级组数=%d\n%s",
violationCount, totalSeverity, maxSingleSeverity,
groupPriority.size(), new HashSet<>(groupPriority.values()).size(),
detail.toString());
return new PriorityCheckResult(violationCount, totalSeverity,
maxSingleSeverity, report);
}
/**
* Priority检查结果
*/
public static class PriorityCheckResult {
public final int violationCount;
public final int totalSeverity;
public final double maxSingleSeverity;
public final String report;
PriorityCheckResult(int violationCount, int totalSeverity,
double maxSingleSeverity, String report) {
this.violationCount = violationCount;
this.totalSeverity = totalSeverity;
this.maxSingleSeverity = maxSingleSeverity;
this.report = report;
}
public boolean isPerfect() {
return violationCount == 0;
}
@Override
public String toString() {
return report;
}
}
/**
* 辅助类:用于权重排序
*/
......
......@@ -409,6 +409,7 @@ if(entry.getMachineOptions()!=null)
if (machine.getCapacityTypeName() == null) {
machine.setCapacityTypeName(equipinfo.getCapacityTypeName());
}
}else {
machine.setCode(PlanResource.getReferenceCode());
machine.setName(PlanResource.getTitle());
......
......@@ -184,7 +184,7 @@ public class PlanResultService {
try {
ScheduleParams param = InitScheduleParams();
// param.setBaseTime(LocalDateTime.of(2026, 1, 1, 0, 0, 0));
this.baseTime=param.getBaseTime();
// 策略读取入口:优先使用前端传入的 userId;没传时用 sceneId 查场景创建人。
Long effectiveUserId = scheduleStrategyService.resolveScheduleUserId(SceneId, userId);
......@@ -2106,7 +2106,7 @@ if(job.getGeneDetails()!=null)
ApsTimeConfig apsTimeConfig= apsTimeConfigMapper.selectOne( queryWrapper);
ScheduleParams param = new ScheduleParams();
param.setBaseTime(LocalDateTime.of(2025, 11, 1, 0, 0, 0));
param.setBaseTime(LocalDateTime.of(2026, 1, 1, 0, 0, 0));
if(apsTimeConfig!=null) {
if(apsTimeConfig.getBaseTime()!=null)
{
......
......@@ -41,8 +41,7 @@ public class PlanResultServiceTest {
// sortService.test1();
// nsgaiiUtils.Test();
// planResultService.execute2("64E64F6B68094AF38CEDC418630C3CC2");//2000
planResultService.execute2("5C93A528725F40228889FCFC1E040B55");//2000
planResultService.execute2("72744D094BAB45948F5172E84C78B260");//2000
// planResultService.execute2("15210B13B88A453F8B84AAC7F16C7541");//2000
......
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