如何防止 Prolog 在不该回溯的地方回溯

2023-12-03

我正在尝试解决一个 CSP,我需要向调酒师分发鸡尾酒,以便每个调酒师最多拥有一份鸡尾酒,并且所有鸡尾酒都由调酒师提供。我通过创建 clpfd 变量列表来解决这个问题,首先为他们提供所有调酒师的完整域,然后删除所有不知道如何制作鸡尾酒的调酒师。
我的代码可以工作,但有一个问题:速度太慢。如果我查看分析器,remove_domain 会被调用 2000 次(对于我为程序提供的输入),而它的重做统计数据>100 000。 我需要在这些函数之一(或两个)中更改什么,以便 prolog 不需要回溯?

produce_domains(_,_,[],[]) :- !.
produce_domains(Bartenders,NBartenders,[Cocktail|Cocktails],[Var|Vars]) :-
    Var in 1..NBartenders,
    remove_domain(Bartenders,NBartenders,Cocktail,Var),!,
    produce_domains(Bartenders,NBartenders,Cocktails,Vars),!.

remove_domain([],0,_,_) :- !.
remove_domain([Bartender|Bartenders],NBartenders,Cocktail,Var) :-
    (\+ member(Cocktail,Bartender) -> Var #\= NBartenders;!),!,
    NNBartenders is NBartenders - 1,
    remove_domain(Bartenders,NNBartenders,Cocktail,Var),!.

我已经读过这个相关问题,但我使用的是最新的 Windows 版本的 SWI-Prolog(5.10.5),所以这不应该是这里的问题。


你不需要那么多!/0:Prolog 通常可以看出您的谓词是确定性的。

让我首先提供您的代码的以下版本。它使用更具相关性的名称,不包含!/0并使用高阶谓词来使代码更短。

:- use_module(library(clpfd)).

bartenders_cocktails_variables(Bs, Cs, Vs) :-
        length(Bs, LBs),
        maplist(bartenders_cocktail_variable(Bs, LBs), Cs, Vs).

bartenders_cocktail_variable(Bs, N, C, V) :-
        V in 1..N,
        foldl(compatible_bartender(C,V), Bs, 1, _).

compatible_bartender(C, V, Cs, N0, N1) :-
        (   member(C, Cs) -> true
        ;   V #\= N0
        ),
        N1 #= N0 + 1.

请注意,我是向上计数而不是向下计数来枚举调酒师(这只是他们能够混合的鸡尾酒的列表),因为这看起来更自然。我也可以省略一个(\+)/1只需切换 if-then-else 的分支即可。

示例查询,显示谓词在此用例中是确定性的:

?- bartenders_cocktails_variables([[a,b],[a,b],[x,y]], [x,a,b], Vars).
Vars = [3, _G1098, _G1101],
_G1098 in 1..2,
_G1101 in 1..2.

我们看到: 鸡尾酒x必须由第三位调酒师等混合。

我认为你的程序的这一部分可能not对您所描述的缓慢性能负责。也许你的程序的其他部分(无意中)不是确定性的?也许尝试不同的标签策略或其他限制?如果您发布更多背景信息,我们也许能够为您提供更多帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何防止 Prolog 在不该回溯的地方回溯 的相关文章

  • Prolog - 递归列表构建

    对于我正在编写的程序 我需要创建一个列表列表 其中包含代表乘积的数字对和两个给定数字的总和 现在我有一个函数 我可以指定将列表添加到列表中的次数 稍后将使用完整功能进行扩展 这是我所拥有的 s1 0 X s1 Q X N is Q 1 mu
  • Prolog 程序从列表中删除每个第 n 个元素

    您能帮我解决以下问题吗 编写三元谓词delete nth从列表中删除每个第 n 个元素 样本运行 delete nth a b c d e f 2 L L a c e false delete nth a b c d e f 1 L L f
  • 展平列表

    尝试解决练习 07http www ic unicamp br meidanis courses mc336 2009s2 prolog problemas http www ic unicamp br meidanis courses m
  • 获取 Prolog 中的解决方案列表

    我正在学习 Prolog 并且正在阅读一本名为 人工智能 Prolog 编程 的书 作为练习 我想学习如何扩展本书中的示例之一 有人可以帮忙吗 假设您有以下事实 parent pam bob pam is a parent of bob p
  • Prolog,如何在 write() 中显示多个输出

    go match Mn Fn write Matching Result nl write Mn write match with write Fn match Mn1 Fn1 person may female 25 blue perso
  • Prolog 变量查询中的“\+”问题

    我正在读 七周七种语言 atm 我对一些 Prolog 查询感到困惑 我不明白对 否 的回答 The friends pl文件看起来像这样 likes wallace cheese likes grommit cheese likes we
  • 如何在 GNU Prolog 中使用“long int”?

    所以基本上看来 GNU Prolog 在我的 32 位 x86 Linux 上使用 28 位整数 下面的代码无法编译 foo A A0 is 0xdeadbeef A1 is A0 gt gt 8 A2 is A0 gt gt 16 A3
  • 如何在 Prolog 中为变量(如字符串)分配多个值?

    今天早些时候 我寻求帮助以在序言中构建数据库以及如何通过参数搜索 有人提出了这个 您还可以向每个处理器添加术语列表 例如 processor pentium g4400 brand intel family pentium series g
  • 非成员规则在 Prolog 中无法按预期工作

    我正在尝试在 Prolog 中创建一个迷宫程序 其目的是找到一条从迷宫起点到迷宫中心点 m 的路线 迷宫由使用四种颜色之一连接的正方形组成 蓝色 绿色 紫色或橙色 从起点到中心的路线遵循四种颜色的重复图案 我创建了以下代码 link2 A
  • 在 Prolog、尾递归中计算斐波那契数列

    我想在 Prolog 中以递归尾部模式计算斐波那契数列 fibonacci 0 0 fibonacci 1 1 fibonacci N Result fibonacci N 1 0 fibonacci N Result Count Coun
  • 如何在 Prolog 中计算数字序列的和

    任务是计算从0到M的自然数之和 我使用SWI Prolog编写了以下代码 my sum From To From gt To my sum From To S From 0 Next is 1 S is 1 my sum Next To S
  • 列表中的连续元素

    我正在阻止一个谓词来编码Prolog 我需要对两个谓词进行编码 如果我打电话 u a b c d e f X 它会给X a b X b c X c d 如果我打电话 v a b c d e f X 它会给X a b X c d X e f
  • Prolog 罗马数字(属性语法)

    我正在做一项作业prolog questions tagged prolog扫描数字列表并应返回该列表是否是有效的罗马数字以及数字的十进制值 前任 1 roman N I N 1 true 2 当我运行我认为应该工作的程序时 十进制值总是正
  • SWI Prolog 使用的检查优化会发生什么情况?

    去引用SICStus Prolog 手册 https sicstus sics se sicstus docs 3 12 9 html sicstus Occur html 逻辑编程背后的通常数学理论禁止 创建循环项 规定发生检查应该是 每
  • 如何在 Prolog 中解决这个算术表达式难题?

    我有一个编程问题 https blog svpino com 2015 05 08 solution to problem 5 and some other thoughts about this type of questions htt
  • 如何找到排列的索引

    index List Idx Predicate will get List with permutation and I want to know index of permutation For example index 4 1 3
  • 我应该在 Prolog 和一般情况下避免尾递归吗?

    我正在阅读 立即学习 Prolog 在线书籍 以获取乐趣 我正在尝试编写一个谓词 该谓词遍历列表的每个成员并向其添加一个 使用累加器 我已经在没有尾递归的情况下轻松完成了 addone addone X Xs Y Ys Y is X 1 a
  • Prolog 展平列表

    flatten A B R islist A gt flatten A R1 R R1 write A append A R1 R flatten B R1 flatten X X islist 这是我写的代码 但我有奇怪的问题 I get
  • 在 SWI Prolog 中使用 process_create/3 使用命令提示符或 shell 时出错

    在 Windows 7 上 当我在 SWI Prolog 中使用 process create 3 打开 Notepad exe 等应用程序时 记事本将打开 但是 它不适用于使用命令提示符的应用程序 例如 当我尝试打开命令提示符窗口时 使用
  • 从终端查询不会打印任何内容

    当在命令行中运行时 这 swipl g write 42 t halt 打印 42 到STDOUT正如预期的那样 然而 这 swipl g X 42 t halt 不打印任何内容 它只是返回 我如何让它打印在 REPL 中打印的内容 即X

随机推荐

  • 检查失败:mdb_status == 0 (2 vs. 0) 没有这样的文件或目录

    我在训练数据时收到以下错误 我已经尝试了互联网上给出的所有解决方案 但似乎没有一个对我有用 我已检查 lmdb 文件的路径和大小不为零 但问题仍然存在 我不知道如何解决这个问题 pooling I0411 12 42 53 114141 2
  • 根据窗口大小调整页面元素的大小

    Problem 我的客户希望我为他的产品创建一个启动网页 以便页面上不应该有滚动 任何浏览器或窗口尺寸 Doubt 使用 CSS 和 JavaScript 可以实现这一点吗 一些早期诊断 这可能有点类似于this or this但不同之处在
  • Xamarin.Auth Google 登录完成后不会自动关闭

    我跟随导游在此输入链接描述 当我登录我的谷歌帐户时遇到问题 它显示 toast 并且浏览器不会自动关闭以支持我的 Thanks 在您的 CustomUrlSchemeInterceptorActivity 页面中替换 OnCreate 内
  • 保存多帧 TIFF

    我从 C 应用程序中的 Stream 加载多帧 TIFF 然后使用 Image Save 方法保存它 但是 这仅保存第一帧的 TIFF 如何让它保存多帧 tiff 由于您没有提供任何详细信息 仅提供一些一般提示 多帧 TIFF 是非常复杂的
  • Bootstrap 导航栏宽度与容器相同

    我正在使用 Bootstrap 3 我不能让导航栏与容器具有相同的宽度 如果它适用于大屏幕但不适用于其他屏幕尺寸 我如何制作固定大小的导航栏 它将改变与容器宽度相同的不同屏幕 div class row div
  • 从 NSUserDefaults 字典 iOS 中删除所有键

    我使用 NSUserDefaults 字典来存储基本信息 例如高分等 以便当用户关闭应用程序时数据不会丢失 无论如何我使用 NSUserDefaults prefs NSUserDefaults standardUserDefaults 存
  • 如何使用 PYQt' QImage scanline() 访问像素数据

    我需要使用 PyQt4 访问 qimage 对象中的像素数据 pixel 太慢 因此文档说使用 scanline 方法 在 C 中 我可以获得 scanline 方法返回的指针 并从缓冲区读取 写入像素 RGB 值 使用Python 我得到
  • 如何在 CentOS 7 上安装最新版本的 Docker [已关闭]

    Closed 这个问题是与编程或软件开发无关 目前不接受答案 我正在尝试在 CentOS 7 64 位系统上安装现代 docker io 版本 1 5 yum 服务器附带的默认 docker io 是 1 3 2 并且 这个版本对于我需要的
  • 该文档没有页面。贾斯珀报告

    我在寻找此问题的解决方案时遇到问题 我的代码运行后工作正常 它假设将我的 sql 数据库上的数据显示到我的 jtable 中 并且有一个按钮将触发显示 jasper 报告 但有一点问题 它总是向我显示消息 文档没有页面 这是为什么 有人可以
  • 如何使用 adb shell 打开 Android 设备扬声器

    没有看到任何关于使用 adb shell 打开 Android 设备扬声器的命令 好奇是否有办法 call phone adb shell am start a android intent action CALL d tel X XXX
  • 如何使用 solana rust 合约发送 SOL

    我是一名 Rust Solana 开发新手 感觉我遇到的问题对大多数其他新手都有帮助 我想知道如何在指令期间将 SOL 从帐户转移到程序 然后能够将 SOL 发送回调用该指令的帐户 我读了https docs solana com 但我找不
  • 为什么调用 main 函数被认为是未定义的行为 (UB)

    我担心这又是一个关于解释 ISO IEC 14882 C 标准 的问题 但是 正在呼叫main从程序中 例如我的使命main 递归地从main至少不是实现定义的行为 更新 我的意思是稍后格式不正确 未定义实现 也不是 UB 请参见下文并回答
  • 无法查看 Azure 日志流中的日志

    在我的 Web Api 应用程序中 我有控制器 Route api controller public class ValuesController Controller GET api values HttpGet public IEnu
  • GtkDrawingArea - 如何使其可绘制?

    我有点失去理智了 我正在尝试使用 cairo 在 GTK 表单上绘制一些简单的图形 include
  • 晾干石头剪刀布

    我是一个新手 ruby 程序员 虽然这段代码可以工作 但我想知道如何改进它 我对 lambda 和 procs 等的了解非常有限 但任何建议都会很棒 有什么办法可以简化if else每种情况下的陈述 另外 有没有什么替代方法case语句被跳
  • 如何在javascript中设置JSTL变量值?

    如何在javascript中设置JSTL变量值 我如何设置 user 多变的 JSTL 来自 的值val1 JavaScript 这是不可能的 因为它们在不同的环境中执行 JSP 在服务器端 JavaScript 在客户端 因此它们不会按照
  • 在 save_post 上设置产品重量的挂钩

    有没有办法设置产品重量save post hook 我有以下代码 但我不知道如何覆盖重量 add action save post change weight function change weight post id WC Produc
  • 为 Neo4j 的 CQL 创建 NOT MATCH 命令?

    我有一个非唯一节点 Neighborhood 它唯一地出现在 IN 一个 City 节点 我想创建一个新的邻里节点 并仅当该邻里节点不存在于该城市时才建立其关系 可以有多个具有相同名称的社区 但每个社区必须在房产城市中唯一出现 遵循吉尔在这
  • 回归基础:Apache Camel 路由和直接组件

    我对骆驼路线及其两个端点有点困惑 Direct 和 Seda 好吧 假设我有一条这样的路线 public void configure from direct services process Some processing here to
  • 如何防止 Prolog 在不该回溯的地方回溯

    我正在尝试解决一个 CSP 我需要向调酒师分发鸡尾酒 以便每个调酒师最多拥有一份鸡尾酒 并且所有鸡尾酒都由调酒师提供 我通过创建 clpfd 变量列表来解决这个问题 首先为他们提供所有调酒师的完整域 然后删除所有不知道如何制作鸡尾酒的调酒师