加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

状态机实现复杂程序流程

(2011-07-07 14:35:32)
标签:

状态机

编程方式

步骤

4a

a6

分类: Matlab

前一阵编写优化设计约束优化的程序,被可行方向法复杂的计算流程搞晕了,如下为其计算步骤

image

image

步骤的复杂关键在于各步程序之间的跳转,为了跳转要相应的修改一些变量的值,要准备一些变量,要考虑的细节复杂的很啊。

想到曾经接触过状态机,考虑用状态机实现各步之间的跳转,代码大概如下

flag = 1;
while flag ~= -1
    switch flag
        case 1
            xk = x0;
            flag = flag + 1;
        case 2
            dk = -getGradsVector(FuncNo, xk);
            dk = dk/norm(dk);
            flag = flag + 1;
        case 3
            t = GetTestStep(FuncNo, xk ,dk);
            flag = flag + 1;
        case 4
            flagInRange = getConstraintCondition(FuncNo, xk + t*dk, delta);
            flag = flag + 1;
        case 5
            switch flagInRange
                case 0
                    flag = 9;
                case 1
                    if getFuncValue(FuncNo, xk + t*dk) > getFuncValue(FuncNo, xk)
                        flag = 6;
                    else
                        t = t*2;
                        flag = 4;
                    end
                case -1
                    flag = 8;
            end
        case 6
            % 一维搜索
            ODSNo = 1;
            xk = fmin(ODSNo, FuncNo, xk, dk, t, err);
            flag = flag +1;
        case 7
            dk = -getGradsVector(FuncNo, xk);
            dk = dk/norm(dk);
            flag = 10;
       case 8
            t = ChangeStep(FuncNo, xk, t, dk, delta);
            flag = flag + 1;
        case 9
            if getFuncValue(FuncNo, xk + t*dk) > getFuncValue(FuncNo, xk)
                flag = 6;
            else
                xk = xk + t*dk;
                dk = GetNewDirection(FuncNo, xk, delta); % 可以更改产生可行方向的方法
               
                flag = flag + 1;
               
                if isnan(dk)
                    flag = -1;
                end
            end
        case 10
            gradxk = getGradsVector(FuncNo, xk);
            gradxk = gradxk/norm(gradxk);
            if abs(gradxk'*dk) <= err && delta <= err || abs(t) <= 0.00000001
                flag = -1;
            else
                if abs(gradxk'*dk) <= err
                    delta = delta/2;
                end
                flag = 3;
            end
    end
end

上面的实现方法,效率可能不算最高的,但思路绝对清晰,而且如果把复杂的步骤封装成一个函数,思路将更清晰;这样做,如果算法是完备的,状态之间的转换也是完备的,就是说不会出现乱蹦的情况;最后,这种编程方式,调试起来也很方便,在各个case下设断点(可能断点多点),每执行一下就是一个步骤,可以完全按着算法思路来调试。

想想,如果没有用这种方式,估计最后会编到吐血啊!

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有