我最喜欢的敏捷开发工具

经过几年这个行业,如果你和我一样,一个敏捷的软件开发技术的风扇和嗜测试(测试,检验,检测!!!),只是收集的工具,库和语言,以方便系列他们的工作。 我经常使用这些聚集在这里,并记住那些谁对某些特殊理由,他们都在我的事业带:

  1. JUnit的 :我带有明显的,所有父亲开始。 除非你一直在防核地堡藏身在过去的一年,你听说过,或已使用单元测试。 如果你真的很幸运,甚至有可能起到测试驱动开发。 事实上,关于这个问题的很好的参考是测试驱动开发:通过示例
  2. 重构 :好,好,我将停止与老生常谈,但你不能谈论有关敏捷开发没有一个好的IDE,允许重构。 无论是IDE 的EclipseNetBeans的 ,我最喜欢的,提供了极好的支持。 我认为这是不普遍,这是落入遗忘的,不仅提供您的IDE重构实际上是那些存在,而这本书的推广这些技术是重构:改善既有代码的设计 在它有这么多,不被任何其他的IDE实施,多次不让自动化任务。 这是值得密切关注。
  3. Maven的 :在基础管理是一项复杂和错误方向,如果没有很好的管理,并最终交付给客户的产品是一个关键时刻,发展个月,他们最好的工具和技术之大成并且要给予正确的印象。 对我来说,Maven是管理工具,我选择的基础,得到了一系列的问题,并不想知道一些细节去掉,并给了我一个对项目健康报告等一系列的测试覆盖率报告,坚持代码格式约定,Javadoc中,等等... ...,所有在该项目的漂亮网站收集。 大来打动你的经理。
  4. EasyMock的 :理想情况下,测试设备必须有一个非常短的运行时间,几毫秒。 如果一开始就涉及到数据库,服务JEE平台,I / O一般,反馈循环程序重构,眉头变得非常缓慢,程序员站作为自然结果测试。 单元测试应该允许运行的时候,每天几十人。 这就是在EasyMock的,它可以让你取代假对象的系统部件与作为真正的对象相同的接口,并确认系统正在调用的预期。 魔术!
  5. DBUnit的 :而如何普及要在测试的测试大规模使用的表? 这是一个任务的DBUnit的可以插入和删除表中的数据在您的测试周期。
  6. HttpUnit的 :首先想到的HttpUnit的是,让单位的网络应用测试。 有了它你可以访问网址,填写表格栏位,发送,检查答案,最后,来模拟人类用户。 最近我一直在给它另外一个用途,高效的接入服务休息和检查响应数据。 非常好。
  7. Liquibase :我是这个项目的风扇。 通过使用Ruby on Rails的玩,我是真正的惊讶与架构变更管理数据库。 它通过小脚本是项目本身的一部分,包括保持版本的安装和运行轨道只有每一个新的更新必要的。 当在Java世界中的东西外观类似,我碰到这个库,并利用它成功地在我的应用程序。 您构建与作者和版本确定了银行的变化,XML文件和库需要更新通过应用版本之间的区别仅在数据库服务。 或者你也可以只在一个迭代结束时,产生的是在一个环境,需要更多的由DBA控制执行的脚本文件。 我建议。
  8. 水银 :我是一个长期的CVS和Subversion用户。 但是,分布式版本控制系统存在,并给予除了是非常快的整体一系列新的可能性。 Mercurial是使用NetBeans项目,大项目,如提交的业务许多国内,更新,roolbacks,diff文件几乎是瞬间完成的。 而没有进行整个资料库,并承诺在客户的网站。
  9. P6Spy的 :费拉拉过于简单,实用,也很关注自2003年以来不被升级。 允许您监视之间的代码和数据库服务器之间的通信,直入你的服务器,测试单位,只要插入适用的JDBC驱动程序。 总的调整和绝望的时刻大。
  10. OpenEJB的 :我承认,我花了从JEE平台很长一段时间带走创伤的EJB规范,总是喜欢选择,让我来测试和灵活性。 此时该项目使用非常阿帕奇仙人掌 ,但真的,是不是一回事。 该OpenEJB的是EJB容器服务器使用Apache Geronimo的 ,但可用于任何应用JSE在独立或与Tomcat的捆绑,或者在其单元测试,允许异步消息JMS,EJB的无状态,状态检测,单身,时间服务,总之,一切你期望从一个真正的服务器。 他还作出决定太聪明真正方便单元测试,如数据源的自动创建,它的使用,使用内存中的HSQLDB数据库。 尽管在EJB 3.1容器运,为在独立应用程序和单元测试使用合适的存在,规范指出,供应商只需要提供个人资料EJB精简版,而如果你需要休息,我尽量不在配置文件中发现,是不够的。
  11. HSQLDB :并没有什么对与数据库,而不是一个数据库,可以让你在内存中创建表只有你的单元测试更好。 就这样,就这么简单。
  12. SeleniumHQ :任何人谁曾经尝试自动化测试的用户界面,知道这不是一件容易的事。 用户界面是一个移动的目标,很难打。 我真的很佩服那些谁提出这一崇高的任务。 开发接口没有我的事,但我打了硒左右,并且是非常深刻的印象。 它具有测试昂贵的工具相同的功能,作为其与系统的互动记录,并有能力的机器上运行的操作系统和浏览器的各种配置网络相同的测试套件。 当然,你的下一个杀手级网络应用程序,值得努力。
  13. 巡航控制 :如果要找出快速传送到仓库的代码仍然工作,避免了整合阶段,没有什么比一个持续集成工具更好的噩梦。 我所经历的哈德森连续 ,但仍继续进行良好的老巡航控制。 虽然它是更难配置比他们年轻的兄弟姐妹,在其配置允许更大的灵活性,并具有很大的稳定性。 我保持两个计划任务:每次提交后的代码库建设,以及建设项目现场每天。
  14. JMeter的 :最后但并非最不重要的... ... 不要让后为什么你的功能测试,但可能为时已晚。 尤其是性能测试。 JMeter的可以模拟对数百个用户的应用来势汹汹的行为,并找到瓶颈以及这些泄漏是隐藏的。

远不是一个完整的清单,是我的清单。 当然,最后一个重要工具,是一个常识位,毕竟,试图获得100%的测试覆盖率无关。 这听起来理想,但它肯定是幼稚的。 始终记住Dijkstra算法的不朽词:

测试表明存在,而不是无缺陷。

书签和共享
3个评论到目前为止,添加你

博客提升到一等公民

我想提醒所有谁遵循这个博客我只是提出来一流的公民! 对于习惯了域的www.architecteam.com.br /人/坦率/博客 ,和www.architecteam.net /人/坦率/博客 ,你现在可以按照在同一本博客www.smallthoughts.com.br 我希望博客越来越重要,而这可能不会发生,而它是如此糟糕的待遇。 我会继续工作下去的其他地址,但如果你唯一的兴趣是遵循博客,我建议你更新你的feed阅读器客户端的新领域。 不着急。

书签和共享
2个评论到目前为止,添加你

通过翻译对葡萄牙Pharo例子的书!

在未来的几个月里,我将带头努力翻译这本书由Pharo例子对葡萄牙,我的小贡献,使这个语言和环境,无论口感更好的学生和葡萄牙语的开发,谁可能有一个主要障碍语言已知和不语。

我相信,无论是环境和语言是完全不同于任何我们在企业环境中有不同的,虽然在这种环境中提出的许多想法已超过30年,始终是一个振兴环境保持接触。

由于所有代码是开放的,在Smalltalk中,一切都可以访问,并能够改变的。 一切都是对象。 在语言,编译器和软件工程的主要研究人员测试与单元测试他们的想法第一次在这样的环境及其变种,面向方面编程和其他封闭。 您的社区当然是令人兴奋的,它的意见。

