Ruby Simulated Annealing Trouble - ruby-on-rails

I'm trying to implement a simulated annealing on ruby based on a TSP in which i tried to solve (i converted this code from java). However it turns out the annealing is making my results worst! (PlayerPath gives me a path in which i'll do an Simulated annealing on - i got the path by carrying out a greedy algorithm 1). Can someone help me check on the code and see if i've got something wrong or is it just that simulated annealing doesnt always make things better?
#BEGIN ANNEALING
for i in 1..k
temp = 10000000
cooling = 0.003
if (playerPath[i].length > 2) # if path is larger than 2
bestPath = playerPath[i]
while temp > 1
newSolution = playerPath[i];
firstPosition = rand(newSolution.length)
secondPosition = rand(newSolution.length)
if(firstPosition == 0 || firstPosition == newSolution.length-1)
next
end
if(secondPosition == 0 || secondPosition == newSolution.length-1 )
next
end
# swap cities
tempStore = newSolution[firstPosition]
newSolution[firstPosition] = newSolution[secondPosition]
newSolution[secondPosition] = tempStore
# Tabulation
currentEnergy = calculate_distance(playerPath[i])
neighbourEnergy = calculate_distance(newSolution)
if(acceptanceProbability(currentEnergy,neighbourEnergy,temp) > rand)
playerPath[i] = newSolution
end
if(calculate_distance(playerPath[i])< calculate_distance(bestPath))
bestPath = playerPath[i];
end
temp *= (1-cooling);
end
end
end
#END ANNEALING
#acceptanceProbability
def acceptanceProbability(energy, newEnergy,temperature)
# If the new solution is better, accept it
if (newEnergy < energy)
return 1.0
end
# If the new solution is worse, calculate an acceptance probability
return Math.exp((energy - newEnergy) / temperature)
end

Related

Optimizing finding and counting proper divisors in ruby

This code needs to run under 7000ms or it times out and I am trying to learn ruby so I am here to see if anyone has any ideas that could optimize this code. Or if you can just let me know which functions in this code take the most time so I can concentrate on the parts that will do the most good.
The questions to solve is that you have to tell if the number of divisors for any umber is odd or even.
For n=12 the divisors are [1,2,3,4,6,12] – 'even'
For n=4 the divisors are [1,2,4] – 'odd'
Any help is greatly appreciated,
Thanks.
def oddity(n)
div(n) % 2 == 0 ? (return 'even'): (return 'odd')
end
def div(num)
divs = []
(1..num).each{|x| if (num % x == 0) then divs << x end}
return divs.length
end
The key observation here is that you need only the number of divisors, rather than the divisors themselves. Thus, a fairly simple solution is to decompose the number to primes, and check how many combinations can we form.
require 'mathn'
def div(num)
num.prime_division.inject(1){ |prod, n| prod *= n[1] + 1 }
end
prime_division returns a list of pairs, where the first is the prime and the second is its exponent. E.g.:
12.prime_division
=> [[2, 2], [3, 1]]
We simply multiply the exponents, adding 1 to each, to account for the case where this prime wasn't taken.
Since performance is an issue, let's compare the OP's solution with #standelaune's and #dimid's.
require 'prime'
require 'fruity'
n = 100_000
m = 20
tst = m.times.map { rand(n) }
#=> [30505, 26103, 53968, 24108, 78302, 99141, 22816, 67504, 10149, 28406,
# 18294, 92203, 73157, 5444, 24928, 65154, 24850, 64219, 68310, 64951]
def op(num) # Alex
divs = []
(1..num).each { |x| if (num % x == 0) then divs << x end }
divs.length
end
def test_op(tst) # Alex
tst.each { |n| op(n) }
end
def pd(num) # divid
num.prime_division.inject(1){ |prod, n| prod *= n[1] + 1 }
end
def test_pd(tst) #divid
tst.each { |n| nfacs_even?(n) }
end
def div(num) # standelaune
oddity = false
(1..num).each{|x| if (num % x == 0) then oddity = !oddity end}
oddity ? "odd" : "even"
end
def test_div(tst) # standelaune
tst.each { |n| div(n) }
end
compare do
_test_op { test_op tst }
_test_div { test_div tst }
_test_pd { test_pd tst }
end
Running each test 16 times. Test will take about 56 seconds.
_test_pd is faster than _test_div by 480x ± 100.0
_test_div is similar to _test_op
I'm not suprised that divid's method smokes the others, as prime_division uses (an instance of) the default prime generator, Prime::Generator23, That generator is coded in C and is fast relative to other generators in Prime subclasses.
You could solve this by optimising your algorithm.
You don't have to check all numbers below the number you are examining. It is enough to split your number in to it´s prime components. Then it is a simple matter of combinatorics to determine how many possible divisors there are.
One way to get all prime components could be:
PRIME_SET = [2,3,5,7,11,13,17,19]
def factorize(n)
cut_off = Math.sqrt(n)
parts = []
PRIME_SET.each do |p|
return parts if p > cut_off
if n % p == 0
n = n/p
parts << p
redo
end
end
raise 'To large number for current PRIME_SET'
end
Then computing the number of possible can be done in a number of different ways and there are probably ways of doing it without even computing them. But here is a naive implementation.
def count_possible_divisors(factors)
divisors = Set.new
(1..factors.length-1).each do |i|
factors.combination(i).each do |comb|
divisors.add(comb.reduce(1, :*))
end
end
divisors.length + 2 # plus 2 for 1 and n
end
This should result in less work than what you are doing. But for large numbers this is a hard task to achieve.
If you want to stick with your algorithm, here is an optimization.
def div(num)
oddity = false
(1..num).each{|x| if (num % x == 0) then oddity = !oddity end}
oddity ? "odd" : "even"
end

