rubylabs 0.8.3 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/bitlab.rb +16 -21
- data/lib/hashlab.rb +25 -11
- data/lib/marslab.rb +93 -135
- data/lib/randomlab.rb +19 -5
- data/lib/rubylabs.rb +238 -131
- data/lib/spherelab.rb +9 -21
- data/lib/tsplab.rb +101 -79
- metadata +5 -30
data/lib/tsplab.rb
CHANGED
@@ -476,29 +476,44 @@ module TSPLab
|
|
476
476
|
return factorial(n-1) / 2
|
477
477
|
end
|
478
478
|
|
479
|
+
# Exhaustive search
|
480
|
+
|
481
|
+
def xsearch(m)
|
482
|
+
best = m.make_tour
|
483
|
+
m.each_tour { |t| best = t if t.cost < best.cost }
|
484
|
+
return best
|
485
|
+
end
|
486
|
+
|
479
487
|
# Random search
|
480
488
|
|
481
|
-
|
489
|
+
|
490
|
+
def rsearch( matrix, nsamples, userOptions = {} )
|
491
|
+
options = @@rsearchOptions.merge(userOptions)
|
492
|
+
|
482
493
|
Tour.reset
|
494
|
+
|
483
495
|
best = matrix.make_tour(:random)
|
484
496
|
if @@drawing
|
485
497
|
make_histogram([]) # clear histogram display
|
486
498
|
view_tour(best)
|
487
|
-
init_labels(["tours:", "cost:"])
|
499
|
+
init_labels(["#tours:", "cost:"])
|
488
500
|
end
|
501
|
+
|
489
502
|
(nsamples-1).times do |i|
|
490
503
|
t = matrix.make_tour(:random)
|
491
|
-
|
492
|
-
|
504
|
+
if t.cost < best.cost
|
505
|
+
best = t
|
506
|
+
if @@drawing
|
507
|
+
view_tour(t)
|
508
|
+
@@drawing.labels[1].update(sprintf( "cost: %.2f", best.cost ))
|
509
|
+
end
|
510
|
+
end
|
493
511
|
if @@drawing
|
494
|
-
|
495
|
-
labels = []
|
496
|
-
labels << sprintf( "#tours: %d", Tour.count )
|
497
|
-
labels << sprintf( "cost: %.2f", best.cost )
|
498
|
-
update_labels( labels )
|
512
|
+
@@drawing.labels[0].update(sprintf( "#tours: %d", Tour.count ))
|
499
513
|
end
|
514
|
+
sleep options[:pause]
|
500
515
|
end
|
501
|
-
|
516
|
+
|
502
517
|
return best
|
503
518
|
end
|
504
519
|
|
@@ -518,7 +533,6 @@ module TSPLab
|
|
518
533
|
|
519
534
|
if @@drawing
|
520
535
|
make_histogram(a)
|
521
|
-
Canvas.sync
|
522
536
|
end
|
523
537
|
|
524
538
|
return a
|
@@ -548,7 +562,6 @@ module TSPLab
|
|
548
562
|
|
549
563
|
if @@drawing && toplevel
|
550
564
|
show_survivors( population )
|
551
|
-
Canvas.sync
|
552
565
|
end
|
553
566
|
|
554
567
|
return population
|
@@ -564,7 +577,7 @@ module TSPLab
|
|
564
577
|
|
565
578
|
# :begin :rebuild_population
|
566
579
|
def rebuild_population( population, popsize, userOptions = {} )
|
567
|
-
options = @@
|
580
|
+
options = @@esearchOptions.merge(userOptions)
|
568
581
|
tracing = (options[:trace] == :on)
|
569
582
|
|
570
583
|
map = population[0].matrix # assume they're all from the same map...
|
@@ -600,7 +613,6 @@ module TSPLab
|
|
600
613
|
|
601
614
|
if @@drawing
|
602
615
|
update_histogram(population)
|
603
|
-
Canvas.sync
|
604
616
|
end
|
605
617
|
|
606
618
|
return population
|
@@ -622,9 +634,8 @@ module TSPLab
|
|
622
634
|
updated = false
|
623
635
|
end
|
624
636
|
ngen += 1
|
625
|
-
update_tour_display( population, ngen, updated ) if @@drawing
|
637
|
+
update_tour_display( population, ngen, updated, options[:pause] ) if @@drawing
|
626
638
|
end
|
627
|
-
Canvas.sync if @@drawing
|
628
639
|
return best
|
629
640
|
end
|
630
641
|
# :end :evolve
|
@@ -639,7 +650,7 @@ module TSPLab
|
|
639
650
|
=end
|
640
651
|
|
641
652
|
def esearch( matrix, maxgen, userOptions = {} )
|
642
|
-
options = @@
|
653
|
+
options = @@esearchOptions.merge(userOptions)
|
643
654
|
|
644
655
|
if options[:continue]
|
645
656
|
if @@previousPopulation
|
@@ -673,19 +684,18 @@ module TSPLab
|
|
673
684
|
@@previousOptions = options
|
674
685
|
@@previousNGen = maxgen
|
675
686
|
|
676
|
-
Canvas.sync if @@drawing
|
677
|
-
|
678
687
|
return population[0]
|
679
688
|
end
|
680
689
|
|
681
|
-
def update_tour_display(population, ngen,
|
682
|
-
|
690
|
+
def update_tour_display(population, ngen, new_tour, dt)
|
691
|
+
if new_tour
|
692
|
+
view_tour(population[0])
|
693
|
+
@@drawing.labels[2].update(sprintf( "cost: %.2f", population[0].cost ))
|
694
|
+
end
|
683
695
|
update_histogram(population)
|
684
|
-
labels
|
685
|
-
labels
|
686
|
-
|
687
|
-
labels << sprintf( "cost: %.2f", population[0].cost )
|
688
|
-
update_labels(labels)
|
696
|
+
@@drawing.labels[0].update(sprintf( "generations: %d", ngen ))
|
697
|
+
@@drawing.labels[1].update(sprintf( "#tours: %d", Tour.count ))
|
698
|
+
sleep dt
|
689
699
|
end
|
690
700
|
|
691
701
|
=begin rdoc
|
@@ -740,11 +750,10 @@ module TSPLab
|
|
740
750
|
r = options[:dotRadius]
|
741
751
|
m.labels.each do |loc|
|
742
752
|
x, y = m.coords(loc)
|
743
|
-
nodes << Canvas.
|
744
|
-
Canvas.
|
753
|
+
nodes << Canvas::Circle.new( x, y, r, :fill => options[:dotColor] )
|
754
|
+
Canvas::Text.new(loc.to_s, x+r, y+r)
|
745
755
|
end
|
746
756
|
@@drawing = MapView.new(m, nodes, links, [], [], options)
|
747
|
-
Canvas.sync
|
748
757
|
return true
|
749
758
|
end
|
750
759
|
|
@@ -753,45 +762,47 @@ module TSPLab
|
|
753
762
|
puts "call view_map to initialize the canvas"
|
754
763
|
return nil
|
755
764
|
end
|
756
|
-
options = @@
|
765
|
+
options = @@esearchOptions.merge(userOptions)
|
757
766
|
map = @@drawing.cities
|
758
|
-
@@drawing.links.each { |x| x.
|
767
|
+
# @@drawing.links.each { |x| x.erase }
|
768
|
+
Canvas::Line.erase_all(:path)
|
759
769
|
@@drawing.links.clear
|
760
770
|
x0, y0 = map.coords(t.path[-1])
|
761
771
|
for i in 0...t.path.length
|
762
772
|
x1, y1 = map.coords(t.path[i])
|
763
|
-
@@drawing.links << Canvas.
|
773
|
+
@@drawing.links << Canvas::Line.new(x0, y0, x1, y1, :tags => :path)
|
764
774
|
x0, y0 = x1, y1
|
765
775
|
end
|
766
776
|
@@drawing.nodes.each { |x| x.raise }
|
767
|
-
Canvas.sync
|
768
777
|
return true
|
769
778
|
end
|
770
779
|
|
780
|
+
=begin rdoc
|
781
|
+
Initialize a set of text label objects. Erase any old labels saved
|
782
|
+
for this drawing, replace them with new ones.
|
783
|
+
=end
|
784
|
+
|
771
785
|
def init_labels(a)
|
772
786
|
labelx = 525
|
773
787
|
labely = 350
|
774
788
|
dy = 20
|
775
|
-
|
776
|
-
|
777
|
-
labels.each { |x| x.text = "" }
|
789
|
+
@@drawing.labels.each do |x|
|
790
|
+
x.erase
|
778
791
|
end
|
779
|
-
labels.clear
|
792
|
+
@@drawing.labels.clear
|
780
793
|
for i in 0...a.length
|
781
|
-
|
782
|
-
|
783
|
-
labely += dy
|
784
|
-
end
|
785
|
-
labels[i].text = a[i]
|
794
|
+
@@drawing.labels << Canvas::Text.new(a[i], labelx, labely)
|
795
|
+
labely += dy
|
786
796
|
end
|
797
|
+
return @@drawing.labels
|
787
798
|
end
|
788
799
|
|
789
|
-
def update_labels(a)
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
end
|
800
|
+
# def update_labels(a)
|
801
|
+
# labels = @@drawing.labels
|
802
|
+
# for i in 0...labels.length
|
803
|
+
# labels[i].update(a[i])
|
804
|
+
# end
|
805
|
+
# end
|
795
806
|
|
796
807
|
# todo! color bin red if new tour comes from crossover? but what if > 1 tour per bin?
|
797
808
|
|
@@ -799,7 +810,7 @@ module TSPLab
|
|
799
810
|
|
800
811
|
def make_histogram(pop)
|
801
812
|
if @@drawing.histogram.length > 0
|
802
|
-
@@drawing.histogram.each { |box| box.
|
813
|
+
@@drawing.histogram.each { |box| box.erase }
|
803
814
|
@@drawing.histogram.clear
|
804
815
|
end
|
805
816
|
return if pop.length == 0
|
@@ -813,7 +824,7 @@ module TSPLab
|
|
813
824
|
(0..pop.length-1).step(npb) do |i|
|
814
825
|
h = pop[i..(i+npb-1)].inject(0.0) { |sum, tour| sum + tour.cost }
|
815
826
|
h = (h/npb)*scale
|
816
|
-
@@drawing.histogram << Canvas.
|
827
|
+
@@drawing.histogram << Canvas::Rectangle.new(x, y+ymax-h, x+w, y+ymax, :fill => 'darkblue' )
|
817
828
|
x += w
|
818
829
|
end
|
819
830
|
@@drawing.options[:scale] = scale
|
@@ -849,30 +860,41 @@ module TSPLab
|
|
849
860
|
end
|
850
861
|
@@recolor = true
|
851
862
|
end
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
end
|
863
|
+
|
864
|
+
# Outdated attempt to show sequence of ancestors -- if revived, needs to
|
865
|
+
# be updated for new Tk interface
|
866
|
+
|
867
|
+
# def show_lineage(tour, userOptions = {} )
|
868
|
+
# options = @@lineageOptions.merge(userOptions)
|
869
|
+
# dt = options[:dt]
|
870
|
+
# a = []
|
871
|
+
# while tour.parent
|
872
|
+
# a << tour
|
873
|
+
# tour = tour.parent
|
874
|
+
# end
|
875
|
+
# init_labels(["id:", "cost:", "op:"]) if @@drawing
|
876
|
+
# a.reverse.each do |x|
|
877
|
+
# puts x.inspect + ": " + x.op.inspect
|
878
|
+
# if @@drawing
|
879
|
+
# view_tour(x)
|
880
|
+
# labels = []
|
881
|
+
# labels << sprintf( "id: %d", x.id )
|
882
|
+
# labels << sprintf( "cost: %.2f", x.cost )
|
883
|
+
# labels << sprintf( "op: %s", x.op.inspect )
|
884
|
+
# update_labels(labels)
|
885
|
+
# sleep(dt)
|
886
|
+
# end
|
887
|
+
# end
|
888
|
+
# return true
|
889
|
+
# end
|
890
|
+
|
891
|
+
# def test_setup
|
892
|
+
# m = Map.new(15)
|
893
|
+
# view_map(m)
|
894
|
+
# t = m.make_tour(:random)
|
895
|
+
# view_tour(t)
|
896
|
+
# return [m, t]
|
897
|
+
# end
|
876
898
|
|
877
899
|
# Values accessible to all the methods in the module
|
878
900
|
|
@@ -883,11 +905,11 @@ module TSPLab
|
|
883
905
|
:dotRadius => 5.0,
|
884
906
|
}
|
885
907
|
|
886
|
-
|
887
|
-
|
888
|
-
|
908
|
+
@@rsearchOptions = {
|
909
|
+
:pause => 0.01,
|
910
|
+
}
|
889
911
|
|
890
|
-
@@
|
912
|
+
@@esearchOptions = {
|
891
913
|
:popsize => 10,
|
892
914
|
:maxgen => 25,
|
893
915
|
:profiles => {
|
@@ -898,7 +920,7 @@ module TSPLab
|
|
898
920
|
:all_cross => [0.0, 0.0, 1.0],
|
899
921
|
},
|
900
922
|
:distribution => :all_small,
|
901
|
-
:pause => 0.
|
923
|
+
:pause => 0.02,
|
902
924
|
}
|
903
925
|
|
904
926
|
@@histogramOptions = {
|
metadata
CHANGED
@@ -1,13 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubylabs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease: false
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 8
|
9
|
-
- 3
|
10
|
-
version: 0.8.3
|
4
|
+
version: 0.9.0
|
11
5
|
platform: ruby
|
12
6
|
authors:
|
13
7
|
- conery
|
@@ -15,7 +9,7 @@ autorequire:
|
|
15
9
|
bindir: bin
|
16
10
|
cert_chain: []
|
17
11
|
|
18
|
-
date: 2010-
|
12
|
+
date: 2010-12-19 00:00:00 -08:00
|
19
13
|
default_executable: lab-setup.rb
|
20
14
|
dependencies: []
|
21
15
|
|
@@ -82,19 +76,6 @@ files:
|
|
82
76
|
- lib/sievelab.rb
|
83
77
|
- lib/spherelab.rb
|
84
78
|
- lib/tsplab.rb
|
85
|
-
- test/bit_test.rb
|
86
|
-
- test/eliza_test.rb
|
87
|
-
- test/encryption_test.rb
|
88
|
-
- test/hash_test.rb
|
89
|
-
- test/iteration_test.rb
|
90
|
-
- test/mars_test.rb
|
91
|
-
- test/random_test.rb
|
92
|
-
- test/recursion_test.rb
|
93
|
-
- test/rubylabs_test.rb
|
94
|
-
- test/sieve_test.rb
|
95
|
-
- test/sphere_test.rb
|
96
|
-
- test/test_helper.rb
|
97
|
-
- test/tsp_test.rb
|
98
79
|
has_rdoc: true
|
99
80
|
homepage: http://github.com/conery/rubylabs
|
100
81
|
licenses: []
|
@@ -105,27 +86,21 @@ rdoc_options:
|
|
105
86
|
require_paths:
|
106
87
|
- lib
|
107
88
|
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
-
none: false
|
109
89
|
requirements:
|
110
90
|
- - ">="
|
111
91
|
- !ruby/object:Gem::Version
|
112
|
-
hash: 3
|
113
|
-
segments:
|
114
|
-
- 0
|
115
92
|
version: "0"
|
93
|
+
version:
|
116
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
-
none: false
|
118
95
|
requirements:
|
119
96
|
- - ">="
|
120
97
|
- !ruby/object:Gem::Version
|
121
|
-
hash: 3
|
122
|
-
segments:
|
123
|
-
- 0
|
124
98
|
version: "0"
|
99
|
+
version:
|
125
100
|
requirements: []
|
126
101
|
|
127
102
|
rubyforge_project: rubylabs
|
128
|
-
rubygems_version: 1.3.
|
103
|
+
rubygems_version: 1.3.5
|
129
104
|
signing_key:
|
130
105
|
specification_version: 3
|
131
106
|
summary: Software and data for lab projects for Explorations in Computing.
|