Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >约束编程示例【Programming】

约束编程示例【Programming】

作者头像
Potato
修改于 2019-11-18 04:01:36
修改于 2019-11-18 04:01:36
2.5K00
代码可运行
举报
运行总次数:0
代码可运行

通过示例应用程序了解约束编程,该示例应用程序可以转换字符的大小写和ASCII代码。

图片来源:João Trindade. Modified by Jason Baker. CC BY-SA 2.0.
图片来源:João Trindade. Modified by Jason Baker. CC BY-SA 2.0.

解决计算问题的方法有很多种。 您可以通过尽可能多地计算可能性来“蛮力”解决问题,或者您可以采取程序性方法并仔细建立影响正确答案的已知因素。 在约束编程中,问题被视为对可能是有效解决方案的一系列限制。这种范式可以用来有效地解决一组问题,这些问题可以转化为变量和约束,或表示为一个数学方程。 在这种方式下,它与约束满足问题( CSP )有关。

它使用声明式编程风格来描述具有某些属性的通用模型。 与命令式风格相比,它不告诉如何实现目标,而是实现目标。 约束编程不是使用仅一种显而易见的方法来定义一组指令来计算值,而是声明约束内变量之间的关系。 最终模型使计算变量值成为可能,而与方向或变化无关。 因此,一个变量值的任何变化都会影响整个系统(即所有其他变量),并且要满足定义的约束条件,它将导致重新计算其他值。

例如,我们以毕达哥拉斯定理为例: a²+b²=c² 。 约束由该等式表示,该等式具有三个变量 (a,b和c),每个变量都有一个域 (非负)。 如果我们有其他两个变量,则使用命令式编程样式来计算任何变量,我们将需要创建三个不同的函数(因为每个变量是由不同的方程式计算的):

  • c =√(a²+b²)
  • a =√(c²-b²)
  • b =√(c²-a²)

这些函数满足主要约束,并且要检查域,每个函数都应验证输入。 此外,根据所提供的变量来选择合适的功能将需要至少一个另外的功能。 这是一个可能的解决方案:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def pythagoras(*, a=None, b=None, c=None):
 ''' Computes a side of a right triangle '''
 # Validate
 if len([i for i in (a, b, c) if i is None or i <= 0]) != 1:
 raise SystemExit("ERROR: you need to define any of two non-negative variables")
 # Compute
 if a is None:
 return (c**2 - b**2)**0.5
 elif b is None:
 return (c**2 - a**2)**0.5
 else:
 return (a**2 + b**2)**0.5

为了了解与约束编程方法的区别,我将展示一个“问题”的示例,该问题具有四个变量和一个约束,该约束没有用直接的数学方程式表示。 这是一个转换器,可以更改字符的大小写(小写到大写/大写),并返回每个字符的ASCII码。 因此,转换器在任何时候都知道所有四个值,并对任何变化立即做出反应。 创建此示例的想法完全受到John DeNero的Fahrenheit-Celsius转换器的启发。

这是约束系统的图:

表示的“问题”被转换成一个由节点(约束)和连接器(变量)组成的约束系统。连接器提供了一个用于获取和设置值的接口。他们还会检查变量的域。当一个值发生更改时,该特定连接器将更改通知其所有连接的节点。反过来,节点满足约束,计算新值,并通过“请求”它们设置一个新值,将它们传播到系统中的其他连接器。传播是使用消息传递技术完成的,这意味着连接器和节点(同步地)获得消息并相应地作出反应。例如,如果系统在“大写字母”连接器上获得A字母,那么其他三个连接器根据节点上定义的约束提供适当的结果:97、a和65。不允许在该连接器上设置任何其他小写字母(例如,b),因为每个连接器都有自己的域。

当所有连接器都链接到由约束定义的节点时,系统已完全设置并准备好在四个连接器中的任何一个上获取值。 设置完成后,系统会自动计算并设置其余连接器上的值。 无需像命令式方法中那样检查设置了什么变量以及应该调用哪个函数,用几个变量相对容易实现,但在数十个或更多变量的情况下会变得有趣。

工作原理

