伪代码法

[b][color=red]2011-05-11 补充一个链接,这个例子实际些:[/color][/b] [url]http://www.iteye.com/topic/826710#1809014[/url]

今天在看跟[url="http://wxmfly.iteye.com/"]Bob[/url]借来的[url="http://book.douban.com/subject/3109238/"]《Everyday Scripting with Ruby》[/url],看到第7章第2小节提到的一个“假设式脚本编写法”,忍不住兴奋,这不就是我一直在用的所谓“伪代码法”嘛。顿时一股[url="http://www.iteye.com/topic/243210"]“英雄所见略同”的自豪感[/url]油然而生。 :D 喔呵呵呵呵……骄傲了点。。

其实所谓的“伪代码法”的想法来自于[url="http://book.douban.com/subject/1229923/"]《重构》[/url]一书中所说的:[quote]我们应当遵循这样一个原则,每当感觉需要注释来说明一些什么的时候,就将要说明的东西写进独立函数,并以其用途(而不是实现手法)命名。[/quote]
以及论坛里一些前辈的经验之谈,还有自己在学习过程中的一点领悟(如[url="http://yuan.iteye.com/blog/452228"]从AWDWR中的depot思考软件设计[/url])。遵循着这条原则写代码多了,有时候就会有意的把一些估计处理起来会比较麻烦的过程(往往不是该方法的职责)直接以一句话替代,也就是一个并未实现的方法调用。最后总结出这么个伪代码法。

现在觉得这样写起代码挺自然的,就像是一层层深入的,从最接近用户需求的表面到具体的技术实现的细节的,自顶向下的为你解释一个系统如何工作:
这个功能要做事情A,事情B;
当遇到某种情况时,要去做事情C;
否则,做事情D;
最后做事情E。

然后如果有必要的话,接着开始详细解释、或者说定义事情A、B、C、D、E,就像上面的解释一样。
事情A:
首先做XX
然后……

这样自顶向下写出来的代码目的很明确,下层的接口定义的很清楚,同时[b]保证了不会有多余的代码,你所写的即是你所需要的,避免了过度设计[/b]。也不会出现大把业务逻辑写在控制器中的情况了。因为你的控制器已经写明白了控制器要负责的事,剩下的都交给模型去处理吧:

根据perishable_toke查找用户
如果找到用户
激活用户
返回登录页面
否则
返回报告错误页面
结束

@user = User.find_using_perishable_token(params[:token])
if @user
@user.activate!
redirect_to signin_path
else
render 'activate_failed'
end


然后实现find_using_perishable_token方法(authlogic已经实现了)。
接着定义激活用户的方法:
激活用户:
设置user的active值为true
重置perishable_token
保存

User#activate!
def activate!
self.active = true
reset_perishable_token
save
end

然后再实现reset_perishable_token和save方法,不过在这里这两个方法已经是authlogic和rails实现的了。

总的来说伪代码法就是用最直白最简单的人类语言把系统要做的事情简要说一遍(就像讲故事一样 :) ),然后再往下逐个解释每件事情大概应该怎么做,在处理每件事情的过程中可能又有更繁琐的细节,这时候也以一句简单的话概括,不管它如何实现,然后继续……直到整个功能完成。

之所以叫伪代码法是因为在一开始写出来的代码是不能执行的。不过现在找到它的名字了:假设式脚本编写法(scripting by assumption)、一厢情愿式编程法(programming by wishful thinking)。

我觉得这是一种很实用的开发方法,再跟TDD结合会相当的完美。 :D
### 内点伪代码及算实现 内点(Interior Point Method)是一种用于求解线性规划和非线性规划问题的优化算。它通过构造一个障碍函数来避免违反约束条件,从而将约束优化问题转化为一系列无约束优化问题。以下为内点的基本伪代码及其实现[^5]。 #### 内点伪代码 ```plaintext Input: 初始点 x0,目标函数 f(x),约束条件 g(x) ≤ 0,参数 μ > 0,终止条件 ε > 0 Output: 满足约束的最优解 x* 1. 初始化:令 k = 0,x = x0 2. while 停止条件不满足 (||∇L(x, μ)|| > ε): 3. 构造障碍函数: L(x, μ) = f(x) - μ * Σ log(-g_i(x)), 其中 g_i(x) 是所有约束条件 4. 计算 L(x, μ) 的梯度 ∇L(x, μ) 5. 使用牛顿或其他优化方求解 ∇L(x, μ) = 0,得到新的 x 6. 更新迭代计数器 k = k + 1 7. 返回最优解 x* ``` #### 内点的 Python 实现 以下是基于上述伪代码的一个简单实现示例,使用牛顿进行迭代求解: ```python import numpy as np def interior_point_method(f, grad_f, hessian_f, g, grad_g, x0, mu=0.1, epsilon=1e-6, max_iter=100): """ 内点实现。 参数: f: 目标函数 grad_f: 目标函数的梯度 hessian_f: 目标函数的 Hessian 矩阵 g: 不等式约束函数列表 [g1, g2, ..., gm] grad_g: 不等式约束函数的梯度列表 [grad_g1, grad_g2, ..., grad_gm] x0: 初始点 mu: 障碍参数 epsilon: 终止条件阈值 max_iter: 最大迭代次数 返回: 最优解 x """ x = np.array(x0) m = len(g) k = 0 while k < max_iter: # 构造障碍函数及其梯度和 Hessian 矩阵 barrier_term = -mu * sum(np.log(-gi(x)) for gi in g if gi(x) < 0) L = f(x) + barrier_term grad_L = grad_f(x) - mu * sum(grad_gi(x) / (-gi(x)) for gi, grad_gi in zip(g, grad_g) if gi(x) < 0) hessian_L = hessian_f(x) + mu * sum( np.outer(grad_gi(x), grad_gi(x)) / (-gi(x))**2 - hessian_gi(x) / (-gi(x)) for gi, grad_gi, hessian_gi in zip(g, grad_g, hessian_g) if gi(x) < 0 ) # 牛顿求解 delta_x = np.linalg.solve(hessian_L, -grad_L) x_new = x + delta_x # 检查停止条件 if np.linalg.norm(grad_L) < epsilon: break x = x_new k += 1 return x ``` #### 关于内点的说明 内点的核心思想是通过引入障碍函数将约束优化问题转化为无约束优化问题。障碍函数的形式通常为对数形式,如 `-μ * Σ log(-g_i(x))`,其中 `g_i(x)` 是约束条件,`μ` 是障碍参数。随着迭代的进行,`μ` 逐渐减小,使得解逐渐逼近约束边界[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值