概率论是深度学习(Deep Learning, DL)和深度强化学习(Deep Reinforcement Learning, DRL)的核心数学基础之一,尤其在建模不确定性、优化模型和决策过程中扮演
E喧嚣E[Makespan]=∑P(state)⋅Makespan(state)E喧嚣 E[\text{Makespan}] = \sum P(\text{state}) \cdot \text{Makespan(state)}P(故障∣状态)=P(状态∣故障)P(故障)P(状态)P(\text{故障}|\text{状态}) = \frac{P(\text{状态}|\text{故障})P(\tex
概率论是深度学习(Deep Learning, DL)和深度强化学习(Deep Reinforcement Learning, DRL)的核心数学基础之一,尤其在建模不确定性、优化模型和决策过程中扮演关键角色。本文将从概率论的基础概念出发,结合图解和动态车间调度(Job Shop Scheduling, JSS)的DRL场景,详细解析概率在深度学习中的应用,涵盖概率分布、期望、贝叶斯定理、蒙特卡洛方法等核心概念,并提供基于TensorFlow.NET的C#代码示例,展示如何在DRL中利用概率方法优化调度决策。代码将包含清晰的中文注释,并优化为更简洁易读的结构。
1. 概率论基础概念与图解
1.1 概率与随机变量
-
定义:
-
概率:事件发生的可能性,范围为 ([0, 1])。
-
随机变量:描述随机事件结果的变量,分为离散型(如动作选择)和连续型(如状态值)。
-
数学表示:
- 离散随机变量 ( X ),概率质量函数(PMF):
P(X=x)P(X = x)
。P(X = x) - 连续随机变量 ( X ),概率密度函数(PDF):
fX(x)f_X(x)
,概率为f_X(x)P(a≤X≤b)=∫abfX(x) dxP(a \leq X \leq b) = \int_a^b f_X(x) \, dx
.P(a \leq X \leq b) = \int_a^b f_X(x) \, dx
- 离散随机变量 ( X ),概率质量函数(PMF):
-
-
图解:
离散:P(X = 1) = 0.4, P(X = 2) = 0.6 [图:柱状图,X=1 和 X=2 的概率] 连续:f(x) = N(0, 1)(标准正态分布) [图:正态分布曲线,x轴为值,y轴为密度] -
深度学习中的作用:
-
建模数据分布(如图像像素值)。
-
DRL中,状态转移概率 ( P(s'|s, a) ) 描述环境动态。
-
-
车间调度示例:
-
动作选择:离散随机变量 ( A ),表示选择某个工序的概率。
-
状态:连续随机变量 ( S ),如机器可用时间。
-
1.2 概率分布
-
常见分布:
- 伯努利分布:二元事件(如选择/不选择某工序),
P(X=1)=pP(X=1) = p
,P(X=1) = pP(X=0)=1−pP(X=0) = 1-p
。P(X=0) = 1-p - 多项式分布:多类别事件(如选择多个工序),
P(X1,…,Xk)=n!x1!…xk!p1x1…pkxkP(X_1, \dots, X_k) = \frac{n!}{x_1!\dots x_k!} p_1^{x_1} \dots p_k^{x_k}
.P(X_1, \dots, X_k) = \frac{n!}{x_1!\dots x_k!} p_1^{x_1} \dots p_k^{x_k} - 正态分布:连续变量,
f(x)=12πσ2e−(x−μ)22σ2f(x) = \frac{1}{\sqrt{2\pi\sigma^2}} e^{-\frac{(x-\mu)^2}{2\sigma^2}}
.f(x) = \frac{1}{\sqrt{2\pi\sigma^2}} e^{-\frac{(x-\mu)^2}{2\sigma^2}}
- 伯努利分布:二元事件(如选择/不选择某工序),
-
深度学习中的作用:
-
分类任务:Softmax输出概率分布(如动作选择概率)。
-
噪声建模:正态分布用于权重初始化或数据增强。
-
-
车间调度示例:
- 动作选择概率:Softmax输出
P(ai∣s)=eQ(s,ai)∑jeQ(s,aj)P(a_i|s) = \frac{e^{Q(s, a_i)}}{\sum_j e^{Q(s, a_j)}}
.P(a_i|s) = \frac{e^{Q(s, a_i)}}{\sum_j e^{Q(s, a_j)}} -
图解:
Q(s, a) = [2.1, 1.5, 0.8] Softmax:P(a|s) = [0.58, 0.32, 0.10] [图:Softmax概率分布柱状图]
- 动作选择概率:Softmax输出
1.3 期望(Expectation)
-
定义:
-
期望是随机变量的加权平均,衡量其“平均”结果。
-
数学表示:
- 离散:
E[X]=∑xxP(X=x)E[X] = \sum_x x P(X=x)
.E[X] = \sum_x x P(X=x) - 连续:
E[X]=∫xfX(x) dxE[X] = \int x f_X(x) \, dx
.E[X] = \int x f_X(x) \, dx
- 离散:
-
-
深度学习中的作用:
- 损失函数:期望损失
E[L(θ)]E[L(\theta)]
用于优化模型。E[L(\theta)] - DRL:Q值
Q(s,a)=E[Rt+γmaxa′Q(s′,a′)]Q(s, a) = E[R_t + \gamma \max_{a'} Q(s', a')]
,表示期望累积奖励。Q(s, a) = E[R_t + \gamma \max_{a'} Q(s', a')]
- 损失函数:期望损失
-
车间调度示例:
- 期望Makespan:
E喧嚣E[Makespan]=∑P(state)⋅Makespan(state)E喧嚣 E[\text{Makespan}] = \sum P(\text{state}) \cdot \text{Makespan(state)}
.E喧嚣 E[\text{Makespan}] = \sum P(\text{state}) \cdot \text{Makespan(state)} -
图解:
状态 s1, s2, s3 Makespan = [10, 12, 15] P(s) = [0.5, 0.3, 0.2] E[Makespan] = 10*0.5 + 12*0.3 + 15*0.2 = 11.6 [图:期望值计算]
- 期望Makespan:
1.4 贝叶斯定理
-
定义:
- 描述条件概率:
P(A∣B)=P(B∣A)P(A)P(B)P(A|B) = \frac{P(B|A)P(A)}{P(B)}
.P(A|B) = \frac{P(B|A)P(A)}{P(B)}
- 描述条件概率:
-
深度学习中的作用:
-
贝叶斯网络:建模参数的不确定性。
-
变分自编码器(VAE):推断潜在变量分布 ( P(z|x) ).
-
-
车间调度示例:
- 推断机器故障概率:
P(故障∣状态)=P(状态∣故障)P(故障)P(状态)P(\text{故障}|\text{状态}) = \frac{P(\text{状态}|\text{故障})P(\text{故障})}{P(\text{状态})}
.P(\text{故障}|\text{状态}) = \frac{P(\text{状态}|\text{故障})P(\text{故障})}{P(\text{状态})} -
图解:
P(故障|高温) = P(高温|故障) * P(故障) / P(高温) [图:贝叶斯公式条件概率]
- 推断机器故障概率:
1.5 蒙特卡洛方法
-
定义:
-
通过随机抽样估计期望或积分。
- 数学表示:
E[f(X)]≈1N∑i=1Nf(xi)E[f(X)] \approx \frac{1}{N} \sum_{i=1}^N f(x_i)
,其中E[f(X)] \approx \frac{1}{N} \sum_{i=1}^N f(x_i)xi∼P(X)x_i \sim P(X)
.x_i \sim P(X)
-
-
深度学习中的作用:
-
经验回放:DRL中通过采样经验估计Q值。
-
蒙特卡洛 dropout:通过多次前向传播估计模型不确定性。
-
-
车间调度示例:
- 估计平均Makespan:通过多次模拟调度策略,计算
Avg Makespan=1N∑Makespani\text{Avg Makespan} = \frac{1}{N} \sum \text{Makespan}_i
.\text{Avg Makespan} = \frac{1}{N} \sum \text{Makespan}_i -
图解:
模拟 N 次调度 Makespan = [11, 12, 10, 13, ...] E[Makespan] ≈ 平均值 [图:蒙特卡洛采样]
- 估计平均Makespan:通过多次模拟调度策略,计算
2. 概率在深度学习与DRL中的应用
2.1 概率分布与Softmax
-
Softmax函数:
-
将Q值转换为概率分布:
P(ai∣s)=eQ(s,ai)∑jeQ(s,aj)P(a_i|s) = \frac{e^{Q(s, a_i)}}{\sum_j e^{Q(s, a_j)}}
P(a_i|s) = \frac{e^{Q(s, a_i)}}{\sum_j e^{Q(s, a_j)}} -
用于动作选择(如ε-贪婪策略中的概率采样)。
-
-
车间调度示例:
- Q值
Q(s,a)=[2.1,1.5,0.8]Q(s, a) = [2.1, 1.5, 0.8]
,Softmax输出动作概率:Q(s, a) = [2.1, 1.5, 0.8]P(a∣s)=[0.58,0.32,0.10]P(a|s) = [0.58, 0.32, 0.10]
P(a|s) = [0.58, 0.32, 0.10] -
图解:
Q值 -> Softmax -> 概率分布 [图:Q值到概率的转换]
- Q值
2.2 期望与Q值
-
Q值:
-
Q值是累积奖励的期望:
Q(s,a)=E[Rt+γRt+1+γ2Rt+2+…∣s,a]Q(s, a) = E[R_t + \gamma R_{t+1} + \gamma^2 R_{t+2} + \dots | s, a]
Q(s, a) = E[R_t + \gamma R_{t+1} + \gamma^2 R_{t+2} + \dots | s, a] - DQN通过神经网络近似
Q(s,a;θ)Q(s, a; \theta)
.Q(s, a; \theta)
-
-
车间调度示例:
- 期望奖励:
E[R]=∑P(s′,r∣s,a)⋅rE[R] = \sum P(s', r|s, a) \cdot r
,奖励为负的Makespan增量。E[R] = \sum P(s', r|s, a) \cdot r -
图解:
s -> a -> (s', r) Q(s, a) = E[R + γ max Q(s', a')] [图:期望奖励计算]
- 期望奖励:
2.3 蒙特卡洛与经验,回放
-
经验回放:
-
存储经验 ( (s, a, r, s') ),随机抽样估计Q值。
-
蒙特卡洛方法:通过多次采样逼近期望Q值。
-
-
车间调度示例:
-
抽样32条经验,计算目标Q值:
target=r+γmaxa′Q(s′,a′;θ′)\text{target} = r + \gamma \max_{a'} Q(s', a'; \theta')
\text{target} = r + \gamma \max_{a'} Q(s', a'; \theta') -
图解:
经验池:[(s1, a1, r1, s1'), (s2, a2, r2, s2'), ...] 随机抽样 -> 目标Q值 [图:经验回放采样]
-
2.4 贝叶斯方法
-
变分推断:
- 近似后验分布
P(θ∣D)≈q(θ)P(\theta|D) \approx q(\theta)
,优化模型参数。P(\theta|D) \approx q(\theta)
- 近似后验分布
-
车间调度示例:
- 推断机器状态的概率分布:
P(可用∣历史数据)P(\text{可用}|\text{历史数据})
.P(\text{可用}|\text{历史数据}) -
图解:
P(可用|数据) = P(数据|可用) * P(可用) / P(数据) [图:贝叶斯推断]
- 推断机器状态的概率分布:
3. C#代码示例:基于TensorFlow.NET的DQN与概率方法
以下代码实现DQN优化动态车间调度问题,使用Softmax概率分布进行动作选择,结合经验回放和目标网络,利用蒙特卡洛方法估计Q值。代码包含清晰的中文注释,结构简洁。
3.1 代码
csharp
using System;
using System.Collections.Generic;
using System.Linq;
using Tensorflow;
using NumSharp;
using static Tensorflow.Binding;
namespace DynamicDQNScheduler
{
/// <summary>
/// 动态车间调度器,使用DQN优化调度,目标是最小化Makespan。
/// 概率方法:Softmax动作选择,蒙特卡洛经验回放,目标网络稳定训练。
/// </summary>
class DynamicDQNScheduler
{
/// <summary>
/// 工序类,表示作业的一个工序。
/// </summary>
public class Operation
{
public int JobId { get; set; } // 作业ID
public int MachineId { get; set; } // 机器ID
public int Duration { get; set; } // 加工时间
}
/// <summary>
/// 作业类,表示一个作业。
/// </summary>
public class Job
{
public int Id { get; set; } // 作业ID
public List<Operation> Operations { get; set; } = new List<Operation>(); // 工序列表
public int ArrivalTime { get; set; } // 到达时间
}
/// <summary>
/// 经验类,用于经验回放。
/// </summary>
public class Experience
{
public float[] State { get; set; } // 当前状态
public int Action { get; set; } // 动作索引
public float Reward { get; set; } // 奖励
public float[] NextState { get; set; } // 下一状态
public bool Done { get; set; } // 是否完成
}
// 成员变量
private readonly List<Job> jobs; // 作业列表
private readonly int machineCount; // 机器数量
private List<int> machineAvailableTime; // 机器可用时间
private List<int> jobNextOperation; // 作业当前工序索引
private List<int> jobLastEndTime; // 作业最后完工时间
private readonly Random rand = new Random(); // 随机数生成器
private readonly List<Experience> replayBuffer = new List<Experience>(); // 经验回放缓冲区
private float epsilon = 0.5f; // ε-贪婪探索率
private readonly float epsilonDecay = 0.995f; // ε衰减率
private readonly float gamma = 0.9f; // 折扣因子
private readonly Graph graph = new Graph().as_default(); // TensorFlow计算图
private readonly Session session; // TensorFlow会话
private Operation trainOp; // 训练操作
private Tensor stateInput; // 状态输入
private Tensor qValues; // 主网络Q值
private Tensor targetQ; // 目标Q值
private Tensor targetQValues; // 目标网络Q值
private readonly int maxActions = 10; // 最大动作数量
private readonly int targetUpdateFreq = 10; // 目标网络更新频率
/// <summary>
/// 构造函数,初始化调度器和神经网络。
/// </summary>
/// <param name="jobs">作业列表</param>
/// <param name="machineCount">机器数量</param>
public DynamicDQNScheduler(List<Job> jobs, int machineCount)
{
this.jobs = jobs;
this.machineCount = machineCount;
this.machineAvailableTime = new List<int>(new int[machineCount]);
this.jobNextOperation = new List<int>(new int[jobs.Count]);
this.jobLastEndTime = new List<int>(new int[jobs.Count]);
InitializeNeuralNetwork();
session = tf.Session();
session.run(tf.global_variables_initializer());
}
/// <summary>
/// 初始化主网络和目标网络。
/// 数学背景:
/// - 主网络:Q(s, a; θ) = W2 * ReLU(W1 * s + b1) + b2
/// - 目标网络:Q(s', a'; θ') = tw2 * ReLU(tw1 * s' + tb1) + tb2
/// - 损失:L(θ) = E[(r + γ max Q(s', a'; θ') - Q(s, a; θ))²]
/// - Softmax:P(a|s) = exp(Q(s, a)) / Σ exp(Q(s, a'))
/// </summary>
private void InitializeNeuralNetwork()
{
tf_with(graph, g =>
{
int stateSize = 1 + machineCount + jobs.Count; // 状态维度
stateInput = tf.placeholder(tf.float32, shape: new Shape(-1, stateSize), name: "state");
// 主网络
var w1 = tf.get_variable("w1", shape: new Shape(stateSize, 64), initializer: tf.random_normal_initializer());
var b1 = tf.get_variable("b1", shape: new Shape(64), initializer: tf.zeros_initializer());
var h1 = tf.nn.relu(tf.matmul(stateInput, w1) + b1);
var w2 = tf.get_variable("w2", shape: new Shape(64, maxActions), initializer: tf.random_normal_initializer());
var b2 = tf.get_variable("b2", shape: new Shape(maxActions), initializer: tf.zeros_initializer());
qValues = tf.matmul(h1, w2) + b2;
// 目标网络
var tw1 = tf.get_variable("tw1", shape: new Shape(stateSize, 64), initializer: tf.random_normal_initializer());
var tb1 = tf.get_variable("tb1", shape: new Shape(64), initializer: tf.zeros_initializer());
var th1 = tf.nn.relu(tf.matmul(stateInput, tw1) + tb1);
var tw2 = tf.get_variable("tw2", shape: new Shape(64, maxActions), initializer: tf.random_normal_initializer());
var tb2 = tf.get_variable("tb2", shape: new Shape(maxActions), initializer: tf.zeros_initializer());
targetQValues = tf.matmul(th1, tw2) + tb2;
// 损失函数
targetQ = tf.placeholder(tf.float32, shape: new Shape(-1, maxActions), name: "targetQ");
var loss = tf.reduce_mean(tf.square(targetQ - qValues));
trainOp = tf.train.AdamOptimizer(0.001f).minimize(loss);
});
}
/// <summary>
/// 更新目标网络参数:θ' ← θ。
/// </summary>
private void UpdateTargetNetwork()
{
session.run(new[] {
tf.get_variable("tw1").assign(tf.get_variable("w1")),
tf.get_variable("tb1").assign(tf.get_variable("b1")),
tf.get_variable("tw2").assign(tf.get_variable("w2")),
tf.get_variable("tb2").assign(tf.get_variable("b2"))
});
}
/// <summary>
/// 添加新作业,动态扩展状态空间。
/// </summary>
/// <param name="newJob">新作业</param>
public void AddJob(Job newJob)
{
jobs.Add(newJob);
jobNextOperation.Add(0);
jobLastEndTime.Add(0);
Console.WriteLine($"时间 {newJob.ArrivalTime}:新作业 J{newJob.Id} 到达");
}
/// <summary>
/// 获取状态向量:s = [时间, 机器可用时间, 作业进度]。
/// </summary>
/// <param name="currentTime">当前时间</param>
/// <returns>状态向量</returns>
private float[] GetState(int currentTime)
{
var state = new float[1 + machineCount + jobs.Count];
state[0] = currentTime;
for (int i = 0; i < machineCount; i++) state[i + 1] = machineAvailableTime[i];
for (int i = 0; i < jobs.Count; i++) state[i + 1 + machineCount] = jobNextOperation[i];
return state;
}
/// <summary>
/// 获取可用动作(可调度的工序)。
/// </summary>
/// <param name="currentTime">当前时间</param>
/// <returns>动作列表(作业、工序、索引)</returns>
private List<(Job, Operation, int)> GetAvailableActions(int currentTime)
{
var actions = new List<(Job, Operation, int)>();
int actionIndex = 0;
for (int i = 0; i < jobs.Count; i++)
{
if (jobs[i].ArrivalTime <= currentTime && jobNextOperation[i] < jobs[i].Operations.Count)
{
actions.Add((jobs[i], jobs[i].Operations[jobNextOperation[i]], actionIndex++));
}
}
return actions;
}
/// <summary>
/// 使用ε-贪婪策略选择动作,基于Softmax概率分布。
/// 数学背景:P(a|s) = exp(Q(s, a)) / Σ exp(Q(s, a'))
/// </summary>
/// <param name="state">当前状态</param>
/// <param name="actions">可用动作</param>
/// <returns>动作索引</returns>
private int SelectAction(float[] state, List<(Job, Operation, int)> actions)
{
if (rand.NextDouble() < epsilon) // 探索:随机选择
return actions.Count > 0 ? actions[rand.Next(actions.Count)].actionIndex : -1;
var stateTensor = np.array(state).reshape(1, -1);
var qVals = session.run(qValues, new FeedItem(stateInput, stateTensor));
var probs = Softmax(qVals[0]); // Softmax概率分布
float maxProb = float.MinValue;
int bestAction = -1;
for (int i = 0; i < actions.Count; i++)
{
if (probs[actions[i].actionIndex] > maxProb)
{
maxProb = probs[actions[i].actionIndex];
bestAction = actions[i].actionIndex;
}
}
return bestAction;
}
/// <summary>
/// 计算Softmax概率分布。
/// 数学公式:P(a_i|s) = exp(Q_i) / Σ exp(Q_j)
/// </summary>
/// <param name="qValues">Q值数组</param>
/// <returns>概率分布</returns>
private float[] Softmax(float[] qValues)
{
var expQ = qValues.Select(x => (float)Math.Exp(x)).ToArray();
var sumExpQ = expQ.Sum();
return expQ.Select(x => x / sumExpQ).ToArray();
}
/// <summary>
/// 训练网络,使用蒙特卡洛经验回放。
/// 数学背景:
/// - 目标Q值:target = r + γ max Q(s', a'; θ')
/// - 蒙特卡洛:通过采样估计E[L(θ)]
/// </summary>
private void TrainNetwork()
{
if (replayBuffer.Count < 32) return;
var batch = replayBuffer.OrderBy(x => rand.Next()).Take(32).ToList();
var states = batch.Select(e => e.State).ToArray();
var targets = new float[batch.Count, maxActions];
for (int i = 0; i < batch.Count; i++)
{
var experience = batch[i];
var nextStateTensor = np.array(experience.NextState).reshape(1, -1);
var nextQ = session.run(targetQValues, new FeedItem(stateInput, nextStateTensor));
float maxNextQ = nextQ[0].Max();
targets[i, experience.Action] = experience.Reward + (experience.Done ? 0 : gamma * maxNextQ);
}
var stateBatch = np.array(states);
session.run(trainOp, new FeedItem(stateInput, stateBatch), new FeedItem(targetQ, targets));
}
/// <summary>
/// 运行DQN调度,优化Makespan。
/// </summary>
/// <param name="maxSimulationTime">最大模拟时间</param>
/// <returns>最佳Makespan</returns>
public int Run(int maxSimulationTime)
{
int episodeCount = 0;
int bestMakespan = int.MaxValue;
while (episodeCount < 50)
{
machineAvailableTime = new List<int>(new int[machineCount]);
jobNextOperation = new List<int>(new int[jobs.Count]);
jobLastEndTime = new List<int>(new int[jobs.Count]);
int currentTime = 0;
int stepCount = 0;
while (currentTime < maxSimulationTime || jobs.Any((j, i) => jobNextOperation[i] < j.Operations.Count))
{
if (currentTime == 5 && episodeCount == 0)
{
var newJob = new Job
{
Id = jobs.Count,
ArrivalTime = currentTime,
Operations = new List<Operation>
{
new Operation { JobId = jobs.Count, MachineId = 0, Duration = 2 },
new Operation { JobId = jobs.Count, MachineId = 1, Duration = 3 },
new Operation { JobId = jobs.Count, MachineId = 2, Duration = 1 }
}
};
AddJob(newJob);
}
var state = GetState(currentTime);
var actions = GetAvailableActions(currentTime);
if (actions.Count == 0)
{
currentTime++;
continue;
}
int actionIndex = SelectAction(state, actions);
if (actionIndex == -1) continue;
var (job, operation, _) = actions.Find(a => a.actionIndex == actionIndex);
int jobIndex = jobs.IndexOf(job);
int machineId = operation.MachineId;
int duration = operation.Duration;
int oldMakespan = machineAvailableTime.Max();
int startTime = Math.Max(machineAvailableTime[machineId], jobLastEndTime[jobIndex]);
startTime = Math.Max(startTime, currentTime);
int endTime = startTime + duration;
machineAvailableTime[machineId] = endTime;
jobLastEndTime[jobIndex] = endTime;
jobNextOperation[jobIndex]++;
currentTime = startTime;
int newMakespan = machineAvailableTime.Max();
float reward = -(newMakespan - oldMakespan);
var nextState = GetState(currentTime);
bool done = !jobs.Any((j, i) => jobNextOperation[i] < j.Operations.Count);
replayBuffer.Add(new Experience
{
State = state,
Action = actionIndex,
Reward = reward,
NextState = nextState,
Done = done
});
TrainNetwork();
if (stepCount % targetUpdateFreq == 0) UpdateTargetNetwork();
Console.WriteLine($"时间 {startTime}:调度 J{job.Id}-工序{jobNextOperation[jobIndex]} 到 M{machineId},加工时间:{duration},完成时间:{endTime}");
epsilon = Math.Max(0.1f, epsilon * epsilonDecay);
stepCount++;
}
int makespan = machineAvailableTime.Max();
bestMakespan = Math.Min(bestMakespan, makespan);
episodeCount++;
Console.WriteLine($"第 {episodeCount} 次训练,Makespan:{makespan}");
}
return bestMakespan;
}
/// <summary>
/// 测试程序。
/// </summary>
public static void Main()
{
var jobs = new List<Job>
{
new Job { Id = 0, ArrivalTime = 0, Operations = new List<Operation>
{
new Operation { JobId = 0, MachineId = 0, Duration = 3 },
new Operation { JobId = 0, MachineId = 1, Duration = 2 },
new Operation { JobId = 0, MachineId = 2, Duration = 5 }
}
},
new Job { Id = 1, ArrivalTime = 0, Operations = new List<Operation>
{
new Operation { JobId = 1, MachineId = 1, Duration = 4 },
new Operation { JobId = 1, MachineId = 2, Duration = 1 },
new Operation { JobId = 1, MachineId = 0, Duration = 2 }
}
},
new Job { Id = 2, ArrivalTime = 0, Operations = new List<Operation>
{
new Operation { JobId = 2, MachineId = 2, Duration = 2 },
new Operation { JobId = 2, MachineId = 0, Duration = 4 },
new Operation { JobId = 2, MachineId = 1, Duration = 3 }
}
}
};
var scheduler = new DynamicDQNScheduler(jobs, 3);
int makespan = scheduler.Run(20);
Console.WriteLine($"最终Makespan:{makespan}");
}
}
}
3.2 代码说明
-
概率方法:
-
Softmax:SelectAction中使用Softmax将Q值转换为动作选择概率。
-
蒙特卡洛:TrainNetwork通过随机抽样32条经验估计期望损失。
-
-
目标网络:
-
每10步更新目标网络参数,稳定Q值目标。
-
-
状态与动作:
- 状态:
s=[t,m1,m2,m3,p1,p2,p3,… ]\mathbf{s} = [t, m_1, m_2, m_3, p_1, p_2, p_3, \dots]
.\mathbf{s} = [t, m_1, m_2, m_3, p_1, p_2, p_3, \dots] -
动作:选择工序,基于Softmax概率分布。
- 状态:
- 奖励:
r=−ΔMakespanr = -\Delta \text{Makespan}
.r = -\Delta \text{Makespan} -
图解:
状态:s = [5, 3, 4, 2, 1, 2, 0] Q值:q = [2.1, 1.5, 0.8] Softmax:P(a|s) = [0.58, 0.32, 0.10] 经验回放:[(s1, a1, r1, s1'), ...]
4. 总结
-
概率核心概念:
-
概率分布(Softmax)、期望(Q值)、贝叶斯定理(推断)、蒙特卡洛方法(经验回放)。
-
图解直观展示概率分布和期望计算。
-
-
深度学习应用:
-
Softmax用于动作选择,蒙特卡洛估计Q值,贝叶斯方法建模不确定性。
-
-
车间调度:
-
DRL通过概率方法优化动态调度,适应新作业到达。
-
代码使用Softmax和经验回放实现动作选择和Q值优化。
-
-
代码特点:
-
清晰的注释,结构化说明功能和数学背景。
-
集成目标网络和Softmax,提升训练稳定性和动作选择。
-
如果您需要更深入的概率推导(如贝叶斯变分推断)、更复杂的图解(如概率分布3D可视化)或进一步代码优化(如优先级经验回放),请告诉我,我可以提供更详细的内容!
更多推荐
所有评论(0)