我创建了一个新的一页 ,以跟上翻译工作部分结果更新。 大家谁愿意作出贡献,感到邀请。 是否所有的欢迎。

书签和共享
将第一个评论

文化月1日结余

这个月应该是一个典型月份的“休假”(尽管没有感觉也许有过真正的假期...). 我几乎感觉有罪的评分:

  • 13部影片
  • 1班
  • 1本书

开始的电影,像一个按时间顺序的东西... ... 我看到Norbit ,并提出了一些很好笑... 我认为这将是一个很大的混乱,但它是一个很好的废话。 有趣的。 作为一个贫穷的孤儿,在孤儿院谁发现了他生活的热爱,但很快就失去了一个机会,一个巨大的女人,丑就可以了胶水的命运,并认为提交的屈辱和生活是什么值得他的故事。 但很快他的爱在城市,比以往任何时候更漂亮,但也有一些问题,骑士会帮助解决。 关于他的妻子和他的兄弟大很多笑话欺负,胖人在政治上反对和黑人不正确的。 以大斗的爆米花,看不妥协。

厄尔尼诺Orphanato更多的是同一块没有更多的参与丰富,不下吉尔摩-德尔托罗 一个惊悚片是粘贴在椅子上,抱着他的妻子/女友/不管手。 不诉诸血腥和怪物,设法惊喜即使是那些谁是体裁累。 它有味道厄尔尼诺laberinto德尔牧神 ,其中实部和虚都搞不清楚在幼稚的想象丢失。 我强烈推荐这一定是称职的整个电影情人一般文化的一部分!

007皇家赌场 我的父亲有一个所有旧007S非常完整的收集,并与我们的朋友我的最爱肖恩康纳利的。 看完与皮尔斯布鲁斯南,诚实最新的,我累了的动作场面完全不可能和不真实的,其中詹姆斯邦德是几乎是超人的超能力是无限的运气过量。 重点也不再是故事,强调,我发誓,我是在老电影兴奋电子工具,而是开始由过剩恼火。 我认为,董事已捕捉到这个球迷的不满,并创建了一个伟大的动作片,更原始,其中债券受伤,跌倒,需要打,是错误的,只有做好了自己的能力比他们的小工具,而高科技。 竖起大拇指! 爆米花中脉!

最终幻想VII:降临之子 我是英雄传奇视频游戏最终幻想RPG的优秀品质和惊人的图形永远的情人。 我在电脑上播放没有最终幻想VII但是完成游戏。 工作中,始终工作。 当我看到这个在出租标题,怀旧爆发,并希望观看比赛的基础上长期的。 事实上,据说或多或少像在同样的环境,以同样的字符的游戏事件的延续。 尽管优秀的图形(OK,我们总是给予适当的比例根据生产时间,不要期望头像... ...)的故事是枯燥的,没有惊险刺激,不保持良好的节奏,沉闷的对话... ... 最后,乏味。 令人失望。 如果你是怀旧的,像一台计算机图形并没有什么好做,去观看,否则擦肩而过。

贫民窟Millionare 或者葡萄牙语,谁想成为百万富翁? 一个贫穷的印度开始解决一个像我们这样的游戏万美元的方案问题,是对涉嫌作弊。 然后开始告诉他的传奇,正如你知道的所有问题的答案,为什么他们都参与:为爱他的生活​​搜索。 这部影片有一个非常漂亮的图片,他的故事是很漂亮,但关于它的听证会上,预计更多。 不过可以肯定的看,那肯定是电影,使其中的差别。

Kalifornia 另一部电影里布拉德皮特试图表明,不仅是对万人迷的角色。 他可以。 一个有趣的电影里一对夫妇开始他们的旅程到加利福尼亚,留下了关于连环杀手的书材料。 他们发现,他们乘坐的,自己,冷血杀手。 一个令人不安的惊悚片,更多的问题,使我们人类的天性。 推荐给朋友。

最后的苏格兰王 ,一个电影,给了最佳的福里斯特惠特克,对乌干达独裁者伊迪阿明达达总统奥斯卡演员。 我觉得电影是伪历史的,必要的诗意自由,但无论如何也是一位出色的电影,也呈现出令人不安的现实一直居住在非洲大陆。 非常好。

向上 ,高冒险! 卡通说谁只是为了孩子呢? 一段时间以来的主要电影公司知道,对于一个动画成功的真正公式是同时涉及公众和成年子女。 我有我的是否是良好,截至平衡疑问,我认为脚本是深受孩子比成人赞赏。 当然也有愚蠢和滑稽的场面,使孩子们笑,但其数量远小于,例如, 冰河时代超人特攻队 当然,一个让人赏心悦目的场景构成一定的节点,这是很多你所谓干的心脏。 值得的。

三河couleurs:高棉 我看所有的颜色的三部曲。 这是最后一次。 他们可能会扔石头的谁是邪教,但必须有胆量看所有三个。 好了,美丽的,处处流露出的激情,自私,爱,失落,和唧唧歪歪人性化的一面... ...但作为一个良好的生菜沙拉,豆腐是健康的,但无味。 只要不睡觉,因为我在那些谁希望看到电影的地方去时,即使是最差的。 如果你想打动你的朋友,请继续收看! 或者需要制定一个这样的片子的味道,或所有影迷聚集在他们的车轮和撒谎。 我试图找到三部影片之间的联系,我想:驼背的老太太在后台,这是试图把瓶​​子在​​回收箱。 这几乎是“哪里的金都”看到它,所以不要相信任何人声称看到谁不说,老太太的三部曲游戏。 别说我没提醒你。

所有SOBRE英里马德雷 欢迎到阿尔莫多瓦世界! 和电影版权来说,一个人谁在这里每部电影是一个骑在他头上的邀请。 我怕他。 我已经看到了男同性恋,异装癖,牧师谁强奸小男孩,谁怀孕癖修女,赶上艾滋病电影... 什么扭曲的小世界。 但你不能否认的家伙知道如何讲一个故事,展示了他笔下人类往往在极端情况下,。 这部影片是没有什么不同。 但我知道很多人谁也不会看它的肚子,所以要慎用。 这是阿莫多瓦的风格,面对最大的一记耳光。

老爷车 我能说什么关于克林特伊斯特伍德? 我认为世界失去了一位演员引起争议,但赢得了导演/制片/编剧的第一。 他的故事很简单,攻击如安乐死争议的问题百万美元宝贝 ,在征服了更人性化的远景硫磺岛来信 ,这对种族偏见所造成的失误。 我不知道为什么,有一个脚本的错误印象,我想克林特会是坏人,但很难不得到重视老人更badassmotherfucker的电影从未见过。 我推荐!

最新电影星际旅行给我的印象,纠正我值班跋涉,是一个电影的名字也值得。 我有我的帐户数量最多,尽管不看电影穿着尖尖的耳朵... ... 我喜欢速度,我喜欢的动作,所有的电视连续剧引用。 不要说看到我的英雄,青少年和一切的开始快感。 +乐肯定爆米花电影!

巴黎,我爱你 我能说什么... ... 法国电影是少数,我排除组。 在这部影片中,有著名的导演组讲述的爱情故事在巴黎举行。 大电影的旅行社或如果您计划去世界资本更美丽,但如果你想要的乐趣。 虐恋电影观众,这是给你的。

