【问题标题】:Programmatically creating multivariate functions in Mathematica在 Mathematica 中以编程方式创建多元函数
【发布时间】:2011-02-09 03:56:36
【问题描述】:

这是对earlier问题的讨论的分歧。

假设我需要定义一个函数 f 来检查给定的图形标签是否是正确的着色。换句话说,我们为每个节点分配了一个整数,并且没有两个相邻节点得到相同的答案。例如,对于 {"Path",3},f[{1,2,3}] 返回 True,而 f[{1,1,2}] 返回 False。我将如何为任意图创建这样的函数?

以下内容基本上可以满足我的需要,但会生成部分警告。

g[edges_] := Function @@ {{x}, And @@ (x[[First[#]]] != x[[Last[#]]] & /@ edges)}
f = g[GraphData[{"Path", 3}, "EdgeIndices"]];
f[{1, 2, 1}]==False

这是我经常遇到的一个玩具实例问题——我需要以编程方式创建一个多元函数 f,并最终得到 1) 部分警告 2) 将 g 的评估推迟到 f 的评估

【问题讨论】:

  • 所以您有 2 个问题 (1) 如何创建一个函数,该函数采用向量参数并使用 Part[] 对其进行操作,并避免在 Part 尝试解构未定义符号时出现错误,以及 (2 ) 如何记住函数的评估,以便不需要重新计算。还是我误会了?
  • 我之前建议的代码构建了一个函数f,如果a->b 是传递给g 的图形索引中的一条边,则f[a,b] 给出True。我想我在那些早期的 cmets 中误解了你的问题。
  • 实际上,不,它没有,它构建了一个函数f[x],如果x[[a]]==x[[b]] 为图中的任何边a->b 给出True。今天早上还没有咖啡!
  • 马克:我只需要(1)。 Michael:实际上它检查 x[a]==x[b] 而不是 x[[a]]==x[[b]],这就是问题

标签: wolfram-mathematica


【解决方案1】:

这里有一些东西。当没有其他工作时,Hold 和规则通常可以完成工作。我不确定它是否会产生正确的结果 w.r.t.您的图形着色问题,但希望能给您一个起点。我最终使用了Slot 而不是命名变量,因为当我使用了一个我没有花时间尝试的命名变量时,存在一些范围问题(也出现在我之前的建议中,x$ vs. x)解决方法。

g[edges_] := 
 With[{ors = (Hold @@ edges) /. {a_, b_} :> #[[a]] == #[[b]]},
  Function[!ors] /. Hold -> Or
  ]

In[90]:= f = g[GraphData[{"Path", 3}, "EdgeIndices"]]
Out[90]= !(#1[[1]] == #1[[2]] || #1[[2]] == #1[[3]]) &

In[91]:= f[{1, 2, 3}]
Out[91]= True

In[92]:= f[{1, 1, 2}]
Out[92]= False

我觉得它缺乏典型的 Mathematica 优雅,但它确实有效。如果我受到更美丽的东西的启发,我会更新。

【讨论】:

  • 是的,这行得通,但“缺乏典型的优雅”是我不断回到这个问题的原因。使用 Part 并忽略警告似乎也有效,并且还提供了最简洁的代码。我想知道我是否应该关闭 [Part] 并停止担心警告
  • 您可以将构建器代码封装在Quiet[..., Part::partd] 中,以便在评估时禁止它们,但不要将它们完全关闭,而不是将它们完全关闭。
【解决方案2】:

对于此类问题,还有一些其他解决方案不需要您使用HoldReleaseHold,而是依赖于Function 已经具有HoldAll 属性这一事实。您首先使用Block 在本地“擦除”Part 的定义,因此可以安全地构造您感兴趣的表达式,然后使用With 将其插入到Function 中,然后可以安全地返回在Block 之外,并且还使用了Slot 并不真正意味着Function 之外的任何东西这一事实。

使用您的示例:

coloringChecker[edges_List] := 
 Block[{Part},
  With[{body = And @@ Table[#[[First@edge]] != #[[Last@edge]], {edge, edges}]},
   body &]]

我不知道这是否比使用Hold 简单得多,但它是不同的。

【讨论】:

    【解决方案3】:

    我仍然对你似乎遇到的困难感到困惑。这是一个检查列表中没有 2 个连续元素相同的函数:

    f[l_List] := Length[Split[l]] == Length[l]
    

    部分没有问题,到目前为止我尝试过的简单示例没有错误消息,包括 OP 的“测试”用例。我还认为,这比目前看到的其他任何一种方法都更简洁、更具可读性。

    【讨论】:

    • 目标是让函数g自动为任意图生成函数f,而不是手工制作函数f
    猜你喜欢
    • 2022-01-10
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-31
    • 2013-02-08
    • 1970-01-01
    相关资源
    最近更新 更多