在Common Lisp中交换列表元素

dan*_*sto 1 lisp common-lisp

我需要交换给定两个位置(i,j)的列表元素来实现TSP的2-opt启发式,并发现这个问题建议使用rotatef.

但是,当我尝试使用它时,我无法理解它的行为.

这段代码令我头疼:

(setq loop '(A B C D E F))
> (A B C D E F)

;; Original copy saved in loop
(setq new_tour loop)

(format t "ORIGINAL LOOP: " loop)
> LOOP: (A B C D E F)

(format t "NEW_TOUR: " new_tour)
> NEW_TOUR: (A B C D E F)

(rotatef (nth 0 new_tour) (nth 1 new_tour))
(format t "NEW_TOUR IS NOW: ~a~%" new_tour)
> NEW_TOUR IS NOW: (B A C D E F)

(format t "ORIGINAL LOOP IS NOW: ~a~%" loop)
> ORIGINAL LOOP IS NOW: (B A C D E F)
Run Code Online (Sandbox Code Playgroud)

为什么rotatef还要修改'循环'列表?有没有一种方法交换元素而new_tour不会丢失原始列表(loop)?

Dou*_*rie 5

复制loop使用

(setq new_tour (copy-list loop))
Run Code Online (Sandbox Code Playgroud)