Removing nested [quote] tags in ruby

I'm writing a forum application in Rails and I'm stuck on limiting nested quotes.
I'm try to use regex and recursion, going down to each matching tag, counting the levels and if the current level is > max, deleting everything inside of it. Problem is that my regex is only matching the first [ quote ] with the first seen [ /quote ], and not the last as intended.
The regex is just a slight tweak of what was given in the docs of the custom bbcode library I'm using (I know very little about regex, I've tried to learn as much as I can in the past couple days but I'm still stuck). I changed it so it'd include [quote], [quote=name] and [quote=name;222] . Could someone examine my code and let me know what the problem could be? I'd appreciate it lots.
def remove_nested_quotes(post_string, max_quotes, count)
result = post_string.match(/\[quote(:.*)?(?:)?(.*?)(?:)?\](.*?)\[\/quote\1?\]/mi)
if result.nil?
return false
elsif (count = count+1) > max_quotes
full_str = result[0]
offset_beg = result.begin(3)
offset_end = result.end(3)
excess_quotes = full_str[offset_beg ..offset_end ]
new_string = full_str.slice(excess_quotes )
return new_string
else
offset_beg = result.begin(3)
offset_end = result.end(3)
full_str = result[0]
inner_string = full_str[offset_beg..offset_end]
return remove_nested_quotes(inner_string , max, count)
end
end
I mean something like
counter = 0
max = 5
loop do
matched = false
string.match /endquote|quote/ do |match|
matched = true
if endquote matched
counter -= 1
else # quote matched
counter += 1
end
if counter > max
# Do something, break or return
else
string = match.post_match
end
end
break unless matched
end

How to compare two images in rails3

