*
lsh
2025-08-19 6b787523118e4f25de403d38691a1060960ffbad
*
1个文件已添加
1个文件已修改
212 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/utils/SchedulingCarUtil.java 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/utils/SchedulingCarUtil.java
New file
@@ -0,0 +1,208 @@
package com.zy.asrs.utils;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import lombok.Data;
public class SchedulingCarUtil {
    private static final Map<Integer, Double> STATION_PRIORITIES =
            Collections.unmodifiableMap(new HashMap<Integer, Double>() {{
                put(5101, 0.8);
                put(5120, 0.9);
                // ...
            }});
    private static final Map<String, Double> AREA_WEIGHTS =
            Collections.unmodifiableMap(new HashMap<String, Double>() {{
                put("A", 1.2);
                put("B", 1.0);
                put("C", 0.8);
                // ...
            }});
    // 常量配置
    private static final double WAIT_THRESHOLD = 120.0; // 等待临界点(秒)
    private static final double MAX_DISTANCE = 1000.0;  // 轨道最大长度
    private static final double DIST_PENALTY = -0.5;     // 最低距离系数
    // 新增线性增长阈值和系数
    private static final double LINEAR_THRESHOLD = 300.0; // 线性增长起点(秒)
    private static final double LINEAR_FACTOR = 0.0083;    // 线性增长系数(≈0.5/60)
    private static final double LOAD_THRESHOLD = 0.7;
    private static final double ADJUSTMENT_STEP = 0.01;
    // 权重参数 (可动态调整)
    private double baseWeight = 0.40;
    private double waitWeight = 0.35;
    private double distWeight = 0.25;
    private static final double[] EXP_CACHE = new double[1800]; // 缓存0~1800秒(30分钟)
    static {
        for (int i = 0; i < EXP_CACHE.length; i++) {
            EXP_CACHE[i] = 0.8 * (1 - Math.exp(-0.02 * i));
        }
    }
    // 预计算常量
    private static final double EXP_BASE = 0.5;
    private static final double EXP_FACTOR = 3.0;
    private static class Weights {
        double base = 0.40, wait = 0.35, dist = 0.25;
    }
    private final AtomicReference<Weights> weightsRef = new AtomicReference<>(new Weights());
//    // 复用对象(线程安全)
//    private final ThreadLocal<Double> distanceCache = ThreadLocal.withInitial(() -> 0.0);
    /**
     * 计算任务综合优先级
     * @param task 当前任务对象
     * @param agv  当前小车对象
     * @return 综合优先级得分(0.0 - 1.0 ~ ∞)
     */
    public double calculatePriority(Task task, AGV agv) {
        // 1. 站点基础优先级计算
        double stationPriority = calculateStationPriority(task.getStationId());
        // 2. 任务等待时间优先级
        double waitPriority = calculateWaitPriority(task.getWaitSeconds());
        // 3. 小车距离优先级
        double distancePriority = calculateDistancePriority(
                agv.getPosition(),
                task.getTargetPosition()
        );
        applyDynamicWeightAdjustment();
        return (stationPriority * baseWeight)
                + (waitPriority * waitWeight)
                + (distancePriority * distWeight);
    }
    private void applyDynamicWeightAdjustment() {
        Weights current = weightsRef.get();
        Weights updated = new Weights();
        double loadFactor = SystemMonitor.getLoadFactor();
        if (loadFactor > LOAD_THRESHOLD) {
            waitWeight = Math.min(0.55, waitWeight + ADJUSTMENT_STEP);
            distWeight = Math.max(0.10, distWeight - ADJUSTMENT_STEP/2);
        } else if (loadFactor < LOAD_THRESHOLD - 0.05) {
            // 负载降低时逐步恢复权重
            waitWeight = Math.max(0.35, waitWeight - ADJUSTMENT_STEP);
            distWeight = Math.min(0.25, distWeight + ADJUSTMENT_STEP/2);
        }
        weightsRef.compareAndSet(current, updated); // CAS更新
    }
    /**
     * 站点基础优先级(固定值+区域权重)
     */
    private double calculateStationPriority(int stationId) {
        double basePriority = STATION_PRIORITIES.getOrDefault(stationId, 0.5);
        String area = "A";
        return basePriority * AREA_WEIGHTS.getOrDefault(area, 1.0);
    }
    /**
     * 等待时间优先级(非线性增长)
     */
    private double calculateWaitPriority(double waitSeconds) {
//        if (waitSeconds <= WAIT_THRESHOLD) {
//            return 0.2; // 基础值
//        }
//        // 等待超时后的指数增长(无峰值上限)
//        return Math.min(1.0, 0.2 + 0.8 * (1 - Math.exp(-0.02*(waitSeconds-WAIT_THRESHOLD))));
        if (waitSeconds <= WAIT_THRESHOLD) {
            return 0.2; // 基础值
        }
        double exceedSeconds = waitSeconds - WAIT_THRESHOLD;
        double expPart = (exceedSeconds < EXP_CACHE.length) ?
                EXP_CACHE[(int) exceedSeconds] :
                0.8 * (1 - Math.exp(-0.02 * exceedSeconds));
//        double exceedSeconds = waitSeconds - WAIT_THRESHOLD;
//        // 指数增长阶段(0~300秒)
//        double expPart = 0.8 * (1 - Math.exp(-0.02 * exceedSeconds));
        // 线性增长阶段(300秒后)
        double linearPart = (exceedSeconds > LINEAR_THRESHOLD) ?
                LINEAR_FACTOR * (exceedSeconds - LINEAR_THRESHOLD) : 0;
        return 0.2 + expPart + linearPart; // 突破1.0上限
    }
    /**
     * 小车距离优先级(含负向调节)
     */
    private double calculateDistancePriority(double agvPos, double stationPos) {
        // 计算轨道有效距离(考虑单向移动)
        double distance = calculateEffectiveDistance(agvPos, stationPos);
//
//        double distance = distanceCache.get();
//        if (distance == 0.0) { // 0表示未计算
//            distance = calculateEffectiveDistance(agvPos, stationPos);
//            distanceCache.set(distance);
//        }
        // 非线性衰减公式(近距离奖励,远距离惩罚)
        double ratio = distance / MAX_DISTANCE;
//        return Math.max(DIST_PENALTY, 0.5 * (Math.pow(0.5, ratio * 3) - 0.5));
        double exponentValue = Math.pow(EXP_BASE, ratio * EXP_FACTOR);
        return Math.max(DIST_PENALTY, 0.5 * (exponentValue - 0.5));
    }
    /**
     * 计算有效距离(单方向轨道逻辑)
     */
    private double calculateEffectiveDistance(double agvPos, double stationPos) {
        // 单向轨道场景:若小车已过站点,需绕行至终点再返回起点
//        if (agvPos > stationPos) {
//            return (MAX_DISTANCE - agvPos) + stationPos;
//        }
//        return stationPos - agvPos;
        return (stationPos - agvPos + MAX_DISTANCE) % MAX_DISTANCE;
    }
}
@Data
class Task {
    private int taskId;
    private int stationId;
    private double targetPosition;
    private long createTime; // 任务创建时间戳
    private static final long THIRTY_DAYS_MS = 30L * 24 * 60 * 60 * 1000;
    public double getWaitSeconds() {
        long elapsed = (System.currentTimeMillis() - createTime) ;
        // 固定为30天
        return (elapsed > THIRTY_DAYS_MS) ? (THIRTY_DAYS_MS / 1000.0) : (elapsed / 1000.0);
    }
}
@Data
class AGV {
    private int agvId;
    private double position; // 当前轨道位置(0-MAX_DISTANCE)
}
// 系统监控类(示例)
@Data
class SystemMonitor {
    public static double getLoadFactor() {
        // 实际实现中读取系统负载率
        return 0.1;
//        return LoadHolder.cachedLoad; // 定时更新,非实时读取
    }
//    private static class LoadHolder {
//        static double cachedLoad = 0.1;
//        static { ScheduledExecutorService.scheduleAtFixedRate(() ->
//                cachedLoad = realTimeLoad(), 5, 5, TimeUnit.SECONDS); }
//    }
}
src/main/resources/application.yml
@@ -8,8 +8,8 @@
    name: @pom.build.finalName@
  datasource:
    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    url: jdbc:sqlserver://127.0.0.1:50751;databasename=gdhmasrs
#    url: jdbc:sqlserver://127.0.0.1:50948;databasename=gdhmasrs
#    url: jdbc:sqlserver://127.0.0.1:50751;databasename=gdhmasrs
    url: jdbc:sqlserver://127.0.0.1:50948;databasename=gdhmasrs
    username: sa
    password: sa@123
  mvc: