Repository navigation
Expand file tree
/
Copy pathtspga.html
More file actions
134 lines (116 loc) · 4.77 KB
/
Copy pathtspga.html
File metadata and controls
134 lines (116 loc) · 4.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<html>
<head>
<title>TSP-GA Model</title>
<script src="../lib/agentscript.js"></script>
<script src="../tools/coffee-script.js"></script>
<script type="text/coffeescript">
u = ABM.Util # ABM.Util alias
class MyModel extends ABM.Model
setup: ->
@agentBreeds "nodes travelers"
# no optimizations: 44fps
@refreshPatches = false # for static patches
@refreshTurtles = false # for static turtles
# @patches.usePixels(), setCacheTurtlesHere would not apply
# @patches.cacheTurtlesHere() # not needed, inRadius used only once
# both: 57+fps (max)
# globals
@nodeCount = 50
@travelersCount = 100
@growPopulation = true
@useInversion = true
@bestTourNodes = []
@bestTourLength = 0
@bestTourTick = 0
@stopTickDifference = 500
@anim.setRate 10, true
# @anim.setRate 60, false
# defaults
@patches.setDefault "color", [250, 250, 0]
# @turtles.setDefault "shape", "circle"
# @turtles.setDefault "color", [255,0,0]
# @turtles.setDefault "heading", 0 # override promotion to random angle
@nodes.setDefault "shape", "circle"
@nodes.setDefault "color", [255,0,0]
@nodes.setDefault "heading", 0 # override promotion to random angle
@travelers.setDefault "hidden", true
@links.setDefault "color", [255,0,0]
# p.color = [250, 250, 0] for p in @patches
# @setupNode a for a in @turtles.create @nodeCount
@setupNode n for n in @nodes.create @nodeCount
@createTourLinks @nodes #()
@bestTourLength = @links.reduce ((sum,l)->sum+l.length()), 0
# @turtles.create @travelersCount, (a) => @setupTraveler(a)
@travelers.create @travelersCount, (a) => @setupTraveler(a)
setupNode: (a) =>
a.setXY @patches.randomPt()...
a.setXY @patches.randomPt()... while @nodes.inRadius(a,2).other(a).any()
setupTraveler: (a) =>
# a.hidden = true
# a.breed = "travelers"
a.tourNodes = @nodes.clone().shuffle() # ()
a.tourLength = @lengthFromNodes a.tourNodes
step: ->
# console.log @anim.toString() if @anim.ticks % 100 is 0
@makeTour a for a in @travelers #()
@installBestTour()
if (@anim.ticks - @bestTourTick) is @stopTickDifference
console.log "Stopping at tick #{@anim.ticks} after no change in #{@stopTickDifference} ticks"
console.log "Best tour: #{@bestTourLength} at tick #{@bestTourTick}"
@stop()
createTourLinks: (nodeList) ->
@links.clear()
@links.create nodeList[0], nodeList.last()
@links.create nodeList[i], nodeList[i-1] for i in [1...nodeList.length]
# @links.setProp "color", [255,0,0]
lengthFromNodes: (nodeList) ->
len = nodeList[0].distance(nodeList.last())
len += nodeList[i].distance(nodeList[i-1]) for i in [1...nodeList.length]
len
installBestTour: ->
# @travelers().maxOneOf("tourLength").die() while @travelers().length>@travelersCount
# a = @travelers().minOneOf("tourLength")
@travelers.maxOneOf("tourLength").die() while @travelers.length>@travelersCount
a = @travelers.minOneOf("tourLength")
if a.tourLength < @bestTourLength
@reportNewTour a
@bestTourLength = a.tourLength
@bestTourNodes = a.tourNodes
@bestTourTick = @anim.ticks
@createTourLinks @bestTourNodes
makeTour: (a) ->
nlist = if @useInversion then @inversionStrategy a else @randomStrategy a
len = @lengthFromNodes nlist
if @growPopulation
then a.hatch 1, @travelers, (a) => a.tourNodes=nlist; a.tourLength=len
else (a.tourNodes=nlist; a.tourLength=len) if len < a.tourLength
randomStrategy: (a) -> a.tourNodes.clone().shuffle()
inversionStrategy: (a) -> @asSet @newInversion a.tourNodes
newInversion: (nlist) ->
len = nlist.length
i = u.randomInt len-1
len = 2 + u.randomInt len-i-2
[].concat (nlist.slice 0, i),
(nlist.slice i, i+len).reverse(),
(nlist.slice i+len)
reportNewTour: (a) ->
console.log "new best tour at tick #{@anim.ticks}: #{a.tourLength} by traveler #{a.id}"
# div, patchSize, minX, maxX, minY, maxY, isTorus, hasNeighbors
# Defaults: 13, -16, 16, -16, 16, false, true
model = new MyModel {
div: "layers",
size: 16,
minX: -14,
maxX: 14,
minY: -14,
maxY: 14,
hasNeighbors: false
}
model.debug() # Debug: Put Model vars in global name space
model.start() # Run model immediately after startup initialization
</script>
</head>
<body>
<div id="layers"></div>
</body>
</html>