还有来自电影,我想我overdid这个月,我需要阅读更多,花的时间少了屏幕前... ... 虽然所有的补偿,我做我的第一个大的摩托车之旅,通过Jaguariúna,鱼,宪法保护,最后,黑芒。 此行产生了良好的照片 ,并给我看了他的长途旅行做好准备。 事实上,我们只看到尽可能多的Jaguariúna宪法保护传球,甚至停止采石和黑山。 石矿​​场而成的各种工艺品... 石(玻璃,陶瓷,滑石,铁),木制工艺品和装饰品。 虽然不喜欢工艺品集市,材料其实很不错又便宜,而且尽管空间不大,只是带来了吊灯那里,铁形郁金香。 它的茶几。 黑山是一个具有旅游潜力的城市,他们告诉我是一个浪漫的城市。 我不知道如果在一段时间或因无知,我错过了看到更多的自然美景,这是我的期望。 即便如此,其次是二级公路沥青,然后土地,并在一个特定的属性,不幸的是旅客收取访问抵达瀑布的梦想 ... ... 这是值得一游。

最后,结束文化活动,阅读务实思考和学习:重构湿件(务实程序员) 最近我一直在吸引到自我理解主题和访问新的思维创造性的方式。 我是一个确切的人,我练得是逻辑思维,分析和不犯错误(或至少推我...). 但在这么晚的日期,我的一些活动失去了颜色和味道,仿佛生命是一个伟大的小吃快餐平淡。 这本书认为,要实现新的生产力水平,我们exatóides,我们必须发展我们的创造力,让思维和学习涉及的整体性和创造性的思维和逻辑分析都,我们的模式。 对于许多人来说,似乎是自助书唧唧歪歪,但我决定克服自己的怀疑,并开始实践作为一种业余爱好绘画。 我开始读一本书,是参考部分: 对大脑的右侧新建绘图 ,我们将看到我走到哪里。 毕竟,专业化是机器和蚂蚁。

而直到下个月...

书签和共享
将第一个评论

文化平衡十二月

我会尝试启动一个健康的习惯,我在一些博客看到,考虑到文化月的股票。 这个月是非常薄弱,比分是:

  • 2本
  • 5部电影

我开始读的模块化Java:创建使用Spring和OSGi(务实程序员)灵活的应用 ,关于使用OSGi框架应用模块化的书。 我发现这本书非常好,有许多实用技巧,它教导模型的优势和不进行宣传,例如糖尿病或春分框架方面,一个主要的球员 ​​一本书。 它显示所有的选项,以及如何实现从一个迁移到另一个。 我开始对我的工作项目之一,以测试这些想法,我感到非常的使用JEE服务器,只有技术和框架,让我更多的灵活性和可测性长期工作方案重的创伤。

我也看过,其实也很迅速,因为它是非常容易阅读,这本书的激情编程:创建一个显着的软件开发事业(务实的生活) ,集合务实书架,拥有最有名的书的优秀部分语用程序员:从中级到主 这本书几乎是一个程序员,一个技术偏见失去了他的职业信仰的人的自助书。 我特别不喜欢自助书籍,平时唯一的人,他们帮助作者是自己的,但这种特别引起我的注意的时候了。 也许是因为它是一种集体反思时期,还是我亲自在我反思的时刻,这本书带来了一些老生常谈的是很好听别人的,和其他一些事情没有那么明显。 它使读者反映你的事业,你的决定就可以了,什么路径跟随,如果你想要一个梦幻般的职业生涯做你的爱,带来的不仅是大米和豆类,以表的每一天。 我推荐!

移动到电影,有些好的,有些不太好。 最后,经过大家一样,看着变形金刚:堕落者的复仇 很好! 对于那些像我这样的怀旧,谁看着长大的图纸,presentaos,优秀的品质机器人打,良好的效果,都好。 这个故事是一种懦弱,并战胜它,还等什么? 它的爆米花并为那些谁喜欢某种风格的乐趣。 它甚至有一个共同的未来创造一个更大,更复杂的机器人,它拥有一切跟我所见过的智能机器人和群会议的主材料机器人小套场景。 先来看看这个视频和联营公司,并会看到我在说什么。

这个月也看到了电影的Solaris ,科幻主演,惊奇,乔治克鲁尼。 说实话,这个电影我的感情都有些混乱。 剧本是好的,但给人的印象,可以更好地利用。 它有一个提示Gattaca ,一部电影,我的爱,在没有大预算的特殊效果,在于它是虚构的电影,然后在故事的重点。 并有足够的 ,另一片挺喜欢的,有关剧本。 但乔治克鲁尼没有说服小说,最好是在医生继续为ER或在许多其他动作片制成。 把你的列表的末尾。

还观看是人 ,只有证实了我先前的印象,我更喜欢做喜剧在金凯瑞不必鬼脸。 好一点的电影,但弱,我更喜欢布鲁斯全能我,我自己和艾琳吉姆的漫画,或艺术品的美丽心灵的永恒阳光 ,这是吉姆,但他的戏剧探索静脉。 如果视频商店并没有什么更好的你可以选择其中产生一个笑。

我去一些亲戚看头像 ,没有寄予厚望,认为它甚至会电影/图童趣。 什么是错误的。 不可思议的视觉效果,令人兴奋的脚本,精湛! 其实,视觉效果所描述的下一部分... 他们设法使所有植物和动物之间有较高的凝聚力与生物相似的解剖因素,(毕竟,所有的字符串有对称的身体,有眼,肺,降低superioes成员,相同数量等... ...)通配符和人物,该死的,总是怀疑是否是CGI或打扮的演员。 我还需要研究如何使用的技术。 如果你还没有看到它,快跑! 但尝试看看其中一个三维房间,可惜我不是其中之一,但我认为应该是经验丰富得多。

最后, 在条纹睡衣的男孩 ,很不错,你可以看无惧,但我预期的东西... ... 我不知道,更多。 较剧,涉及二战,但现在涉及儿童,这使得它更难过,而这样的。 我觉得我试图拉几个眼泪,但它为我工作。 无论是戏剧,涉及在第二次战争儿童,这是令人惊讶无论是在脚本和视觉? 观看厄尔尼诺laberinto德尔牧神 ,另一个伟大的电影导演吉尔摩-德尔托罗。

还试图看灾难电影 ,但我不能,我在第15分钟停止。 电影。 我怕有人会看到我在看它。 远离这个称号,或在出租左,应该杀在这个过程中的一些神经元。 什么不好的电影! 从打闹,毫无意义的,无聊。

直到下个月!

书签和共享
2个评论到目前为止,添加你

记住那些谁缺乏

我不能不佩服喜欢的人Edsger迪杰斯特拉 ,谁当他做了的地区,工作和学习。区别 这些人都是一种激励,应该永远记住。 Dijkstra算法在他曾经写过关于结构化编程注意事项

这些说明有“写入自己的信”我写下他们的地位,因为没有这样做,我发现自己重复一遍又一遍相同的论点。 当读我写,我也并不总是不满意。

这个小片段已经显示出所有与完美,他作为一名研究人员不断改进追求他的当务之急。

哦,我有这么多好东西来为自己写的这个巨人。

书签和共享
将第一个评论

在二郎丸-编译程序

了解进入和退出二郎壳是第一步,但作用不大。 这项活动开始,当我们建立我们自己的方案。

我一直在使用Emacs的写在我的Erlang程序,它有一种气氛,色彩的元素,有助于密切括号和完整的表达。

功能性语言在本质上是递归的,则事你好世界,没有什么比开始一个递归函数的例子。 如何对阶乘:

-module(lib).
-export([fac/1]).

fac(0) ->
    1;
fac(N) ->
    N * fac(N-1).

O código acima pode ser escrito num arquivo e compilado, e demonstra algumas coisas básicas da linguagem. Primeiro, todo comando deve terminar com um ponto ".". Na linha 1 e 2 estão algumas diretivas obrigatórias de todo código fonte, module e export . Toda diretiva de compilação começa com o sinal de "-". A diretiva module declara o nome do módulo deste arquivo. Em Erlang, cada arquivo é um módulo, ou seja, um conjunto coeso de funções. Normalmente se o módulo se chama "lib" como o exemplo, então o arquivo precisa se chamar "lib.erl", porque com esta convenção o compilador consegue encontrá-lo automaticamente. Em Erlang, uma lista de elementos é representada usando colchetes "[]" com cada elemento separado por vírgulas. Alguns exemplos de listas:


