如何 0 成本启动全员 AI 技能提升?戳> 了解详情
写点什么

Google SoC 系列:使用 Ruby 实现约束规划

  • 2007-06-26
  • 本文字数:2383 字

    阅读完需:约 8 分钟

Gecode/R 是一个得到 Google SoC 资助的 Ruby 项目,目的是使得 Ruby 语言的开发者同样可以使用运筹学中的约束规划(Constraint Programming)方法,项目的发起人 Andreas Launila 对于约束规划这样解释道:

约束规划是一种声明式的规划范式(Declarative Programming Paradigm),开发者描述需要何种解决方案,而不是告诉程序如何进行具体的计算。当使用约束规划时,开发者可以试图为问题建立模型,并将模型集中提交给问题处理程序。问题处理程序通过检索问题域中的所有可行解,并利用模型中的约束条件来去除这些解中的部分,而不需要真正去访问到这部分的可能解。 一个常见的例子就是数独游戏(Soduko),通过约束规划解决数独问题的过程是:为问题处理程序填写约束规则(比方说每一行的数字必须是各不相同的),然后寻找令所有约束条件同时满足的解决方案。

当问及现实世界中是否有使用约束规划解决问题的例子时,Andreas 解释道:

约束规划是用于处理 NP 难解组合问题的常用方法,在这种情况下,一般只存在有限的选择,但需要根据特定条件进行搜索。现实世界中的例子包括时序安排,周期分配以及人员工作时间设置等问题。

Gecode/R 实际上是建立在 C++ 约束规划函数库 Gecode基础之上的 Ruby 语言封装,关于为何使用 Ruby 语言来实现 Gecode 的功能,Andreas 这样解释道:

对我来说,约束规划是在我常用工具箱中一个非常有用的工具。当使用约束规划来处理恰当的问题类型时,会为我们节省大量的时间和工作。由于可以进行快速编码实现,当更好的算法存在并且运行效率并非是首要考虑的因素(或者性能上的差别比起在研究和实现算法上需要花的额外时间是可以忽略不计)时,约束规划可以用来很快的解决问题。

一个有趣的话题是关于如何使用 Ruby 语言来定义约束规划:

我的目的是为了创建一个前端,而不仅仅是一个绑定。我称之为类库而不仅是一种 DSL(Domain Specific Language,领域特定语言),尽管两者之间的边界并非有十分严格的界定。因为项目即将开始,至今还没有定义精确的语法规则。下面简单的代码段给出项目的大致指导方向,但这不一定是项目最终使用的语法规则。代码段示例解决了“send+more=money”这个经典的问题。 通过这样的途径,比较方法和算术方法被用于表示线性约束,并且通过对数组进行拓展来表达特殊约束来用于分支选择。变量在创建时需要记录,以便于跟踪他们。其中一个不足之处是符号“!=”没有被定义为一个方法,所以使用不等式时的语法与其他语言并不相同。

下面是程序代码编写的样例:

# 经典的 send+more=money 问题。<br></br>class SendMoreMoneyProblem < Gecode::Space<br></br> def initialize<br></br> # 设置变量,在 0..9 之间的 8 个字母.<br></br> s,e,n,d,m,o,r,y = letters = IntVar.array(8, 0..9)<br></br> # 设置约束条件.<br></br> constrain equation_row(s, e, n, d) +<br></br> equation_row(m, o, r, e) ==<br></br> equation_row(m, o, n, e, y)<br></br> constrain s.not_equal(0) # 并不是写成"s != 0" 因为我们无法重定义符号 != .<br></br> constrain m.not_equal(0)<br></br> letters.all_distinct<br></br> # 选择搜索解决方案时要使用的启发式分支.<br></br> letters.branch_using(:variable => :min_size, :value => :min)<br></br> end<p>private</p><br></br> # 使用线性方程有更好的方法。取出变量中的一个数字,<br></br> # 并且计算线性组合就像变量是基于 10 个字符的阿拉伯数字。<br></br> # 例如:x,y,z 成为 100*x + 10*y + z .<br></br> def equation_row(*variables)<br></br> variables.inject(0){ |result, variable| variable + 10*result }<br></br> end<br></br>end<br></br># 打印出问题的第一种解决方案 <br></br>p SendMoreMoneyProblem.new.solutions(:first)如果想了解更多细节,可以查看维基百科上面“send+more=money”词条相关的文章

当使用 Ruby 语言定义业务逻辑或者数据时,常有可能使用内部 DSL来编写更加简练并且可读性更强的代码。Andreas 关于代码可能的样式这样解释道:

另一个使得代码看起来更像 DSL 的方法是在编码中跳过类声明之类的。这个方法在快速处理单一样例的问题时更加出色,但是会妨碍与其它 Ruby 代码协同来使用约束规划。

下面是使用 DSL 方法的代码样例:

find_first_solution_to define_problem do |p|<br></br> # 设置变量,在 0..9 之间的 8 个字母。<br></br> s,e,n,d,m,o,r,y = letters = p.create_int_vars(8, 0..9)<br></br> # 设置约束。<br></br> p.add 1000*s + 100*e + 10*n + d +<br></br> 1000*m + 100*o + 10*r + e ==<br></br> 10000*m + 1000*o + 100*n + 10*e + y<br></br> p.add s.not_equal(0)<br></br> p.add m.not_equal(0)<br></br> p.add all_distinct(letters)<br></br> # 选择启发式分支。<br></br> p.branch_on letters, :variable => :min_size, :value => :min<br></br>end由于 Gecode/R 是在本地类库基础之上的绑定实现,这样就存在一个潜在的瓶颈问题。Andreas 非常自信的认为这不会是一个影响项目发展的问题:

在 Gecode 中已经实现了通用约束的传播机制,所以这些约束的实际传播过程已在此处完成。如果用户设置自定义的传播机制,则需要在 C 语言和 Ruby 语言之间进行来回切换,目前我还不清楚这样是否存在性能问题。但 Gecod 的设计可以使其能很好地与外界进行交互,并且可以很好的与 Java 语言协同工作,所以如果有人说 Gecode/R 在本地类库上实现绑定将会成为瓶颈,我肯定会对此表示惊讶。

Gecode/R 是建立在 RubyForge 上的开放源代码项目,这同时也是吸引对此感兴趣开发者加入的优秀站点。约束规范相关的API 接口和语法的可以在链接中的Wiki 页面深入了解。Andreas 同时也维护着建立在O’Reilly Ruby 站点上的Gecode/R 项目相关博客

查看英文原文: Google SoC Series: Constraint programming with Ruby

2007-06-26 19:301449
用户头像

发布了 74 篇内容, 共 14.8 次阅读, 收获喜欢 3 次。

关注

评论

发布
暂无评论
发现更多内容

原点安全入选Gartner®“数据安全平台”中国市场指南代表厂商

原点安全

用DeepSeek+ Python 自动生成测试用例 狂省5小时,漏测率暴降83%!

测试人

人工智能

图纸太杂乱?1秒关闭CAD图层,清爽看图!

在路上

cad cad看图 cad图纸

开源鸿蒙亮相HDC 2025 共建千行万业的数字底座

最新动态

编程助手怎么选?我都要!左手通义灵码,右手 Cursor,组合来用超级爽

阿里巴巴云原生

阿里云 通义灵码

Java 集合框架底层数据结构实现深度解析

电子尖叫食人鱼

Java 数据结构

基于Casbin的ABAC授权模型设计与开发踩坑实录

天翼云开发者社区

安全 权限管理 访问控制

爱测智能体测试平台·全新升级邀您体验

测试人

人工智能 软件测试

flstudio找不到中文设置,没有语言选项怎么办?FL Studio设置中文教程,FL Studio中文版免费下载

阿拉灯神丁

编曲软件 FL Studio 水果FL Studio FL水果 音乐创作

2025年面试通过率低?来看看一位Android大牛的BAT面试心得与经验总结

程序员每日分享

程序员 面试 移动开发 Android开发 互联网大厂

博大数据精彩亮相2025中国国际金融展,全栈解决方案赋能金融数字化升级

极客天地

YMatrix 技术内幕:详解 10w+ TPS 背后的技术矩阵

YMatrix 超融合数据库

OLTP HTAP OLTP 场景实践 YMatrix HTAP数据库

Java线程池详解:高效并发编程的核心利器

不在线第一只蜗牛

Java

JVM内存结构33连问

量贩潮汐·WholesaleTide

JVM

2025年含泪狂刷Android基础面试118题,offer拿到手软

程序员每日分享

程序员 面试 移动开发 Android开发 互联网大厂

AppGallery Connect(AGC)账号与权限管理体系

小赵学鸿蒙

商务 AppGallery Connect 鸿蒙开发工具

商场商圈潜客挖掘模型

天翼云开发者社区

数据挖掘 大数据

更强模型效果!豆包大模型 1.6 系列上线边缘大模型网关,最高申领1000万免费 Tokens

火山引擎边缘云

AI+ 端侧AI 大模型 侧端大模型

向量删除的3种方式

DashVector

人工智能 数据库 大模型

从电脑到座舱:英特尔携AI科技杀入智能汽车主战场

科技热闻

DeepSeek-R1源码解读

AI布道Mr.Jin

医学+AI系列第一场|聚焦北京中医药大学的产-教-研融合、以赛促学、创新驱动的人才培养实践

ModelWhale

以赛促学 北京中医药大学

HDC 2025|在AppGallery发现精品应用

最新动态

编程助手怎么选?我都要!左手通义灵码,右手 Cursor,组合来用超级爽

阿里云云效

阿里云 通义灵码

西南会议 | 2025 Altair 区域技术交流会下周五成都,日程+演讲阵容+惊喜好礼全面公布!

Altair RapidMiner

人工智能 AI 仿真 CAE AI驱动工程

等保测评费用谁出?收费依据是什么?

行云管家

等保 堡垒机 等保测评

PAI推理重磅发布模型权重服务,大幅降低冷启动与扩容时长

阿里云大数据AI技术

开源 扩容 冷启动 模型训练/测试 大型语言模型LLM

电子制造智能化转型:MES如何解决工艺复杂、质量追溯与供应链协同

万界星空科技

mes 万界星空科技mes 电子电器制造业 电子电器行业 电子行业mes

微信读书十周年,后台架构的技术演进和实践总结

JackJiang

网络编程 即时通讯 IM

面临秋招!卷S人的Java中高级核心知识全面解析面试手册,涨薪跳槽拿高薪靠它了!

程序员高级码农

Java 程序员‘

Spring Boot 启动优化实践

不在线第一只蜗牛

Spring Boot

Google SoC系列:使用Ruby实现约束规划_Ruby_Werner Schuster_InfoQ精选文章