How to compare images from my local directory with the downloaded image. Comparison showld be based on image content and size.
How to do this in ruby?
There are several ways to do this.
1) For my opinion the best way is using Rmagick signature(thanks to this useful manual):
require 'RMagick'
new_image = Magick::Image.read(new_photo)[0] ## new_photo = "/your/dir/file.jpg"
expected_image = Magick::Image.read(expected_photo)[0]
new_image.signature.should eql expected_image.signature
or
diff_img, diff_metric = img1[0].compare_channel( img2[0], Magick::MeanSquaredErrorMetric )
2) You also can use raster_graphics library (rosettacode.org):
require 'raster_graphics'
class RGBColour
# the difference between two colours
def -(a_colour)
(#red - a_colour.red).abs +
(#green - a_colour.green).abs +
(#blue - a_colour.blue).abs
end
end
class Pixmap
# the difference between two images
def -(a_pixmap)
if #width != a_pixmap.width or #height != a_pixmap.height
raise ArgumentError, "can't compare images with different sizes"
end
sum = 0
each_pixel {|x,y| sum += self[x,y] - a_pixmap[x,y]}
Float(sum) / (#width * #height * 255 * 3)
end
end
lenna50 = Pixmap.open_from_jpeg('Lenna50.jpg')
lenna100 = Pixmap.open_from_jpeg('Lenna100.jpg')
puts "difference: %.5f%%" % (100.0 * (lenna50 - lenna100))
#=>:
#difference: 1.62559%

Rails DateTime Conversion and Time Comparison

I am having a bit of trouble with comparing times in Rails. I want to check to see if an event lies within a window, if it does, then find which, the event or window starts last and which ends first. My code is as follows.
startingTime = 0
endingTime = 0
time = 0
eventTimeStart = Time.parse(event.start.to_s) #Need to convert DateTime to just Time
windowTimeStart = Time.parse(application.reportStart.to_s)
eventTimeEnd = Time.parse(event.end.to_s) #Need to convert DateTime to just Time
windowTimeEnd = Time.parse(application.reportEnd.to_s)
days = 0
if((windowTimeStart > eventTimeStart) || !(eventTimeStart < windowTimeEnd))
startingTime = windowTimeStart
if((eventTimeStart > windowTimeEnd))
days -= 1
end
else
startingTime = eventTimeStart
end
if((windowTimeEnd > eventTimeEnd) && (eventTimeEnd > windowTimeStart))
endingTime = eventTimeEnd
else
if((eventTimeEnd < windowTimeStart))
days -= 1
end
endingTime = windowTimeEnd
end
I have handwritten out each case, however at runtime it seems to run different from expected. It seems as if I always get into the windowed times. Does Rails use a different approach to Times than what I'm thinking? Can you even compare times in this manner?
If you are trying to see whether intervals overlap or not, this simple check will do:
overlaps = interval_1_start < interval_2_end && interval_1_end > interval_2_start
I don't understand the rest of the question, but I just hope that you don't have two big loops for event and application around the code you have pasted above.
Thanks for your suggestion Mladen.
In order to get this working, I passed all of the time objects into a method I made that converted them into minutes.
def self.getMin(time)
return((time.hour*60) + time.min)
end
I called that on all of my checks and now it seems to work.
if((getMin(windowTimeStart) > getMin(eventTimeStart)) || !(getMin(eventTimeStart) < getMin(windowTimeEnd)))
startingTime = windowTimeStart
if((getMin(eventTimeStart) > getMin(windowTimeEnd)))
days -= 1
end
else
startingTime = eventTimeStart
end
I'm sure there is a better way to check, however it does work now.

rarefying array with limit

I have array of objects form AR
I want to rarefy them, with limit.
Current method looks like:
def rarefied_values(limit = 200)
all_values = self.values.all
rarefied_values = []
chunk_size = (all_values.size / limit.to_f).ceil
if all_values.size > limit
all_values.each_slice(chunk_size) do |chunk|
rarefied_values.push(chunk.first)
end
return rarefied_values
else
return all_values
end
end
Any hints for refactoring?
def rarefied_values(limit = 200)
all_values = values.all
return all_values unless all_values.size > limit
chunk_size = all_values.size / limit
(0...limit).map{|i| all_values[i*chunk_size]}
end
Some general points in refactoring in ruby
self can be omitted usually. In a few cases, you cannot, for example self.class. In this case, self.values.all => values.all
If one of the conditioned procedures is much simpler compared to the others, then place that simple case first, and get rid of it from the rest of the code using return. In this case, return all_values unless all_values.size > limit
In general, when you need nested conditions, design it so that cases with simpler procedures split off eariler, and the complicated cases are placed toward the end.
Let the code be lazy as possible. In this case, rarefied_values = [] is not necessary if all_values.size > limit. So put that in the conditioned section.
Here's a naïve refactor, keeping your same methods, but removing the explicit return calls and only performing certain transformations if necessary:
def rarefied_values(limit = 200)
all_values = self.values.all
if all_values.size <= limit
all_values
else
chunk_size = (all_values.size / limit.to_f).ceil
[].tap{ |rare| all_values.each_slice(chunk_size){ |c| rare << c.first } }
end
end
Here's a faster, more terse version:
def rarefied_values(limit = 200)
all_values = self.values.all
if (size = all_values.size) <= limit
all_values
else
all_values.values_at(*0.step(size-1,(size.to_f/limit).ceil))
end
end

Resources