在Lisp中实现有趣的编码方法 前言

在Lisp中实现有趣的编码方法 前言,lisp,common-lisp,Lisp,Common Lisp,我正致力于实现旅行商问题的遗传算法。我在做一些基本假设,比如你可以从任何城市前往任何城市。虽然这是一个任务,但我已经将其扩展到了一个个人项目,因为截止日期已经过去,我选择使用Lisp,这显然不是必需的。以下面列出的方式对数据进行编码的目的是为了在算法的后面很容易地执行交叉 问题 假设您有一个城市列表,如下所示 (defvar*数据*(列表 "(A 20 10) "(B 5 16) "(C 12 18) "(D x y) "(E x y) ... 我想用类似的方式对这些数据进行编码: 我一生都

我正致力于实现旅行商问题的遗传算法。我在做一些基本假设,比如你可以从任何城市前往任何城市。虽然这是一个任务,但我已经将其扩展到了一个个人项目,因为截止日期已经过去,我选择使用Lisp,这显然不是必需的。以下面列出的方式对数据进行编码的目的是为了在算法的后面很容易地执行交叉

问题 假设您有一个城市列表,如下所示

(defvar*数据*(列表
"(A 20 10)
"(B 5 16)
"(C 12 18)
"(D x y)
"(E x y)
...
我想用类似的方式对这些数据进行编码:


我一生都不知道如何在Lisp中实现这一点。如果有人有一些见解,我将不胜感激。如果有更好的方法来创建我的
*数据集*
集,让它更容易包含在其中!

现在我明白了。以下是解决方案:

(defparameter *data* (list
                     '(A 20 10)
                     '(B 5 16)
                     '(C 12 18)
                     '(D x y)
                     '(E x y)))
首先,您需要一个函数来查找城市列表中城市的索引位置(
*data*
),同时删除城市列表中的条目并返回更新后的城市列表

(defun choose-city (city-list city-name)
  "Return city-name with its index position
  and city-list with the chosen city removed, keeping the order."
  (let* ((cities (mapcar #'car city-list))
         (pos (position city-name cities)))
    (list city-name 
          pos 
          (append (subseq city-list 0 pos)
                  (subseq city-list (+ pos 1) (length city-list))))))

;; improved version by @Kaz - thanks! (lispier)
(defun choose-city (city-list city-name)
  (list city-name 
        (positiion city-name city-list :key #'car :test #'eql)
        (remove city-name city-list :key #'car :test #'eql)))
然后,您需要一个应用上一个函数的函数 通过在
城市序列中删除匹配的
当前城市
,一次又一次地收集索引位置并一步一步地更新
城市列表
。 lisp中出现的一个典型模式是 将待突变变量定义为
let
表达式中的局部变量,并从
let
-表达式的主体使用
setf
(设置)更新变量值

现在,如果你跑

(choose-cities-subsequently *data* '(A D E B C))
它正确返回:

(0 2 2 0 0)
通过在最后一个函数和
setf
-对
解构绑定
表达式主体中的内容进行绑定,并在最终列表中返回最终值, 您可以收集更多信息并使其可见

试图简化一点递归的定义
现在我明白了。以下是解决方案:

(defparameter *data* (list
                     '(A 20 10)
                     '(B 5 16)
                     '(C 12 18)
                     '(D x y)
                     '(E x y)))
首先,您需要一个函数来查找城市列表中城市的索引位置(
*data*
),同时删除城市列表中的条目并返回更新后的城市列表

(defun choose-city (city-list city-name)
  "Return city-name with its index position
  and city-list with the chosen city removed, keeping the order."
  (let* ((cities (mapcar #'car city-list))
         (pos (position city-name cities)))
    (list city-name 
          pos 
          (append (subseq city-list 0 pos)
                  (subseq city-list (+ pos 1) (length city-list))))))

;; improved version by @Kaz - thanks! (lispier)
(defun choose-city (city-list city-name)
  (list city-name 
        (positiion city-name city-list :key #'car :test #'eql)
        (remove city-name city-list :key #'car :test #'eql)))
然后,您需要一个应用上一个函数的函数 通过在
城市序列中删除匹配的
当前城市
,一次又一次地收集索引位置并一步一步地更新
城市列表
。 lisp中出现的一个典型模式是 将待突变变量定义为
let
表达式中的局部变量,并从
let
-表达式的主体使用
setf
(设置)更新变量值

现在,如果你跑

(choose-cities-subsequently *data* '(A D E B C))
它正确返回:

(0 2 2 0 0)
通过在最后一个函数和
setf
-对
解构绑定
表达式主体中的内容进行绑定,并在最终列表中返回最终值, 您可以收集更多信息并使其可见

试图简化一点递归的定义
我不明白,
索引表
是干什么用的?这是一本字典吗?它如何与
*data*
中给出的数据相结合?你需要
下一个城市和索引
索引列表
来说明它们的优点以及它们之间的联系?你没有解释它们之间的关系彼此之间的感情…啊,慢慢地我明白了-给定一条路线,你想从剩余的可能城市中删除那些被访问的城市…我不明白-索引表是做什么的-这是一本字典吗?它如何与
*data*
中给出的数据相结合?以及你需要的de>Next City and Index
Indexlist
的优点以及它们之间的联系?你没有解释它们之间的关系…啊,慢慢地我明白了-给定一条路线,你想从剩余可能访问的城市中删除那些城市…哥们,很好!我花了一段时间才结束我的头脑围绕着这一点,这无疑有助于加深我对Lisp的理解。非常感谢!@DenverEllis Welcome!愿你在你的道路上受到启发-原力与你同在!XD你可以使用原始列表上的
位置
,而无需
地图车
-标出城市!
位置
需要
:key
:test
参数。
(定位城市名称城市列表:key#car)
附加
subseq
操作可以替换为
(移除城市名称城市列表:key#car)
(setf索引位置(cons索引位置))
执行与
(推送索引位置)相同的操作
。但是如果我们使用
循环
,通过使用
收集
,或
收集到
,可以避免整个push now和nreverse later习语。哥们,很好!我花了一段时间才意识到这一点,这无疑有助于加深我对Lisp的理解。非常感谢!@DenverEllis欢迎!祝你愉快在你的道路上受到启发-原力与你同在!XD你可以在原始列表上使用
位置
,而无需
地图车
-显示城市!
位置
采用
:键
:测试
参数。
(位置城市名称城市列表:键#'car
追加
subseq
操作可以替换为
(删除城市名称城市列表:键#'car)
(setf索引位置(cons索引位置))
执行与
(按ind)相同的操作