[3,78,2,7,3].
["hello", "world"].
[hello, world].

A primeira lista contêm 5 números inteiros, a segunda 2 cadeias de caracteres, e a terceira 2 átomos. Então como podemos perceber a segunda diretiva de compilação export recebe como argumento uma lista, onde cada elemento é o nome de uma função que o módulo exporta para uso externo e o número de argumentos. Em Erlang, funções com mesmo nome mas número diferente de argumentos são funções completamente diferentes. Toda função em Erlang precisa retornar algum valor.

Uma função em Erlang sempre tem o formato Assinatura -> CódigoParaExecução. A primeira parte determina o nome e os argumentos da função, enquanto a segunda contêm o que será executado. Em Erlang a execução de uma função sempre envolve comparação de padrões, e uma função pode declarar vários padrões separados por ";". Cada padrão é testado contra os argumentos, em sequência, até que algum se aplique ou caso contrário, é lançado um erro.

No caso do fatorial, o primeiro padrão é "fac(0) -> 1". Ao se chamar esta função com o primeiro argumento igual a zero, será retornado zero. O segundo padrão é "fac(N) -> N * fac(N - 1)". Ou seja, para qualquer valor de parâmetro diferente de zero, o segundo padrão é invocado, e faz uma chamada recursiva para a mesma função, até que o parâmetro seja igual a zero, e então é executado o código do primeiro padrão, e a recursão pára.

Ok, hora de compilar e executar esse código. Salve um arquivo com o nome "lib.erl" com o conteúdo acima e no mesmo diretório execute:

fbdo@Marvin:~/Projetos/Erlang$ erl
Erlang (BEAM) emulator version 5.5.5 [async-threads:0] [kernel-poll:false]

Eshell V5.5.5 (abort with ^G)
1> c(lib).
{ok,lib}
2> lib:fac(10).
3628800
3>

Como pode ser visto, invoquei o shell usando o comando "erl", compilei o código usando "c(lib)", recebi a mensagem de que a compilação teve sucesso "{ok,lib}" e então invoquei a função que acabei de compilar usando a convenção modulo:função "lib:fac(10)". E agora, para impressionar os amigos, que tal calcular o fatorial de 1000?


3> lib:fac(1000).
402387260077093773543702433923003985719374864210714632543799910429938512398629020592044\\
208486969404800479988610197196058631666872994808558901323829669944590997424504087073759\\
918823627727188732519779505950995276120874975462497043601418278094646496291056393887437\\
886487337119181045825783647849977012476632889835955735432513185323958463075557409114262\\
417474349347553428646576611667797396668820291207379143853719588249808126867838374559731\\
746136085379534524221586593201928090878297308431392844403281231558611036976801357304216\\
168747609675871348312025478589320767169132448426236131412508780208000261683151027341827\\
977704784635868170164365024153691398281264810213092761244896359928705114964975419909342\\
221566832572080821333186116811553615836546984046708975602900950537616475847728421889679\\
646244945160765353408198901385442487984959953319101723355556602139450399736280750137837\\
615307127761926849034352625200015888535147331611702103968175921510907788019393178114194\\
545257223865541461062892187960223838971476088506276862967146674697562911234082439208160\\
153780889893964518263243671616762179168909779911903754031274622289988005195444414282012\\
187361745992642956581746628302955570299024324153181617210465832036786906117260158783520\\
751516284225540265170483304226143974286933061690897968482590125458327168226458066526769\\
958652682272807075781391858178889652208164348344825993266043367660176999612831860788386\\
150279465955131156552036093988180612138558600301435694527224206344631797460594682573103\\
790084024432438465657245014402821885252470935190620929023136493273497565513958720559654\\
228749774011413346962715422845862377387538230483865688976461927383814900140767310446640\\
259899490222221765904339901886018566526485061799702356193897017860040811889729918311021\\
171229845901641921068884387121855646124960798722908519296819372388642614839657382291123\\
125024186649353143970137428531926649875337218940694281434118520158014123344828015051399\\
694290153483077644569099073152433278288269864602789864321139083506217095002597389863554\\
277196742822248757586765752344220207573630569498825087968928162753848863396909959826280\\
956121450994871701244516461260379029309120889086942028510640182154399457156805941872748\\
998094254742173582401063677404595741785160829230135358081840096996372524230560855903700\\
624271243416909004153690105933983835777939410970027753472000000000000000000000000000000\\
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\\
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\\
000000000000000000000000000000000000000000000
4>

Uau, isso foi rápido. E o mais impressionante: este número gigante que no meu terminal ocupa 30 linhas e que foi calculado por uma função recursiva não estourou a pilha de execução, nem o tamanho da variável. Para pessoas que, como eu, têm mais experiência com C/C++ ou Java, é quase mágico o que acaba de acontecer. Mas as magias tem nome, e se chamam otimização da recursão em cauda e conversão implícita de tipos.

Em Erlang só existem dois tipos numéricos, o inteiro e o número de ponto flutuante. E eles nunca estouram porque não têm tamanhos fixos, e sim crescem enquanto houver memória disponível.

Para linguagens funcionais, a recursão é parte essencial, já que não existem operadores de laços. Então quase todas otimizam o quanto podem as chamadas recursivas, e no caso do fatorial a otimização é trivial, já que não existem operações a serem realizadas após a chamada recursiva, o que é chamado de recursão em cauda. O que a máquina virtual Erlang faz, ao invés de empilhar a chamada recursiva, é sempre substituir o endereço de retorno da função pelo endereço da função chamada, mantendo a pilha com tamanho constante. Nada de "StackOverflowException". É como se substituíssemos a função recursiva por uma interativa equivalente:


função fatorial(x: inteiro): inteiro
var i, aux: inteiro
inicio
aux <- 1;
para i de 1 até x faça
aux <- aux * i
fim_para
fatorial <- aux
fim

E por hoje chega de diversão com funções recursivas.

书签和共享
Leave the first comment

E o reconhecimento de voz/imagem se tornam commodities...

Ao abrir minha Communications ACM deste mês, vi um artigo na sessão BLOG@CACM que me chamou a atenção. O artigo de Tessa Lau Hello Computer comentava sobre sua satisfação com seu novo GPS, um Garmin Nüvi 850. Não por simplesmente ser um excelente GPS, mas sim por ter uma interface ativada por voz.

Isso me fez lembrar de um pequeno projeto em que me envolvi com alguns amigos, a algum tempo, por nós chamado de projeto MONOH (MOmmy, NO Hands!). Resumindo, o objetivo do projeto era criar um plugin para a IDE Netbeans que fornecesse a capacidade da ativação por voz de alguns comandos normalmente acessíveis via teclas de atalho. Cá entre nós, e que ninguém nos ouça, confesso que a razão principal de investir neste projeto era, na época, a de poder ganhar o NetBeans Innovators Grants Contest , o que conseguimos com relativo sucesso. Eu acredito que um fator determinante para nossa vitória foi exatamente o fator coolness da proposta, afinal de contas todo mundo acha muito legal parar de usar o mouse e o teclado e começar a falar com a máquina. De uma forma geral, o que queremos mesmo é parar de ter que nos relacionar com todas as inúmeras máquinas que nos cercam no dia-a-dia usando a linguagem delas, para poder usar a nossa. Acabar de uma vez por todas com este problema de impedância.

