rubylabs 0.8.3 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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.
|