*
lsh
2025-10-22 41e4860f065a13b00441deff45455b62d3787e2c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
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); }
//    }
}