我有以下功能执行以下工作:如果region-map有两个节点作为邻居,则返回矩阵约束:
(defun map-coloring-constraint (region-map)
(let* ((node-list (list-regions region-map))
(constraints (make-array (list (length node-list) (length node-list)))))
(loop for (node-a . value) in region-map
do (loop for node-b in (car value)
do (setf (aref constraints
(position node-a node-list) ;calculating multiple times
(position node-b node-list))
(not nil))))
constraints))
用法如下,可以了解region-map
:
Break 1 [146]> *australia*
((SA (WA NT Q NSW V)) (WA (NT SA)) (NT (Q SA WA)) (Q (NSW SA NT)) (NSW (V SA Q)) (V (SA NSW)) (T))
Break 1 [146]> (map-coloring-constraint *australia*)
#2A((NIL T T T T T NIL)
(T NIL T NIL NIL NIL NIL)
(T T NIL T NIL NIL NIL)
(T NIL T NIL T NIL NIL)
(T NIL NIL T NIL T NIL)
(T NIL NIL NIL T NIL NIL)
(NIL NIL NIL NIL NIL NIL NIL))
有没有更好的方法来编写它避免内循环。
另一个问题:
我在范围内有一个变量a
(列表)和一个列表b
。我想在此范围内的b的每个元素上应用lambda函数。这可以通过mapcar
来实现。问题是我需要访问lambda函数中的变量a
。我怎样才能做到这一点。
P.S。:对第二个问题的回答也是第一个回答,因此在一个帖子中有两个问题。
答案 0 :(得分:2)
你正在填写一个矩阵;两个级别的循环是一种自然的方式。
您可以使用row-major-aref
来避免内循环,但我不明白您想要的原因。
关于第二个问题,实际上还不清楚:如果你试图从外部范围访问变量,那么它是微不足道的:
(let ((a 2))
(mapcar (lambda (x) (expt x a))
'(1 2 3)))
==> (1 4 9)
如果您想要从内部范围访问变量,那么就不可能:
(let ((a 2))
(mapcar (lambda (x) (expt x a))
'(1 2 3))
;; `x` does not exist anymore, it cannot be accessed
)
PS。您可能希望修改代码以避免不必要地调用length
和position
:这些函数在其列表参数的长度上是线性的。您可能想要做的另一项更改是将(not nil)
替换为t
。