lib/gecoder/interface/search.rb in gecoder-0.6.0 vs lib/gecoder/interface/search.rb in gecoder-0.6.1
- old
+ new
@@ -2,11 +2,13 @@
class Model
# Finds the first solution to the modelled problem and updates the variables
# to that solution. Returns the model if a solution was found, nil
# otherwise.
def solve!
+ GC.disable
space = dfs_engine.next
+ GC.enable
return nil if space.nil?
@active_space = space
return self
end
@@ -28,13 +30,15 @@
end
# Yields each solution that the model has.
def each_solution(&block)
dfs = dfs_engine
+ GC.disable
while not (@active_space = dfs.next).nil?
yield self
end
+ GC.enable
self.reset!
end
# Finds the optimal solution. Optimality is defined by the provided block
# which is given one parameter, a solution to the problem. The block should
@@ -47,34 +51,50 @@
# model.price.must < best_so_far.price.val
# end
#
# Returns nil if there is no solution.
def optimize!(&block)
- next_space = nil
- best_space = nil
- bab = bab_engine
-
+ # Execute constraints.
+ perform_queued_gecode_interactions
+
+ # Set the method used for constrain calls by the BAB-search.
Model.constrain_proc = lambda do |home_space, best_space|
@active_space = best_space
+ @variable_creation_space = home_space
yield(self, self)
@active_space = home_space
+ @variable_creation_space = nil
+
perform_queued_gecode_interactions
end
+
+ # Perform the search.
+ GC.disable
+ result = Gecode::Raw::bab(selected_space,
+ Gecode::Raw::Search::Config::MINIMAL_DISTANCE,
+ Gecode::Raw::Search::Config::ADAPTIVE_DISTANCE,
+ nil)
+ GC.enable
- while not (next_space = bab.next).nil?
- best_space = next_space
- end
+ # Reset the method used constrain calls and return the result.
Model.constrain_proc = nil
- return nil if best_space.nil?
+ return nil if result.nil?
+
+ # Refresh the solution.
+ result.refresh
+ refresh_variables
+ @active_space = result
return self
end
class <<self
+ # Sets the proc that should be used to handle constrain requests.
def constrain_proc=(proc)
@constrain_proc = proc
end
+ # Called by spaces when they want to constrain as part of BAB-search.
def constrain(home, best)
if @constrain_proc.nil?
raise NotImplementedError, 'Constrain method not implemented.'
else
@constrain_proc.call(home, best)
@@ -89,28 +109,13 @@
def dfs_engine
# Execute constraints.
perform_queued_gecode_interactions
# Construct the engine.
- stop = Gecode::Raw::Search::Stop.new
Gecode::Raw::DFS.new(selected_space,
Gecode::Raw::Search::Config::MINIMAL_DISTANCE,
Gecode::Raw::Search::Config::ADAPTIVE_DISTANCE,
- stop)
- end
-
- # Creates a branch and bound engine for optimization search, executing any
- # unexecuted constraints first.
- def bab_engine
- # Execute constraints.
- perform_queued_gecode_interactions
-
- # Construct the engine.
- stop = Gecode::Raw::Search::Stop.new
- Gecode::Raw::BAB.new(selected_space,
- Gecode::Raw::Search::Config::MINIMAL_DISTANCE,
- Gecode::Raw::Search::Config::ADAPTIVE_DISTANCE,
- stop)
+ nil)
end
# Executes any interactions with Gecode still waiting in the queue
# (emptying the queue) in the process.
def perform_queued_gecode_interactions