设计一个算法的方法论
引言
多年来本人在研发团队里担任算法设计工程师,设计过的算法包括:电能计量、复杂控制、无线通信和系统架构等。蓦然回首,顿悟算法设计有很多共性,抽取出来大致为6个步骤,结合近段时间设计的一个算法撰写了这个方法论。主要用于总结经验,提高自身的生产力;如果不小心启发了他人,也算是对业界的一点小贡献。
<一>:设计需求(Who 该算法用来解决什么问题)
例:在一个无线通信系统中,节点定时上报数据给网关(如下图红色时隙),同时也支持网关唤醒节点(如下图绿色时隙),为此需要设计“唤醒算法”。要求:
1. WakeTime被网络内所有节点和网关共享;
2. WakeTime必须避开主动上报,否则将“冲突出错”且“耗能增大”;
3. 它比较适合于“第N个WakeUp”计算“第(N+1)个WakeTime”;
4. 它必须尽可能得简单;
<二>:列影响量(Why 影响该算法的因素有哪些)
在该算法中存在如下参数:
1. reserved slot:保留时隙,即在此段时隙中没有节点主动上报;
2. slot idle:空闲时隙,即相邻两个节点之间隔离的时间;
3. wake exchange:唤醒通信时间,即网关唤醒节点并与其进行交互通信时长;
前面2个参数的解释如下图所示:
<三>:应用场景(What组合各种影响量的场景有哪些)
上面3个参数组合成如下4种应用场景:
<四>:抽象方法(How 建立一个算法模型解决上述场景中问题)
令x=第x次wake,f(x)=第x次wake time,则有:
f(x)=N*wakeperiod+nofly+(x-1)*wakeinterval (1)
safeguard=(wakeperiod-nofly)%wakeinterval (2)
已知:当前RTC值,求隔离最近的wake time值如下:
第一步:if(RTC / wakeperiod != (RTC + safeguard) / wakeperiod)
RTC += safeguard;
第二步:计算N值:N = RTC / wakeperiod;
第三步:计算x的值:
x = (RTC + wake interval –N * wake period –nofly) / wakeinterval;
if (x < 0) x= 0;
x += 1;
第四步:将N和x代入公式(1)计算出f(x)值。
第五步:检查wake time是否与UPLINK相冲突:
wake end = wake time + wake exchange –1;
if (wake time / wake period != wake end/ wake period)
wake time = wake end / wake period* wake period + nofly;
<五>:理论验证(Check代入数据验证算法模型的正确性)
实例一:
实例条件:
| wake period | nofly | wake interval | wake exchange | safeguard |
| 65 | 40 | 10 | 5 | 5 |
计算数据如下表:
| RTC | +safeguard | N | x | f(x) | wake end | wake time |
| 0~39 | / | 0 | 1 | 40 | 44 | 40 |
| 40~49 | / | 0 | 2 | 50 | 54 | 50 |
| 50~59 | / | 0 | 3 | 60 | 64 | 60 |
| 60~64 | 65~69 | 1 | 1 | 105 | 109 | 105 |
| 65~104 | / | 1 | 1 | 105 | 109 | 105 |
实例二:
实例条件:
| wake period | nofly | wake interval | wake exchange | safeguard |
| 63 | 40 | 10 | 5 | 3 |
计算数据如下表:
| RTC | +safeguard | N | x | f(x) | wake end | wake time |
| 0~39 | / | 0 | 1 | 40 | 44 | 40 |
| 40~49 | / | 0 | 2 | 50 | 54 | 50 |
| 50~59 | / | 0 | 3 | 60 | 64 | 103 |
| 60~62 | 63~65 | 1 | 1 | 103 | 107 | 103 |
| 63~102 | / | 1 | 1 | 103 | 107 | 103 |
<六>:实验测试(Test编码/代入数据/白盒/黑盒测试)
一般来说需要编码实现该算法,覆盖应用场景组织测试数据,让系统自动遍历测试数据,检验算法的正确性。白盒测试有助于:跟踪系统的运行,遍历程序分支,还可以优化软件;黑盒测试有助于:快速查看结果,检查算法输出是否正确。往往实验会找出算法缺陷,此时根据反馈需要重新设计或修正。
本实例算法代码清单如下:
static int32_t CalcWakeTime(int32_t lRTC)
{
int32_t lRTCVal, lXInterval,lMulDiv, lWakeTime, lWakeEnd;
lRTCVal = lRTC;
/* Check whether need to add safeguard. */
if ( lRTCVal / s_stSlotWakeTime.lUplinkPeriod !=
(lRTCVal +s_stWakeParam.nSafeGuard) / s_stSlotWakeTime.lUplinkPeriod )
{
lRTCVal += s_stWakeParam.nSafeGuard;
}
/* Calculate value of "N" */
ASSERT(0 < s_stSlotWakeTime.lUplinkPeriod);
lMulDiv =lRTCVal / s_stSlotWakeTime.lUplinkPeriod;
/* Calculate value of "x" */
lXInterval = (lRTCVal + s_stWakeParam.lWakeInterval) - lMulDiv *s_stSlotWakeTime.lUplinkPeriod -
s_stWakeParam.lNoFly;
lXInterval /= s_stWakeParam.lWakeInterval;
if (lXInterval < 0)
{
lXInterval = 0;
}
++lXInterval;
/* wake time = N * wake period + nofly + (x - 1) * wake interval. */
lWakeTime = lMulDiv * s_stSlotWakeTime.lUplinkPeriod +s_stWakeParam.lNoFly + (lXInterval - 1) *
s_stWakeParam.lWakeInterval;
ASSERT(lRTC< lWakeTime);
/* Check collision between WAKE and UPLINK. */
lWakeEnd = lWakeTime + s_stSlotWakeTime.nWakeExchange - 1;
if (lWakeTime / s_stSlotWakeTime.lUplinkPeriod != lWakeEnd /s_stSlotWakeTime.lUplinkPeriod)
{
lWakeTime = lWakeEnd / s_stSlotWakeTime.lUplinkPeriod *s_stSlotWakeTime.lUplinkPeriod +
s_stWakeParam.lNoFly;
}
returnlWakeTime;
}
1万+

被折叠的 条评论
为什么被折叠?