完整的源代码可在我的GitHub中找到。我将深入一些细节来解释系统是如何构建的。

首先,通过给连接器命名并根据一个参数设置域来定义连接器:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import constraint_programming as cp
small_ascii = cp.connector('Small Ascii', lambda x: x >= 97 and x <= 122)
small_letter = cp.connector('Small Letter', lambda x: x >= 'a' and x <= 'z')
capital_ascii = cp.connector('Capital Ascii', lambda x: x >= 65 and x <= 90)
capital_letter = cp.connector('Capital Letter', lambda x: x >= 'A' and x <= 'Z')

其次,将这些连接器链接到节点。 有两种类型: 代码 (将字母来回转换为ASCII码)和aA (将小写字母和大写字母互相转换):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
code(small_letter, small_ascii)
code(capital_letter, capital_ascii)
aA(small_letter, capital_letter)

这两个节点在应调用的函数方面有所不同,但是它们是从常规约束函数派生而来的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def code(conn1, conn2):
 return cp.constraint(conn1, conn2, ord, chr)
def aA(conn1, conn2):
return cp.constraint(conn1, conn2, str.upper, str.lower)

每个节点只有两个连接器。 如果第一个连接器上有更新,则将调用第一个函数来计算另一个连接器(变量)的值。 如果第二个连接器的值更改,也会发生相同的情况。 例如,如果代码节点在conn1连接器上获得A ,则函数ord将用于获取其ASCII代码,同样的,如果aA节点在conn2连接器上获得A ,则它需要使用str.lower函数在conn1上获取正确的小写字母。 每个节点负责计算新值,并将一条消息“发送”到另一个连接器,提示要设置一个新值。 该消息与要求设置新值以及新值的节点的名称一起传送。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def set_value(src_constr, value):
 if (not domain is None) and (not domain(value)):
 raise ValueOutOfDomain(link, value)
 link['value'] = value
 for constraint in constraints:
 if constraint is not src_constr:
 constraint['update'](link)

当连接器收到set消息时,它将运行set_value函数以检查域,设置新值并将“update”消息发送到另一个节点。 通知该连接器上的值已更改。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def update(src_conn):
 if src_conn is conn1:
 conn2['set'](node, constr1(conn1['value']))
 else:
 conn1['set'](node, constr2(conn2['value']))

然后,被通知的节点在连接器上请求此新值,为另一个连接器计算新值,依此类推,直到整个系统发生更改。这就是传播的原理。

但是消息传递是如何发生的?它被实现为访问字典的键。两个函数(连接器和约束)都返回一个调度字典。这样的字典包含作为键的消息和作为值的闭包。比如说,通过访问一个键,一个字典返回一个函数set值(闭包),该函数可以访问“connector”函数的所有本地名称。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# A dispatch dictionary
link = { 'name': name,
 'value': None,
 'connect': connect,
 'set': set_value,
 'constraints': get_constraints }
return link

将字典作为返回值可以创建多个闭包(函数),并且可以访问相同的本地状态。 然后,可以通过使用键作为消息类型来调用这些闭包。

为什么要使用约束编程?

约束编程可以使您对困难的问题有新的认识。并非在每种情况下都可以使用它,但是在某些情况下它可能会为解决方案打开新的机会。如果你发现自己面对的是一个似乎很难在代码中可靠地解决的问题,试着从另一个角度来看待它。 如果最好的角度是约束编程,那么你现在就有了一个如何实现它的例子。