O que me deixa mais chateado é ter que confessar também que todo o mérito pelo reconhecimento de voz do nosso projeto não é de ninguém da equipe, e sim do projeto Sphinx4 . Este projeto, apoiado pela Carnegie Mellon University entre outros, é um reconhecedor de voz escrito em Java, estado-da-arte, livre e open source . Nosso mérito foi o de estudar a API NetBeans, estudar a API do Sphinx4, e colar os dois. É assombroso a qualidade do que se tem hoje em dia na forma de software livre e open source . Ou seja, para fazer hoje um aplicativo que reconhece a voz, não é mais necessário um doutorado. Com tempo e paciência qualquer um pode impressionar seus amigos.

Outro exemplo de como o relacionamento homem-máquina tem melhorado, mas é quase bobagem mencionar, são essas máquinas fotográficas que temos hoje que somente batem a foto quando as pessoas focalizadas sorriem. Elas são quase banais, estão a venda em qualquer loja por preços acessíveis a qualquer mortal. Será que somente eu me assombro em como um simplório chip que cabe numa máquina fotográfica é capaz de fazer o reconhecimento de face, e determinar se alguém está sorrindo?!?!

E por último, um vídeo no YouTube também fez minha cabeça explodir. O mundo foi assolado pela febre do Wii, mas isso poderá ser nada comparado ao Project Natal . O Project Natal , que tem seu nome em homenagem a, pasmem, nossa cidade de Natal no Rio Grande do Norte graças ao brasileiro que comanda o projeto, leva a iteratividade a um outro patamar: não há controles! Somente você, balançando suas mãos e pernas na frente do console, tendo seus movimentos reproduzidos na tela. Droga, serei obrigado a comprar um XBox 360 (além de um PS3 quando sair o God of War III).

Tudo isso me faz ver que estamos no momento histórico onde aquelas inúmeras pesquisas que a décadas não passavam de estudo acadêmico estão chegando às prateleiras, estão aí nas ruas, não assombram mais ninguém. Provavelmente nossos filhos vão achar engraçado nossas histórias de como era usar uma bugiganga com 102 teclas e uma outra com 2 teclas que movíamos na mesa pra lá e pra cá para fazer nossos computadores nos entenderem. Finalmente estamos no ponto histórico onde estudos do guarda chuva de inteligência artificial, por muitos considerados distantes e áridos, viraram commodities , na mão de todo mundo, sem que ninguém nem precise saber o quão sofisticado aquilo na verdade é para poder usar, e poder usufruir.

Não espere mais, comece a falar com seu computador hoje! Ele um dia poderá entender.

书签和共享
Leave the first comment

Erlang em Pílulas - Entrando e saindo do shell

Como muitas vezes é dito por Andrew Hunt, autor do livro The Pragmatic Programmer: From Journeyman to Master (recomendo!) é muito bom para todo programador aprender pelo menos duas novas linguagens por ano. Já a algum tempo tenho flertado com Erlang, e uma das razões é todo o alvoroço na comunidade de desenvolvedores a volta de linguagens funcionais, e outra pelos meus interesses em desenvolvimento de código paralelo e concorrente.

E é justamente nestes pontos em que Erlang mostra a que veio, e é por este motivo todo o alvoroço. Erlang foi desenvolvido nos laboratórios da Ericsson para o desenvolvimento de centrais telefonicas, num ambiente com requisitos de tempo real mais leves e alta disponibilidade. O fato de ser uma linguagem funcional faz ter uma característica muito comum em muitas linguagens funcionais: a ausência de efeitos colaterais em suas funções, não existindo, com isso, a necessidade da existência de mecanismos de sincronização para áreas de memória compartilhada. Existem primitivas na linguagem que permitem o desenvolvimento de software paralelo e concorrente de forma muito mais simples do que no mundo procedural das principais linguagens como Java, Python ou C/C++, usando passagem de mensagens, implementando o modelo de atores ( Actor Model ). Quem já teve que implementar um programa concorrente usando múltiplas threads sabe que não é uma das tarefas mais triviais. Mas isso tudo é muito bem explicado em qualquer sítio na internet sobre Erlang, o que eu gostaria mesmo é de demonstrar um pouco de como é desenvolver programas usando esta linguagem.

Primeiro, instale uma versão de Erlang na sua plataforma preferida. Eu uso linux/Ubuntu, então meus exemplos vão ter a cara desta plataforma. Ao executar o comando erl na linha de comando, você verá algo como isto:


Erlang (BEAM) emulator version 5.5.5

[/source]

[async-threads:0] [kernel-poll:false]

Eshell V5.5.5 (abort with ^G)
1>

Agora digite o seguinte:


1> 2 + 5.
7
2>

Primeira coisa a perceber é que o shell do Erlang numera as linhas conforme você dá entrada. Todo comando em Erlang deve terminar com ponto "." e um enter . Todo comando devolve alguma coisa, e ao digitar 2 + 5 ele corretamente devolveu 7.

Para terminar com o shell do Erlang, basta um Control-C. Você verá a seguinte saída:


BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
(v)ersion (k)ill (D)b-tables (d)istribution

Digite "a" para deixar o shell.

Outra forma de deixar o sistema, é digitando "halt()":


1> halt().
fbdo@Marvin:~$

Na próxima pílula de Erlang, vou falar um pouco sobre como compilar um programa nesta linguagem.

书签和共享
3 comments so far, add yours

Usos de Computação Paralela e Distribuída em Computação Evolutiva

Evolution, from Man to Evolutionary Algorithms

Evolution, from Man to Evolutionary Algorithms

O texto abaixo foi apresentado pelo grupo Ariel Malves, Rodrigo Marques e Fabio Oliveira como trabalho final no curso de Algoritmos Evolutivos, sigla IA770, ministrado no Departamento de Engenharia da Computação e Automação Industrial da Universidade Estadual de Campinas (Unicamp).

Resumo: Os Algoritmos Evolutivos(AEs) têm se mostrado muito eficientes em diversos problemas extremamente difíceis de serem atacados por métodos mais clássicos, e por serem naturalmente paralelizáveis e necessitarem de muitos recursos computacionais, diversas técnicas estão sendo utilizadas para melhorar seu desempenho, elevando ainda mais a utilidade prática desta ferramenta. No entanto, muitas vezes a paralelização do algoritmo leva a alterações estruturais que mudam o seu comportamento comparado a um AE seqüencial, ou então aumentam mais ainda o leque já vasto de parâmetros para ajuste do mesmo. Pretendemos mostrar uma taxonomia dos AEs paralelos e distribuídos, suas principais diferenças, parâmetros e ganhos com relação aos seqüenciais, e construir um arcabouço para comparação do desempenho de um algoritmo representativo contra um semelhante porém seqüencial, demonstrando com um exemplo prático suas características.

Introdução

Os Algoritmos Evolutivos(AEs) mantêm uma população de possíveis soluções que competem entre si seguindo a metáfora da Teoria Evolutiva Moderna. Os operadores envolvidos em AEs para problemas não triviais precisam de muitos recursos computacionais, e por isso a busca por melhores técnicas para a melhora de seu desempenho, como o uso de computação paralela e distribuída.

Em geral, os operadores dos AEs como a recombinação e a mutação, e mesmo a avaliação do fitness , se concentram em um ou em alguns poucos indivíduos da população, tornando os AEs muito propícios a paralelização. Mesmo o operador seleção, que em geral avalia todos os indivíduos simultaneamente, e por isso mesmo seria um gargalo a paralelização, pode ser alterado para se adaptar melhor a este paradigma, ou então podemos nos ater a somente ao subconjunto das suas variantes que se utilizam da informação de poucos indivíduos, como por exemplo o operador torneio.

