0
点赞
收藏
分享

微信扫一扫

Netlogo笔记06:蚁群算法实现TSP问题可视化

我阿霆哥 2022-05-06 阅读 62
算法

蚂蚁旅行商

 

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
举报

相关推荐

0 条评论