蚂蚁旅行商
globals [count1 min1 min_list iteration holes_list prior changed]
breed [ants ant]
breed [holes hole]
ants-own [age hos_already km moving nearest]
holes-own [dis_list phe_list conbine_list]
extensions [rnd]
to setup
ca
set iteration 0
set min1 1000000
set holes_list []
set min_list []
set changed 0
create-holes house-num [
set shape "house"
set color white
setxy random-xcor random-ycor
set dis_list []
set phe_list [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
]
create-ants ant-num [
set shape "bug"
set km 0
set hos_already []
set moving false
move-to hole 1
set hos_already lput min-one-of holes [distance myself] hos_already
set nearest nobody
set count1 count ants
]
ask holes [
;set holes_list lput house
let count5 0
while [count5 < house-num][set dis_list lput distance hole count5 dis_list
set count5 count5 + 1]]
end
to go
ask ants [
if moving = false[
ask last hos_already [set conbine_list (conbine-weight dis_list phe_list)]
let list5 sort-on [who] holes
set list5 filter [ i -> member? i hos_already = false ] list5
let conbine_list1 cut-conbine list5 ([conbine_list] of last hos_already)
let pairs (map list list5 conbine_list1)
ifelse length pairs != 0[
set nearest (n-random-select 5 list5 pairs)]
[set nearest nobody]
]
;let nearest (n-random-select 5 list5 ([conbine_list] of last hos_already) )
ifelse nearest != nobody[
face nearest
;;pen-down
set moving true
fd 0.1
set km km + 0.1
if distance nearest <= 0.1 [
let hos_num [who] of nearest
set hos_already lput nearest hos_already
set moving false
]
;;pen-up
]
[
face item 0 hos_already
let temp_orig item 0 hos_already
fd 0.1
set km km + 0.1
if distance item 0 hos_already <= 0.1[
set hos_already lput item 0 hos_already hos_already
let temp1 1350 / km
set iteration iteration + 1
let count2 0
foreach hos_already [x ->
while [length hos_already - 1 > count2][
ask x [set phe_list replace-item ([who] of item (count2 + 1) [hos_already] of myself) phe_list ((item ([who] of item (count2 + 1) [hos_already] of myself) phe_list / 2) + temp1)
set count2 count2 + 1 ]
]
if km < min1 and km != 0 [
set min1 km
set min_list lput temp_orig hos_already
set changed 1
show word "min: " km
show word "route: " hos_already
show word "iteration: " iteration
]
set km 0
set hos_already []
set hos_already lput temp_orig hos_already
set moving false
]
]
]
]
set prior -1
if changed = 1[
clear-links
]
if length min_list >= 1 and changed = 1[
(
foreach min_list [ x ->
if prior != -1 and prior != [who] of x[
ask hole prior [ create-link-with hole [who] of x ]
set prior [who] of x
]
if prior = -1[
set prior [who] of x
]
set changed 0
]
)
]
ask holes[
;create-links-with item holes 0
]
end
to-report already[hos1 ant1]
let temp1 false
ask ant1 [set temp1 hos_already]
ifelse member? hos1 temp1
[report true]
[report false]
end
to-report n-random-select [ n xs weights ]
let x1 first rnd:weighted-one-of-list weights [ [p] -> last p ]
report x1
end
to-report conbine-weight [list1 list2]
let combine1 []
let count15 0
while [length list1 > count15] [ set combine1 lput ((item count15 list1) * (item count15 list2)) combine1
set count15 count15 + 1]
report combine1
end
to-report cut-conbine [list5 combine_list2]
let new1 []
let count6 0
while [count6 < length list5]
[set new1 lput (item ([who] of item count6 list5) combine_list2) new1
set count6 count6 + 1
]
report new1
end