lib/gecoder/interface/search.rb in gecoder-0.2.0 vs lib/gecoder/interface/search.rb in gecoder-0.3.0
- old
+ new
@@ -10,14 +10,51 @@
# 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!
- stop = Gecode::Raw::Search::Stop.new
- dfs = Gecode::Raw::DFS.new(@base_space, COPY_DIST, ADAPTATION_DIST, stop)
- space = dfs.next
+ space = dfs_engine.next
return nil if space.nil?
@active_space = space
return self
+ end
+
+ # Returns to the original state, before any search was made (but propagation
+ # might have been performed). Returns the reset model.
+ def reset!
+ @active_space = base_space
+ return self
+ end
+
+ # Yields the first solution (if any) to the block. If no solution is found
+ # then the block is not used. Returns the result of the block (nil in case
+ # the block wasn't run).
+ def solution(&block)
+ solution = self.solve!
+ res = yield solution unless solution.nil?
+ self.reset!
+ return res
+ end
+
+ # Yields each solution that the model has.
+ def each_solution(&block)
+ dfs = dfs_engine
+ while not (@active_space = dfs.next).nil?
+ yield self
+ end
+ self.reset!
+ end
+
+ private
+
+ # Creates an DFS engine for the search, executing any unexecuted
+ # constraints first.
+ def dfs_engine
+ # Execute constraints.
+ constraints.each{ |con| con.post }
+ constraints.clear # Empty the queue.
+
+ stop = Gecode::Raw::Search::Stop.new
+ Gecode::Raw::DFS.new(active_space, COPY_DIST, ADAPTATION_DIST, stop)
end
end
end