Программное создание многомерных функций в Mathematica - PullRequest
1 голос
/ 10 ноября 2010

Это разделение от обсуждения ранее вопроса.

Предположим, мне нужно определить функцию 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

Ответы [ 3 ]

1 голос
/ 08 февраля 2011

Существует несколько других решений этой проблемы, которые не требуют использования Hold или ReleaseHold, но вместо этого полагаются на тот факт, что Function уже имеет атрибут HoldAll. Сначала вы локально «стираете» определения Part, используя Block, чтобы интересующее вас выражение могло быть безопасно создано, а затем используете With для интерполяции этого в Function, который затем можно безопасно вернуть за пределами Block, а также использует тот факт, что Slot на самом деле ничего не значит за пределами Function.

Используя ваш пример:

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

Я не знаю, намного ли это сложнее, чем использование Hold, но это не так.

1 голос
/ 10 ноября 2010

Вот что-то. Когда ничего не работает, Hold и правила обычно могут выполнить работу. Я не уверен, что он дает правильные результаты w.r.t. ваш вопрос раскраски графика, но, надеюсь, даст вам стартовое место. В итоге я использовал Slot вместо именованной переменной, потому что были некоторые проблемы с областями видимости (также присутствовавшие в моем предыдущем предложении x$ против 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, но это работает. Я обновлюсь, если меня вдохновит что-то более красивое.

0 голосов
/ 11 ноября 2010

Я все еще озадачен трудностями, которые у вас, похоже, возникают. Вот функция, которая проверяет, что 2 последовательных элемента в списке не идентичны:

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

Нет проблем с Part, нет сообщений об ошибках для простых примеров, которые я пробовал до сих пор, включая тестовые примеры OP. Я также утверждаю, что это более кратко и более читабельно, чем любой из других подходов, рассмотренных до сих пор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...