Normalmente, quando se aplica técnicas de paralelização, busca-se tão e somente diminuição do tempo necessário para a execução do algoritmo. No entanto, no caso de AEs, há evidências [ 1 ][ 2 ] não somente da redução do tempo necessário, mas também da maior manutenção da diversidade, da melhora na capacidade de busca de múltiplas soluções em problemas multi-modais, e na maior qualidade do resultado.

A melhora da qualidade do resultado merece uma discussão mais detalhada. Ao se executar um algoritmo usando N threads de execução ou então ao se executar em N nós (máquinas) diferentes em uma rede no caso de sua distribuição, pode-se esperar uma redução no tempo de execução proporcional a N. No entanto, esta expectativa idealizada é muitas vezes ingênua, já que tanto uma técnica quanto a outra dependem de instrumentos de comunicação e sincronização que no caso seqüencial não são necessários, e sobrecarregam a execução do algoritmo. Mas no caso dos AEs, ao se executar o mesmo algoritmo de forma seqüencial e de forma paralela até que encontrem uma solução de mesma qualidade, muitos experimentos têm mostrado uma melhora super linear do tempo de execução [ 3 ][ 4 ].

Taxonomia

De acordo com o trabalho de Erick Cantú-Paz [ 5 ], há três tipos principais de AEs paralelos:

  1. População única, mestre/escravo: A população é única como nos AEs seqüenciais, mas a avaliação do fitness é distribuída em múltiplos processadores. Como os operadores consideram a população inteira, também são conhecidos como AEs paralelos globais.
  2. População única, modelo celular: Muito utilizado em computadores massivamente paralelos, consiste de uma população estruturada distribuída. A seleção e a recombinação são restritas a uma pequena vizinhança, mas como há a sobreposição de vizinhanças, há iterações entre todos os indivíduos. Busca ter idealmente um único indivíduo por processo.
  3. Múltiplas populações, modelo ilha: Consiste em sub-populações que trocam indivíduos ocasionalmente. Esta troca de indivíduos é chamada migração. É o tipo mais popular por permitir o uso de hardware comum e acessível, porém não é completamente compreendido, e introduz mudanças fundamentais na operação dos AEs.

É claro que neste espectro, existem muitas abordagens híbridas, como por exemplo com arquiteturas combinando múltiplas populações com mestre/escravo. Estas abordagens híbridas são também chamadas de AEs paralelos hierárquicos.

Modelo Mestre/Escravo

O modelo mestre/escravo sugere que a cada geração o processo mestre contendo a população delegue a tarefa de cálculo do fitness para cada um dos processos escravos (ver figura 1) para então devolver esta informação para o mestre. Cabe então ao mestre, assim que todos os escravos retornarem suas informações, as tarefas de seleção dos pais para a próxima geração e criação de novos indivíduos utilizando operadores de recombinação e mutação. É uma técnica simples, que pode ser aplicada em problemas onde a avaliação do fitness no problema atacado seja computacionalmente onerosa.

Figura 1. Modelo Mestre/Escravo

Figura 1. Modelo Mestre/Escravo

Como a população é única e os operadores consideram a população total para atuar, esta é a técnica de paralelismo que mais se assemelha a abordagem clássica de um AE seqüencial e uma aplicação pouco cuidadosa dessa abordagem pode levar a uma imprecisa interpretação dos ganhos em desempenho ou precisão.

Entre o processo mestre e os escravos podemos ter uma comunicação síncrona, onde o mestre interrompe sua execução e aguarda que os escravos retornem a ele todos os resultados, mesmo que existam diferenças de desempenho entre os nós. Obviamente, este tipo de implementação resulta em tempo ocioso de máquina, aproveitando inadequadamente o hardware disponível.

Sempre temos duas comunicações entre mestre-escravo para cada nó adicional, primeiramente no envio da fração da população para avaliação e depois no retorno do fitness avaliado.

Este tempo de comunicação gasto proporcional ao número de escravos pode, dependendo da infra-estrutura utilizada, ser inclusive maior que o ganho efetivo de desempenho conseguido pelo paralelismo. Podemos então ver que quanto maior o número de escravos nesta topologia, melhor a distribuição da tarefa de avaliação de fitness e portanto menor tempo computacional gasto na mesma. Por outro lado, a mesma condição implica em um maior tempo gasto na comunicação entre mestre e escravos.

Este é um compromisso que depende do tempo necessário para avaliar um indivíduo, da quantidade de escravos utilizada e de constantes que dependem do hardware utilizado, mas sugere que existe um número ótimo de escravos que minimize este tempo de execução [ 6 ].

Uma implementação assíncrona pode ser considerada, embora perca um pouco da analogia e das características que assemelham o algoritmo a um AE seqüencial, introduzindo outros fatores que podem ser benéficos de acordo com a classe do problema minimizando os gastos com o tempo de comunicação.

Numa implementação assíncrona o mestre não esperaria pela resposta dos escravos, e trabalharia com as informações que estivessem disponíveis no momento. Cada escravo ainda teria uma fração de população a avaliar mas devolveria os valores de fitness assim que o processamento estivesse concluído. Neste caso a avaliação em um processador mais lento atuaria em gerações espaçadas de acordo com a velocidade do mestre.

Outros operadores como a recombinação e a mutação também são sugeridos como passíveis de execução paralela por terem as mesmas características de independência entre indivíduos, mas por serem operadores normalmente pouco custosos a perda com o aumento das comunicações entre mestre-escravo faz com que esta abordagem seja pouco promissora na maioria dos casos.

Modelo Celular

Um AE celular ou de paralelismo massivo é uma proposta que difere significativamente de um AE tradicional. Neste modelo temos uma população distribuída em uma rede, um indivíduo por nó, como por exemplo num espaço bidimensional, formando uma grade que limita as interações entre os indivíduos, permitindo apenas a interação entre elementos vizinhos (ver figura 2). Como vimos no caso mestre-escravo, existe um custo alto na comunicação entre nós, e esta abordagem só se mostra vantajosa com o uso de hardware específico, como computadores ou processadores massivamente paralelos.

Figura 2. Modelo Celular

Figura 2. Modelo Celular

Os operadores genéticos de seleção e recombinação ocorrem apenas entre indivíduos próximos. Por esta característica, e por representar cada indivíduo na forma de um processo independente interagindo com o meio, oferece uma metáfora mais próxima da real para pesquisadores interessados no estudo de vida artificial.

A forma de implementação varia de acordo com a aplicação de interesse, podendo ter regiões de vizinhança sobrepostas, estruturas multidimensionais, ou mesmo migrações distantes ou disseminação dos melhores indivíduos de forma que não se limitem apenas a sua vizinhança.

Podemos pensar no AE celular como sendo uma adaptação de um AE tradicional que tenha em paralelo componentes do algoritmo como seleção dos indivíduos para recombinação, a própria recombinação, mutação, e a avaliação de fitness . Neste caso o modelo muito se assemelha aos outros modelos propostos tendo um foco maior na topologia e na distância relativa entre os indivíduos.

Portando uma mudança fundamental no AE é remoção da seleção global dos pais para recombinação, limitando-os a vizinhança. O comportamento é alterado significantemente com novos resultados e novos parâmetros como o tamanho da população e as fronteiras de vizinhança, que assumem papel importante nesta abordagem, controlando inclusive a pressão seletiva do algoritmo.

A parametrização ainda contaria com a topologia da rede, os métodos de seleção, recombinação, mutação, tamanho da população e sua distribuição entre múltiplos processadores e número de novos indivíduos gerados a cada iteração, considerando seu espaço de atuação.

Modelo Ilha

A característica fundamental deste modelo é o uso de algumas poucas populações relativamente grandes e do operador de migração. Cada sub-população é processada por um nó e atua como se fosse uma população totalmente independente, mas de acordo com uma política de migração, recebe e envia indivíduos de/para outros nós, distribuindo as informações sobre as soluções candidatas até o momento (ver figura 3).

