设计一个算法的方法论

设计一个算法的方法论

引言

多年来本人在研发团队里担任算法设计工程师,设计过的算法包括:电能计量、复杂控制、无线通信和系统架构等。蓦然回首,顿悟算法设计有很多共性,抽取出来大致为6个步骤,结合近段时间设计的一个算法撰写了这个方法论。主要用于总结经验,提高自身的生产力;如果不小心启发了他人,也算是对业界的一点小贡献。

<一>:设计需求(Who 该算法用来解决什么问题)

例:在一个无线通信系统中,节点定时上报数据给网关(如下图红色时隙),同时也支持网关唤醒节点(如下图绿色时隙),为此需要设计“唤醒算法”。要求:

1. WakeTime被网络内所有节点和网关共享;

2. WakeTime必须避开主动上报,否则将“冲突出错”且“耗能增大”;

3. 它比较适合于“第N个WakeUp”计算“第(N+1)个WakeTime”;

4. 它必须尽可能得简单;

设计一个算法的方法论_第1张图片

<二>:列影响量(Why 影响该算法的因素有哪些)

在该算法中存在如下参数:

1. reserved slot:保留时隙,即在此段时隙中没有节点主动上报;

2. slot idle:空闲时隙,即相邻两个节点之间隔离的时间;

3. wake exchange:唤醒通信时间,即网关唤醒节点并与其进行交互通信时长;

前面2个参数的解释如下图所示:

设计一个算法的方法论_第2张图片

设计一个算法的方法论_第3张图片

<三>:应用场景(What组合各种影响量的场景有哪些)

上面3个参数组合成如下4种应用场景:

 设计一个算法的方法论_第4张图片

设计一个算法的方法论_第5张图片

<四>:抽象方法(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代入数据验证算法模型的正确性)

实例一:

设计一个算法的方法论_第6张图片

实例条件:

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

 

实例二:

 设计一个算法的方法论_第7张图片

实例条件:

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;

}

你可能感兴趣的:(设计方法论)