我有一个链接节点列表,由walker
代理在链接动作期间收集。
当他到达目的地时,他必须保存他的路径,但没有循环。
消除循环的方法是通过从源链接开始按位置迭代扫描链接位置:对于i-th
位置的链接,从目标链接开始扫描路径,直到第一次出现例如,在位置j
遇到链接(它始终保持i <= j
,因为扫描过程最迟在位置i
停止。如果我们有j > i
,则从位置i+1
到位置j
的链接的子路径对应于循环并且可以被删除。
我一直在尝试编写一个递归to-report
,它将初始列表作为参数而没有成功。我的测试代码给了我循环而不是没有循环的路径是这样的:
to-report no-cycles [ lista ]
ifelse empty? lista [
report lista ] [
let x1 (first lista)
let rest (butfirst lista)
let rev-rest (reverse rest)
let rev-rest1 (first rev-rest)
ifelse x1 != rev-rest1 [
report no-cycles (butlast rest)
] [
report lista ]
]
end
我不知道这是不是一个好方法。
非常感谢您的帮助
答案 0 :(得分:1)
我无法弄清楚如何使编码方法完全正常工作,但您的一般概念是有道理的。下面的代码是to-report
,它接受一个列表并向后迭代它,将当前项目之前的所有项目与当前项目进行比较。如果匹配,则跳转到该项目的最早实例。请注意,我使用链接和数字列表对此进行测试,因此它应删除任何类型列表中的重复项。但是,它确实会返回一个列表,因此如果您输入一个链接列表,它将不返回一个代理集 - 如果您希望链接执行某些操作,则必须使用foreach "your-list"
而不是{ {1}}。如果你需要的只是列表,下面的代码至少应该让你开始。
ask
编辑
获得链接列表后,您可以使用to-report no-cycles [ input_list ]
ifelse empty? input_list [
report input_list
]
[
let final_list []
let temp_list reverse input_list
let n 0
while [ n < length temp_list] [
let x n
let cur item n temp_list
while [ x < length temp_list ] [
if (item x temp_list) = cur [
set n x
]
set x x + 1
]
set final_list fput (item n temp_list) final_list
set n n + 1
]
report final_list
]
end
遍历列表并执行您喜欢的操作。例如,如果您希望列表中的每个链接将变量增加1,则可以使用下面的代码块。
foreach
这将修改链接本身的变量,因此请检查您希望更改的其中一个链接,以监视它是否正常工作。希望这就是你所追求的!