distribuido

Figura 3. Modelo Ilha

Experimentos considerando a razão de migração mostraram que para populações isoladas (sem migração), a qualidade do resultado final era pior do que o de uma única população. Para taxas de migração altas, a qualidade era igual a de uma única população.

O excesso de comunicação, da mesma forma como no caso mestre/escravo, degrada o tempo de execução do algoritmo. Existem também indícios de que existe para cada problema e tamanho da população, uma quantidade ideal de nós.

Olhando pela ótica da metáfora natural, pode-se dizer que o modelo ilha reproduz o comportamento e a comunicação entre ecossistemas separados por barreiras naturais, e o resultado se assemelha a teoria do equilíbrio pontual ( punctuated equilibria ) da biologia evolutiva [ 2 ], onde os diversos ecossistemas e seus organismos vivem em equilíbrio a maior parte do tempo, e a alteração do ambiente produz um rápido movimento evolucionário. O modelo ilha adiciona um novo operador de migração aos demais operadores clássicos, e este operador, ao trazer novos indivíduos a uma população estável, gera um impulso evolucionário semelhante. O aumento da capacidade de exploração deste modelo, a evolução de sub-populações isoladas e este mecanismo de perturbação por migração são as chaves para explicar referências apontando melhoras de desempenho super lineares [ 3 ].

A popularidade desse modelo advém da sua simplicidade, facilidade de implementação e possibilidade de aplicação em hardware acessível, como em uma rede de estações de trabalho comuns.

Este modelo ainda oferece muita área para estudo, com muitas questões ainda não respondidas, como por exemplo qual a melhor forma da topologia de rede, ou então qual a melhor taxa e o intervalo de migração.

Migração

Na maioria dos esquemas de migração, ela é síncrona, ocorrendo em intervalo constante. Nesta forma de implementação, todos os nós pulsam numa mesma geração, parando no ponto de sincronização onde ocorre a troca de indivíduos. Pode também ser assíncrono, e neste caso cada nó mantêm uma fila de indivíduos recebidos, numa metáfora de caixa postal, nunca tendo que aguardar o envio/recebimento de indivíduos para continuar com o processamento, perdendo-se com isso o conceito de geração da população como um todo. Alguns esquemas aplicam a migração somente quando a sub-população está próxima de convergir, restaurando a diversidade.

Aliás, uma questão recorrente é de quando deve ocorrer a migração. Ocorrendo muito cedo, os migrantes podem ter building blocks pequenos demais para influenciar a população. Ocorrendo tardiamente, cada nó pode perder diversidade e estagnar num ótimo local, também consumindo preciosos recursos computacionais.

Há referências de um esquema diferente desenvolvido [ 5 ], onde processadores escravos evoluíam suas sub-populações e enviavam seus melhores indivíduos para o mestre, e este então aplicava a seleção com viés para os melhores, e enviava os selecionados para os escravos. Mostrou aumento de desempenho super-linear.

Topologia de rede

A topologia da rede do modelo ilha determina o quão rápido ou quão devagar uma boa solução é disseminada para as demais populações. Também determina o custo de comunicação da rede.

Normalmente são usadas topologias estáticas, que são usadas do começo ao fim do algoritmo, mas já foram feitos experimentos com topologias dinâmicas, onde a migração é realizada entre populações de acordo com algum critério, como diversidade da população, ou então a distância genotípica entre populações, ou até mesmo de forma aleatória.

Híbridos

E, como não poderia deixar de ser, como com os demais parâmetros dos AEs seqüenciais, existe muito espaço para a criatividade em termos de topologias e hibridizações.

Na figura 4, podemos ver um modelo híbrido ilha/celular, onde computadores massivamente paralelos desenvolvem suas sub-populações de forma quase independente, trocando informações de seus indivíduos de tempos em tempos como no modelo ilha.

Figura 4. Modelo Híbrido Ilha + Celular

Figura 4. Modelo Híbrido Ilha + Celular

Já na figura 5 podemos ver um modelo híbrido ilha/mestre-escravo, onde cada nó do modelo ilha delega a tarefa do cálculo da função de avaliação para uma outra coleção de computadores.

Figura 5. Modelo Híbrido Ilha + Mestre/Escravo

Figura 5. Modelo Híbrido Ilha + Mestre/Escravo

E finalmente, na figura 6 uma possível configuração ilha/ilha, onde em cada nó do modelo ilha existe um outro modelo ilha, com uma rede mais densa e de maior velocidade.

Figura 6. Modelo Ilha + Ilha

Figura 6. Modelo Ilha + Ilha

Cada modelo e suas variantes sempre devem ser criados e parametrizados de acordo com o problema atacado, como já é hábito no modelo seqüencial.

Problema de Teste

Para confirmar os dados teóricos até agora expostos, realizamos alguns experimentos. E para tanto buscamos na literatura um problema conhecido usado para realizar a comparação entre as diversas implementações.

Usamos o problema subset sum como detalhado em [ 9 ]. O problema subset sum é NP-Completo, e tem diversas formas, entre elas as mais conhecidas são: dado um conjunto de números W = \ {w_1,w_2 ,..., w_n \} de n inteiros e uma constante M, encontrar um subconjunto V \ subseteq W tal que a soma dos elementos em V é igual a M. Esta versão é basicamente um problema de decisão. Já um problema de otimização seria o de encontrar V tal que a soma dos elementos em V se aproxime de M, sem nunca ultrapassá-lo. A segunda forma será a usada por nós em nossos experimentos.

Nossas instâncias do problema foram criadas com 100000 elementos que foram aleatoriamente escolhidos com distribuição uniforme no intervalo [0.10 ^ 6] . Como pode ser notado, nossa variante é maior do que descrito em [ 9 ], e isto foi feito propositalmente pois as instâncias na forma descritas não se mostraram desafiadoras tanto para o algoritmo seqüencial quanto para o distribuído, obrigando-nos a aumentar seu tamanho e usar o procedimento de criação descrito como inspiração.

Para podermos comparar a nossa implementação quanto a eficiência contra metodologias clássicas, implementamos também um algoritmo para cálculo exato e outro para cálculo aproximado dado um percentual de erro aceitável, como descrito em [ 10 ]. Como o algoritmo para cálculo exato precisa de tempo e memória exponenciais em relação ao tamanho do problema, e lembrando que no caso do subset sum estamos falando de 2 ^ N possíveis subconjuntos, o algoritmo exato só é viável para instâncias muito pequenas. Em estações de trabalho típicas de hoje, fomos capazes de resolver instâncias com até 40 elementos, para instâncias maiores não houve memória suficiente. Já o algoritmo aproximado precisa de tempo e memória polinomiais, e resolveu uma instância com 10000 elementos em 68 minutos em uma estação de trabalho típica. Para uma instância de 100000 elementos, dois dias de execução não foram suficientes para se encontrar uma boa solução com o algoritmo aproximado.

Detalhes de implementação

De todos os modelos apresentados, escolhemos o modelo ilha para ser implementado, por ser bem diferente do AE seqüencial, e ao mesmo permitir a implementação em hardware facilmente acessível.

A representação escolhida foi de uma cadeia binária C com 100000 bits. Cada n-ésimo bit ativo indicava o uso do elemento n do conjunto original. Seja C =(\ VEC {X} =(X_1,x_2 ,..., X_ {100000})) e P(\ VEC {X})= \ sum_ {i = 1} ^ {100000} w_i x_i , a função objetivo utilizada foi:

F(\ VEC {X})= A \ CDOT P(\ VEC {X})+(1 - A)\ CDOT \ lfloor(M - 0.1 \ CDOT P(\ VEC {X}))\ rfloor