这篇文章最初发表在 Oleksii Tsvietnov的博客,并在他的允许下转载。

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
长假慢学,用TensorFlow做了个AI游戏
正好可以趁这段时间学习学习,于是我还是沉下心搞了一下技术研究,接下来就说说从年前宅到现在折腾的东西吧。
花叔
2020/07/24
1.6K0
长假慢学,用TensorFlow做了个AI游戏
微信小程序|调用tensorflow自定义模型
在成功调用官网打包好的tensorflowjs模型后,怎么调用自己的模型呢?又需要做哪些处理呢?
算法与编程之美
2020/06/17
2.7K0
教程 | 如何利用TensorFlow.js部署简单的AI版「你画我猜」图像识别应用
我们将使用卷积神经网络(CNN)来识别不同类型的手绘图像。这个卷积神经网络将在 Quick Draw 数据集(https://github.com/googlecreativelab/quickdraw-dataset)上接受训练。该数据集包含 345 个类别的大约 5 千万张手绘图像。
机器之心
2018/07/26
2K0
教程 | 如何利用TensorFlow.js部署简单的AI版「你画我猜」图像识别应用
Tensorflow.js 视频图片多目标检测
Tensorflow.js 官方提供了很多常用模型库,涵盖了平时开发中大部分场景的模型。例如,前面提到的图片识别,除此之外还有人体姿态识别,目标物体识别,语音文字等识别。其中一些可能是 Python 转换而来,但都是开发人员用海量数据或资源训练的,个人觉得准确度能满足大部分功能开发要求。这里要介绍的是目标物体识别模型 ——CooSSD。
北桥苏
2024/05/11
2000
Tensorflow.js 视频图片多目标检测
TensorFlow 发布新版本v1.9(附应用实践教程)
【人工智能头条导读】TensorFlow 是一个开放源代码软件库,用于进行高性能数值计算。借助灵活的架构,用户可以轻松地将计算工作部署到多种平台(CPU、GPU、TPU)和设备(桌面设备、服务器集群、移动设备、边缘设备等)。最近在 JS 社区中,对 TF 中 Java API 相关项目与技术的高度需求是前所未有的。
用户1737318
2018/07/23
7700
TensorFlow 发布新版本v1.9(附应用实践教程)
TensorFlow.js 入门指南:让你的JavaScript应用拥有机器学习能力
随着机器学习技术的普及,不再仅限于Python和数据科学专家。通过TensorFlow.js,你可以将强大的机器学习能力带入你的JavaScript应用中。不论是网页、移动端还是桌面应用,集成机器学习都能显著提升功能性和用户体验。在本指南中,我们将探讨如何设置TensorFlow.js,构建和训练模型,并实现实际应用。
前端达人
2024/07/10
7790
TensorFlow.js 入门指南:让你的JavaScript应用拥有机器学习能力
当微信小程序遇上TensorFlow - tensorflow.js篇
在上一篇推送《重磅好消息!TensorFlow开始支持微信小程序》中,介绍了TensorFlow开始支持微信小程序平台,并计划将我之前开发的人工智能微信小程序识狗君使用tensorflow js改写。
云水木石
2019/07/01
3K0
当微信小程序遇上TensorFlow - tensorflow.js篇
当微信小程序遇上TensorFlow - 官方文档
前一段时间为了在微信小程序中使用tensorflow.js,对tfjs-core代码做了一些修改,具体情况请参考我之前写的几篇文档:
云水木石
2019/07/22
4.7K1
TensorFlow.js 微信小程序插件开始支持模型缓存
通常情况下,微信小程序追求的是短小精悍,即开即用,用完即走,适用于一些简单的应用场景。然而,随着微信小程序开放能力的提高,人们发现用微信小程序可以实现越来越多的功能,小程序也越来越复杂,越来越庞大起来。这个可以从小程序的大小限制的变化看出,最开始小程序的大小限制为1M,后来限制为2M,最新微信又给小程序提供了分包加载机制,开发者将小程序划分成不同的子包,用户在使用时按需进行加载,所有分包大小限制提高到8M。
云水木石
2020/02/18
1.5K0
前端入门机器学习 Tensorflow.js 简明教程
写这篇文章的目的是给现有web开发的同事提供一些新的开发方向,认识新的js开发领域!
一只图雀
2020/11/03
4.4K0
前端入门机器学习 Tensorflow.js 简明教程
TensorFlow.js、迁移学习与AI产品创新之道
TensorFlow 的 JS 版本终于出啦,deeplearn.js 正式收编至 TensorFlow 项目,并改名为 TensorFlow.js :
mixlab
2018/04/12
2.5K6
TensorFlow.js、迁移学习与AI产品创新之道
【云+社区年度征文】浅谈 TensorFlow.js 在前端的工程化应用
Google 推出 TensorFlow.js 已有多年,JavaScript 也不知不觉成为了世界上最好的语言。相信对于大多数没接触过机器学习的前端工程师来说,都有一个共同的疑惑:TensorFlow.js 到底能做些什么?
CS逍遥剑仙
2020/11/14
3.8K0
初探 TensorFlow.js
在本文中我们来研究怎样用 TensorFlow.js 创建基本的 AI 模型,并用更复杂的模型实现一些有趣的功能。我只是刚刚开始接触人工智能,尽管不需要深入的人工智能知识,但还是需要搞清楚一些概念才行。
疯狂的技术宅
2020/09/30
1.1K0
TensorFlow.js中的几个重要概念
TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统,其命名来源于本身的运行原理。Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算,TensorFlow为张量从流图的一端流动到另一端计算过程。
xiangzhihong
2022/11/30
9160
【官方教程】TensorFlow在图像识别中的应用
我们大脑的成像过程似乎很容易。人们毫不费力地就能区分出狮子和美洲虎,阅读符号,或是识别面孔。但是这些任务对于计算机而言却是一个大难题:它们之所以看上去简单,是因为我们的大脑有着超乎想象的能力来理解图像。 在过去几年里,机器学习在解决这些难题方面取得了巨大的进步。其中,我们发现一种称为深度卷积神经网络的模型在困难的视觉识别任务中取得了理想的效果 —— 达到人类水平,在某些领域甚至超过。 研究员们通过把他们的成果在ImageNet进行测试,来展示计算机视觉领域的稳定发展进步,ImageNet是计算机视觉领域的一
用户1737318
2018/06/06
1.7K0
手把手教你开发人工智能微信小程序(1):线性回归模型
谈到人工智能、机器学习,我们可能会觉得很神秘,其实机器学习背后的理论并不复杂。就如同原子弹这么尖端的科技,其背后的理论就是一个很简单的公式:
云水木石
2020/01/02
8280
TensorFlow 智能移动项目:1~5
本章介绍如何设置开发环境,以使用 TensorFlow 构建所有 iOS 或 Android 应用,本书其余部分对此进行了讨论。 我们不会详细讨论可用于开发的所有受支持的 TensorFlow 版本,OS 版本,Xcode 和 Android Studio 版本,因为可以在 TensorFlow 网站或通过 Google。 相反,我们将在本章中简要讨论示例工作环境,以便我们能够快速了解​​可使用该环境构建的所有出色应用。
ApacheCN_飞龙
2023/04/24
4.7K0
快速入门TensorFlow.js指南
TensorFlow.JS,之前就发现这个好玩的东东,但是一直没有时间去看,作为一名深度学习者,没有折腾的心是不行的。我们都知道深度学习在工业和实际项目中有着很好的应用,但是如果用深度学习去做些有趣的应用也是很好玩的。
老潘
2023/10/19
4180
快速入门TensorFlow.js指南
算法实现,用机器学习模拟一个opencv的边缘识别算法
所有项目代码: https://github.com/qhduan/tfjs_camera_edge
段清华DEAN
2020/08/06
6150
TensorFlow发布面向JavaScript开发者的机器学习框架TensorFlow.js
机器之心报道 参与:机器之心编辑部 当时时间 3 月 30 日,谷歌 TenosrFlow 开发者峰会 2018 在美国加州石景山开幕,来自全球的机器学习用户围绕 TensorFlow 展开技术演讲与演示。去年的 TensorFlow 开发者大会上,该框架正式升级到了 1.0 版本,逐渐成为最流行的深度学习框架。今年,TensorFlow 发布了面向 JavaScript 开发者的全新机器学习框架 TensorFlow.js。 在大会上午的 Keynote 中,谷歌大脑负责人 Jeff Dean、Tenso
机器之心
2018/05/08
9640
TensorFlow发布面向JavaScript开发者的机器学习框架TensorFlow.js
推荐阅读
相关推荐
长假慢学,用TensorFlow做了个AI游戏
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验