下面给出一种常见的思路,说明在我们已经建立了一个理想化的动态模型(不考虑排队时间、假设多窗口并行服务等)之后,如何借助可观测数据来“反演”或“识别” p(t)p(t)。核心思想是:虽然直接测“有多少人一进食堂就决定买饭”非常困难,但如果我们可以“实地”或“额外”量测到一些随时间变化的可观测量(如某个时刻服务区里正在买饭的人数、就餐区里正在吃饭的人数、系统总离开率等),就可以利用前面列出的微分方程或流量平衡来求解或拟合出 p(t)p(t) 。
下面给出具体方法。为了叙述清晰,我会先回顾一下前面给出的简单模型,然后给出从中解出 p(t)p(t) 的思路。
1. 模型回顾
1.1 变量与方程
-
E(t)E(t):进入食堂的人流率 (人/秒),已知(可测)。
-
L(t)L(t):离开食堂的人流率 (人/秒),已知(可测)。
-
p(t) p(t):进入食堂后决定去买饭的比例(概率),我们想反演它。
-
Nservice(t) N_\text{service}(t):时刻 tt 正在服务区(买饭)的人数。
-
Ndining(t) N_\text{dining}(t):时刻 tt 在就餐区(吃饭)的人数。
-
S(t) S(t):平均服务时长 (秒/人)。
-
D(t) D(t):平均就餐时长 (秒/人)。
-
r(t) r(t):买完饭后留下吃饭的比例。
考虑“理想多服务器、无需排长队”假设,服务区人数随时间的变化方程(忽略排队等待)为:
{λ(t) = p(t) E(t),ddtNservice(t) = λ(t) − Nservice(t)S(t) = p(t) E(t) − Nservice(t)S(t).\begin{cases} \lambda(t) ;=; p(t),E(t), \ \dfrac{d}{dt}N_\text{service}(t) ;=;\lambda(t);-;\dfrac{N_\text{service}(t)}{S(t)} ;=;p(t),E(t);-;\dfrac{N_\text{service}(t)}{S(t)}. \end{cases}
就餐区人数随时间的变化方程为:
ddtNdining(t) = r(t) Nservice(t)S(t) − Ndining(t)D(t).\dfrac{d}{dt}N_\text{dining}(t) ;=;r(t),\dfrac{N_\text{service}(t)}{S(t)} ;-;\dfrac{N_\text{dining}(t)}{D(t)}.
整个平台(食堂)的离开速率 L(t)L(t) 可分为3部分:
-
不买饭直接走:(1−p(t)) E(t)(1 - p(t)),E(t);
-
买完饭直接走:(1−r(t)) Nservice(t)S(t)\bigl(1 - r(t)\bigr),\dfrac{N_\text{service}(t)}{S(t)};
-
吃完饭离开:Ndining(t)D(t)\dfrac{N_\text{dining}(t)}{D(t)}。
因此:
L(t)=(1−p(t)) E(t) + (1−r(t)) Nservice(t)S(t) + Ndining(t)D(t).L(t) = (1 - p(t)),E(t) ;+;\bigl(1 - r(t)\bigr),\dfrac{N_\text{service}(t)}{S(t)} ;+;\dfrac{N_\text{dining}(t)}{D(t)}.
2. 反演 p(t)p(t) 的思路
在实际中,直接问每个人“你是要买饭还是直接走” 并统计其随时间的变化并不现实。但是我们可以通过以下两种常见思路,把 p(t)p(t) 识别出来:
思路 A:直接测量 Nservice(t)N_\text{service}(t) 并利用微分方程反演
如果食堂管理方或研究人员可以实时统计“某时刻有多少人在服务区”(这是相对比较容易的观测,如在买饭区放一个红外/视觉计数装置,或者服务区人数相对不大、人手也能统计)那么我们可以利用:
ddtNservice(t) = p(t) E(t) − Nservice(t)S(t).\frac{d}{dt}N_\text{service}(t) ;=;p(t),E(t);-;\frac{N_\text{service}(t)}{S(t)}.
只要我们量得 Nservice(t)N_\text{service}(t) 这个函数(或离散时间点采样),又已知 E(t)E(t) 和 S(t)S(t)(服务时长平均值,也可以测或估计),就能从该方程里显式解出:
p(t) = ddtNservice(t) + Nservice(t)S(t)E(t).\boxed{ p(t) ;=; \frac{\displaystyle \frac{d}{dt}N_\text{service}(t);+;\frac{N_\text{service}(t)}{S(t)}} {E(t)}. }
-
优点:
-
不需要直接去问“你买饭了吗”;
-
只需统计“服务区的人数随时间的变化”并知道平均服务时长 S(t)S(t),然后做一阶微分(或差分)即可。
-
-
难点:
-
测量 Nservice(t)N_\text{service}(t) 虽比直接测 p(t)p(t) 容易,但也需要花功夫(硬件计数或人工统计);
-
在实际场景下, S(t)S(t) 可能也并非固定常数,而是一个带有波动的量(不同窗口、不同服务员、不同高峰期等),需要做好平均或分时估计。
-
但无论如何,如果我们能在时间序列上捕捉到 Nservice(t)N_\text{service}(t) 并知道 S(t)S(t)、E(t)E(t),那就能用上面的公式轻松还原出 p(t)p(t)。这是最快速、最直接的一种方法。
思路 B:利用系统离开率 L(t)L(t) + 就餐区人数 Ndining(t)N_\text{dining}(t) 的数据进行整体拟合
有些场景下,服务区人数并不容易测,但可能出于管理需求,食堂对整个出入口都安了门禁计数器,因此 E(t)E(t) 和 L(t)L(t) 随时间的曲线都容易获得。再加上有时也会关注堂食区域的繁忙程度(比如想知道大厅是否爆满),就可能对“就餐区的人数 Ndining(t)N_\text{dining}(t)”有比较准确的统计。
这时候,可以利用如下三条方程同时做“参数识别”或“数值拟合”:
- (\dfrac{d}{dt}N_\text{dining}(t) = r(t),\dfrac{N_\text{service}(t)}{S(t)}
- \dfrac{N_\text{dining}(t)}{D(t)}.)
- (L(t) = (1 - p(t)),E(t)
-
\bigl(1 - r(t)\bigr),\dfrac{N_\text{service}(t)}{S(t)}
-
\dfrac{N_\text{dining}(t)}{D(t)}.)
- 以及服务区人数方程:ddtNservice(t)=p(t) E(t)−Nservice(t)S(t).\dfrac{d}{dt}N_\text{service}(t) = p(t),E(t) - \dfrac{N_\text{service}(t)}{S(t)}.
但现在麻烦点在于:我们手头并没有 Nservice(t)N_\text{service}(t) 的测量数据,如果只有 L(t)L(t) 和 Ndining(t)N_\text{dining}(t) 这两条曲线可观测,就得在模型里把 Nservice(t)N_\text{service}(t) 当成“隐变量”,把 p(t)p(t) 当成“待识别函数”,再加上 r(t)r(t)、S(t)S(t)、D(t)D(t) 等也可能并非全部精确已知,就需要做一个多参数/多函数的拟合或估计。
思路大体如下:
-
设定一个“初始猜测”:比如先假设 p(t)p(t) 是一个缓慢变化的函数,可以用多项式、分段常数、或其他“低维”参数化函数来表达;类似地, r(t)r(t) 也做类似参数化(或先假设 rr 近似恒定)。S(t),D(t)S(t), D(t) 如果能测一点,就固定成常数或慢变函数。
-
把这组猜测函数带入微分方程(服务区 + 就餐区),从某个初始条件 {Nservice(0), Ndining(0)}{N_\text{service}(0),,N_\text{dining}(0)} 开始做数值积分,得到预测的 Ndining(pred)(t)N_\text{dining}^\text{(pred)}(t) 以及离开率 L(pred)(t)L
-
与实际观测 Ndining(obs)(t)N_\text{dining}^\text{(obs)}(t) 、L(obs)(t)L^\text{(obs)}(t) 做差,用最小二乘或其他误差函数衡量二者的差距,然后采用梯度下降或其他优化算法,对 p(t)p(t)(以及 r(t),S(t),D(t)r(t), S(t), D(t) 的参数)进行迭代调整,直到拟合误差最小。
-
得到的那条“最优 p∗(t)p^*(t) 函数”就是在此模型框架下、与实测数据最匹配的“去买饭概率/比例”估计。
这属于系统辨识或参数识别的典型方法,实际可借助一些常见的数值分析库(如 MATLAB、Python 里的 SciPy 库等)来做。
思路 C:统计退出路径,间接估计 p(t)p(t)
还有一种更直接但也更“精细”的统计思路:我们知道离开食堂有三条路径:
-
直接走(不买);
-
买完就走;
-
买完+堂食后再走。
如果我们能在出口附近做“抽样调查”或者有更智能的系统(比如把三个出口物理分开)来统计某时刻离开者中属于哪条路径,那么就能分辨:
-
在时刻 tt ,“不买饭”离开的流率大约是 (1−p(t))E(t)(1 - p(t))E(t);
-
“买饭直接走”的流率是 (1−r(t)) Nservice(t)S(t)\bigl(1 - r(t)\bigr),\frac{N_\text{service}(t)}{S(t)};
-
“堂食离开”的流率是 Ndining(t)D(t)\frac{N_\text{dining}(t)}{D(t)}。
只要能把这三者在各时段的相对比例测出来,就能直接再现 p(t)p(t) ,因为“不买饭直接走”那部分占了 (1−p(t))E(t)(1 - p(t))E(t) 。
但是在现实场景中,要想随时间连续地分清离开者是“买了没买”、“吃了没吃”也并非易事(可能需要在出口就餐托盘回收处加统计,或者加更多摄像头识别等等),所以大多也不算“简单”。不过这是另一个可行的技术途径。
3. 小结
要点在于:我们已知 λ(t)=p(t) E(t)\lambda(t) = p(t),E(t),但无法直接测 p(t)p(t),可以通过对系统内部状态或子流的观测(典型的就是“服务区人数” Nservice(t)N_\text{service}(t)),或者对离开者结构(买/不买、堂食/不堂食) 的更加细分统计,来反演出 p(t)p(t)。主要有三种常见方法:
-
(推荐) 直接测服务区人数 Nservice(t)N_\text{service}(t):
-
由
ddtNservice(t) = p(t) E(t)−Nservice(t)S(t),\frac{d}{dt}N_\text{service}(t) ;=; p(t),E(t) - \frac{N_\text{service}(t)}{S(t)},
直接解出
p(t) = ddtNservice(t) + Nservice(t)S(t)E(t).p(t) ;=; \frac{\dfrac{d}{dt}N_\text{service}(t);+;\dfrac{N_\text{service}(t)}{S(t)}}{E(t)}.
-
-
(系统辨识) 只测离开率 L(t)L(t) 与就餐区人数 Ndining(t)N_\text{dining}(t) 等宏观指标:
- 把 Nservice(t)N_\text{service}(t) 当成“隐变量”,用微分方程与观测数据做拟合/优化,迭代反演 p(t)p(t) (以及其他参数),需要一定的数值方法和初始猜测。
-
(精细统计) 区分出口:
- 直接在出口区统计不买饭离开的、买饭不堂食离开的、堂食离开的各自流率,从而分离出 (1−p(t))E(t)(1 - p(t))E(t) 这一项,进而得到 p(t)p(t)。
在实践中,一般会根据场地可行性、统计或传感设备、研究预算等不同情况,选择更容易实现的一条路。有些食堂安了比较完善的摄像头和统计系统,就可以实现方法 A 或 C;如果只能做总出入口计数,则要用方法 B 的方式,做更宏观的模型拟合。
简言之:
如果能量测“服务区同时在买饭人数”这一条最关键的内部状态,就能非常“干脆”地通过微分方程直接解出 p(t)p(t)。
若实在无法测“服务区人数”,则只能通过系统整体的离开流量、就餐区人数、或更多分流出口的统计数据,来做多方程/多变量的拟合或辨识,间接获得 p(t)p(t)。
这就是在“理想人”模型下,从外部或内部观测数据还原 p(t)p(t) 的典型做法。
希望对你有所帮助。
附注(Python环境说明)
若要在 Python 中实现“数值拟合”或“求解微分方程”的过程,可以使用numpy、scipy等常见库。国内环境推荐使用镜像源安装,如:pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple pip install scipy -i https://pypi.tuna.tsinghua.edu.cn/simple这方面的代码示例很多,也可以在 Jupyter Notebook / VSCode / PyCharm 等环境中直接使用
scipy.integrate.odeint或solve_ivp进行微分方程数值求解。
下面给出一个在不额外测量服务区人数或堂食人数的情况下,利用 E(t)E(t)(进入率)、L(t)L(t)(离开率)和若干可以估算的“常数”来粗略推断 p(t)p(t)(进门后决定买饭的人所占比例)的方法。
由于没有内部状态(如正在买饭人数、正在堂食人数等)的精确观测,这种方法难以做到精确,但它能给出一个“看起来依赖 E(t) 和 L(t) 等外部可测量”的近似估计,并能直观“揭示”模型中 p(t)p(t) 的含义与影响。
1. 思路概述
我们先回顾最简单的“理想人”流转路径:
-
进门后,不买饭的部分 (占比 1−p(t)1-p(t)) 立即离开(几乎忽略在场时间);
-
进门后,去买饭的部分 (占比 p(t)p(t)),在食堂会停留一段时间再离开;
- 这段时间包含了服务时间 SS,以及(可能)在堂食区停留时间 DD 的一部分。若有比例 rr 会堂食,则总“滞留”时间可写为 τ=S+rD\tau = S + rD(也可做更复杂拆分)。
如果我们只看外部数据(某时刻的进入速率 E(t)E(t) 与离开速率 L(t)L(t)),最直观的简化假设是——买饭的那部分人,约在 τ\tau 秒之后才出现在离开队伍里;而不买饭的那部分人几乎瞬时进、瞬时出。由此可以写出一个“带延迟的简化守恒”关系式:
L(t) ≈ (1−p(t)) E(t)⏟当下进门马上离开 + p(t−τ) E(t−τ)⏟先前时刻买饭的那批人, 现在离开.L(t) ;\approx; \underbrace{\bigl(1 - p(t)\bigr),E(t)}{\text{当下进门马上离开}} ;+; \underbrace{p(t-\tau),E\bigl(t-\tau\bigr)}{\text{先前时刻买饭的那批人, 现在离开}}.
在很多实际情况下,为了让公式更“可操作”,还会做进一步近似,譬如认为 p(t)p(t) 变化不那么快,于是我们可以把 p(t−τ)≈p(t)p(t - \tau)\approx p(t)。这样就得到:
L(t) ≈ (1−p(t)) E(t) + p(t) E(t−τ).L(t) ;\approx; \bigl(1 - p(t)\bigr),E(t) ;+; p(t),E\bigl(t - \tau\bigr).
把这条式子整理一下:
L(t)=E(t) − p(t) E(t) + p(t) E(t−τ)=E(t) + p(t) [E(t−τ) − E(t)].\begin{aligned} L(t) &= E(t) ;-; p(t),E(t) ;+; p(t),E(t - \tau) \ &= E(t) ;+; p(t),\Bigl[E(t - \tau);-;E(t)\Bigr]. \end{aligned}
因此,可以粗略地解出
p(t) ≈ L(t) − E(t) E(t−τ) − E(t) .\boxed{ p(t) ;\approx; \dfrac{,L(t) ;-; E(t),}{,E\bigl(t - \tau\bigr) ;-; E(t),}. }
其中:
-
τ≈S+r D\tau \approx S + r,D 为**“买饭+吃饭”导致的平均停留时长**(当然,这只是非常粗略的“一刀切”时间延迟);
-
E(t)E(t) 和 L(t)L(t) 都是食堂出入口处可直接测量的人流率(人/秒);
-
p(t)p(t) 的取值应在 [0,1][0,1] 之间,但由于上述近似并不严谨,若碰到 [E(t−τ)−E(t)]\bigl[E(t - \tau)-E(t)\bigr] 太小、符号反转,或者 L(t)≈E(t)L(t)\approx E(t) 等情况,可能出现奇异值或反常值,要小心解释或平滑处理。
2. 公式的含义和使用方法
-
该公式的物理直觉:
-
“直接走”那部分贡献了 (1−p(t))E(t)\bigl(1 - p(t)\bigr) E(t) 的瞬时离开率(因为理想人忽略排队,也不在场停留);
-
“买饭/堂食”那部分不会在当下时刻立刻离开,而是在大约 τ\tau 秒后离开。因此,时刻 tt 的这部分离开率大致对应于τ\tau 秒前的买饭人流:p(t−τ) E(t−τ)p(t-\tau), E(t-\tau)。
-
-
如何选取 τ\tau:
-
τ\tau 通常可由平均服务时间 SS 与堂食平均时间 DD 粗略相加,再乘上堂食概率 rr。例如若食堂里“买完就走”的也不少,则可取 τ=S+r D\tau = S + r,D;也可以直接用“买饭人”在系统内的整体平均停留时间(包含服务+等候+吃饭)。
-
在实际中,你可能先做简单抽样或调研,估计出这一平均“停留时长”是多少。
-
-
在什么场合下适用:
-
人流随时间波动明显,且系统没有明显“排队瓶颈”(理想多窗口);
-
p(t)p(t) 在相对于 τ\tau 的尺度上不剧烈震荡(否则假设 p(t−τ)≈p(t)p(t - \tau)\approx p(t) 就太粗了);
-
如果刚好在高峰平衡(稳态)⇒E(t)≈L(t)\Rightarrow E(t)\approx L(t),那么代入公式会导致分子、分母都接近 0,难以给出有效信息。这时只能说“系统差不多流入=流出”,无法仅凭 EE 和 LL 区分究竟多少人选择买饭。
-
-
可能产生的“异常值”与简化局限:
-
如果 [E(t−τ)−E(t)]\bigl[E(t-\tau)-E(t)\bigr] 太小或符号与 [L(t)−E(t)]\bigl[L(t)-E(t)\bigr] 不一致,可能出现负值或大于 1 的 p(t)p(t);
-
公式是假设“买饭”的人几乎都在恰好 τ\tau 秒后离开,实际中会有分布(有人更快、有人更慢);
-
略去了“有人先买饭又没堂食”的多重时间段拆分;
-
若系统存在排长队、不同买饭窗口差异、或在高峰时段远非“无等待”,该近似就更偏离了。
-
简而言之,这个“延迟管道”的近似模型是最简单的一类方法:用一个常数 τ\tau 来代表“买饭(+堂食)”可能带来的平均停留延时,把当下离开率中的“延迟项”与当下“直接离开项”分开,进而以 E(t),L(t)E(t), L(t) 和 τ\tau 来求一个粗略的 p(t)p(t)。
3. 总结
-
直接从 E(t)E(t) 与 L(t)L(t) 两条曲线里,想“零附加观测”就反演 p(t)p(t) 往往是“不可能精确”的,因为系统的内在流动还涉及服务区停留、堂食停留、以及概率分流等诸多环节。
-
上述延迟近似公式:
p(t) ≈ L(t) − E(t) E(t−τ) − E(t) (其中 τ≈S+rD)\boxed{ p(t) ;\approx; \dfrac{,L(t) ;-; E(t),} {,E\bigl(t - \tau\bigr) ;-; E(t),} \quad\text{(其中 }\tau \approx S + rD\text{)} }
可以在“理想多窗口+人流显著随时间波动+(近)无排队”的场合下,给出一个能够“定性揭示” p(t)p(t) 大小的粗略估计。它本质上将“当下离开率大于(或小于)当下进入率”这部分差值,视为“买饭人”在 τ\tau 秒之后集中离开所贡献;在时序上做了一次简单的管道延迟假设。
-
若系统长期保持 E(t)≈L(t)E(t)\approx L(t)(高峰平衡),或者 p(t)p(t) 快速抖动、抑或产生排队大拥堵,则该近似模型效果欠佳,需要更精细的排队论模型或内部人数观测(如测量服务区人数)才能更准确地识别 p(t)p(t)。
额外提示(Python 安装环境)
如需做数值模拟、拟合,或对上述公式进行离散时间实现,可以在 Python 中使用 numpy / scipy 等库,国内可用清华镜像加速安装:
pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install scipy -i https://pypi.tuna.tsinghua.edu.cn/simple在代码中根据采样数据 {E(ti),L(ti)}{E(t_i), L(t_i)} 以及给定的 τ\tau,即可套用上面的公式,逐点估算一个 p(ti)p(t_i) 近似值。