onde A = 1 quando \ VEC {X} é factível, i.e., quando M - P(\ VEC {X})\ GEQ 0 , e A = 0 nos outros casos. Dessa maneira, o valor obtido como fitness é a própria soma do sub-conjunto representado por C, ou então o valor objetivo e uma penalidade de um décimo de P(\ VEC {X}) para soluções infactíveis.

Para que obtivéssemos um maior controle do processo de seleção, usamos o operador de torneio para escolha dos indivíduos que iriam compor a lista de pais para criação de uma nova geração.

Importante também salientar que, no processo de seleção, os filhos substituem os pais em uma configuração (\亩,\λ) . Através de testes preliminares, fora constado que o tempo de convergência estava sendo excessivamente prejudicado pela perda de boas soluções, fato que nos motivou a implementar o operador de elitismo, que mantinha na população a melhor solução encontrada.

Na recombinação utilizamos o operador de crossover de pois pontos e a mutação pontual. A importância do operador de crossover em um AE distribuído não pode ser ignorado, especialmente quando se usa um operador de migração para disseminar a informação genotípica dos elementos através das ilhas.

Nesse experimento utilizamos o operador de migração para transportar os n melhores indivíduos de uma ilha para outra. A ilha receptora elimina seus n piores indivíduos para receber os migrantes. Nos testes, o valor que mostrou melhores resultados foi de n = 2.

A topologia implementada foi a anel com passagem de token . Cada ilha possui outra como destino de suas migrações, mas a todo momento apenas uma ilha pode realizar o processo de migração, exatamente aquela que possuir o token . O token é enviado a ilha alvo junto com os indivíduos migrantes. Essa topologia apresentou-se interessante pois conseguimos ajustar a periodicidade da migração para que ocorresse quando as ilhas já estivessem perto de, ou já estivessem entrado em um estado de equilíbrio, quando atingiam um máximo local.

O software desenvolvido para os testes foi dividido em dois componentes: o AE propriamente dito, realizando o processo de seleção, recombinação, mutação, migração, etc..., e um controlador, um componente que servia para registrar os nós (instâncias dos AEs), configurá-los remotamente, iniciá-los, finalizá-los e coletar dados estatísticos. Este segundo componente proporcionou uma grande versatilidade, possibilitando inúmeras execuções a fim de se testar diferentes parâmetros.

Vale ressaltar também que foram implementados outros operadores e topologias que não foram utilizados na execução final. Um dos operadores criados implementava um algoritmo greedy (guloso) que basicamente colocava os organismos em ótimos locais de maneira bem rápida. Tal operador pode ser muito interessante para resolver instâncias do problema subset sum cujo conjunto possua uma boa quantidade de números de pequena ordem, mas ineficaz para outros tipos de instâncias.

Como topologias adicionais, foram implementadas a dinâmica, onde cada ilha migrava organismos para outra escolhida de forma aleatória, podendo todas as ilhas efetuar o processo de migração de forma simultânea, e o anel sem passagem de token , que é a mesma que a topologia utilizada em nossos experimentos, porém possibilitando migrações simultâneas. Tanto uma como outra forma se mostraram densas demais, fazendo surgir um comportamento de população única.

Ambiente de testes

Foram utilizados 17 computadores, cada qual com CPUs de dois núcleos a 2,2 GHz e 2Gb de memória RAM.

Em cada computador executamos uma instância do AE (ilha). O fato dos computadores possuírem um núcleo adicional auxiliou o transporte dos indivíduos migrantes e do envio de estatísticas para o controlador, visto que essas operações foram concebidas de forma assíncrona, e em threads de execução separadas.

A rede local tinha a velocidade de 100 Mbits/s e cada computador estava ligado a um switch também de 100Mbits/s.

Análise

Para averiguar os ganhos obtidos com as técnicas de paralelização e distribuição descritas, comparamos os tempos de execução para a obtenção de resultados de mesma qualidade confrontando a versão paralela contra sua versão seqüencial com parametrização similar. Obtemos os resultados mostrados na tabela 1.

Execução Seqüencial Modelo Ilha
1 4m50s 2m03s
2 12m41s 2m04s
3 25m16s 1m15s
4 8m42s 1m12s
5 5m37s 0m42s
6 6m36s 0m29s
7 32m54s 0m25s
8 33m18s 0m32s
9 38m17s 1m25s
10 18m14s 0m59s
11 5m25s 1m11s
12 15m47s 1m11s
13 24m22s 2m28s

Nas execuções seqüenciais, a mais rápida execução obteve uma solução em 4m50s, e a mais lenta levou 38m17s. O tempo médio para obtenção de uma solução foi de 17m51s.

Para as execuções em paralelo temos um ganho considerável, onde a mais rápida execução concluiu em 25s e a mais lenta em 2m28s, com tempo médio de execução de 1m10s.

A análise dos resultados visivelmente satisfatórios leva ainda a um Speedup alcançado de 15.28 (praticamente linear), que é definido como sendo o tempo médio das execuções seqüenciais dividido pelo tempo médio das execuções paralelas, neste caso específico utilizando 17 nós.

Conclusões

Foi visto durante o experimento que múltiplas populações isoladas ajudam a manter a diversidade.

O operador de migração, ao disseminar a informação dos indivíduos de melhor fitness gera perturbações na ilha receptora, fazendo com que esta realize um salto para um novo ótimo local.

Foi observado que as sob-populações colaboram entre si para a fuga de máximos locais.

Foi constatado um aumento significativo no número de parâmetros do AE, o que dificulta ainda mais o acerto para um problema específico. O novo parâmetro de periodicidade de migração se mostrou fundamental para alcançar o resultado favorável.

Referências

[ 1 ] E. Alba and J. M. Troya, “An analysis of synchronous and asynchronous parallel distributed genetic algorithms with structured and panmictic islands,” in Parallel and Distributed Processing, ser. Lectures Notes in Computer Science. Berlin: Springer, oct 1999, pp. 248–256.
[ 2 ] T. Baeck, D. B. Foegel, and Z. Michalewicz, Eds., Evolutionary Computation: Advanced Algorithms and Operators, 1st ed. Dirac House, Temple Back, Bristol BS1 6BE, United Kingdom: Institute of Physics Publishing, November 2000, vol. 2, ch. 15, 16, 26, pp. 101–124; 125–133; 253–263.
[ 3 ] S. R., “Parallel genetic algorithms,” in Proceedings of the Fifth International Conference on Genetic Algorithms. San Mateo, CA: Morgan Kaufmann, 1993, pp. 334–341.
[ 4 ] “Speedup,” 2009. [Online]. Available: http://en.wikipedia.org/wiki/Speedup
[ 5 ] E. Cant ́ -Paz, “A survey of parallel genetic algorithms,” Calculateurs Paralleles, vol. 10, 1998.
[ 6 ] ——, “Designing efficient master-slave parallel genetic algorithms,” Illinois Genetic Algorithms Laboratory, University of Illinois at Urbana-Champaign, Tech. Rep. 97004, May 1997.
[7] ——, “Efficient and accurate parallel genetic algorithms.”
[8] X. Li and M. Kirley, “The effects of varying population density in a fine-grained parallel genetic algorithm.”
[ 9 ] M. Jelasity, “A wave analysis of the subset sum problem,” in Proceedings of the Seventh International Conference on Genetic Algorithms, T. Baeck, Ed. San Francisco, CA: Morgan Kaufmann, 1997, pp. 89–96.
[ 10 ] T. H. Cormen, C. E. Leiserson, R. L. Rivest, and C. Stein, Introduction to Algorithms, 2nd ed. Cambridge, Massachusetts 02142: MIT Press, 2001, pp. 1043–1049.

书签和共享
One comment so far, add another