From 26c493419dcc55e08fec1a40d119578251dbf2b8 Mon Sep 17 00:00:00 2001 From: "lperron@google.com" Date: Thu, 7 Oct 2010 00:15:54 +0000 Subject: [PATCH] added Value shortcut in collectors --- constraint_solver/assignment.cc | 16 ++++++++++++ constraint_solver/constraint_solver.h | 35 +++++++++++++++++++++++++++ constraint_solver/search.cc | 25 +++++++++++++++++++ examples/golomb.cc | 4 +-- examples/nqueens.cc | 3 +-- python/golomb8.py | 3 +-- python/simple_meeting.py | 15 ++++++++---- python/sudoku.py | 3 +-- 8 files changed, 91 insertions(+), 13 deletions(-) diff --git a/constraint_solver/assignment.cc b/constraint_solver/assignment.cc index 2e5199edc1..faabc22a99 100644 --- a/constraint_solver/assignment.cc +++ b/constraint_solver/assignment.cc @@ -341,6 +341,10 @@ int64 Assignment::StartMax(const IntervalVar* const v) const { return interval_var_container_.Element(v).StartMax(); } +int64 Assignment::StartValue(const IntervalVar* const v) const { + return interval_var_container_.Element(v).StartValue(); +} + int64 Assignment::DurationMin(const IntervalVar* const v) const { return interval_var_container_.Element(v).DurationMin(); } @@ -349,6 +353,10 @@ int64 Assignment::DurationMax(const IntervalVar* const v) const { return interval_var_container_.Element(v).DurationMax(); } +int64 Assignment::DurationValue(const IntervalVar* const v) const { + return interval_var_container_.Element(v).DurationValue(); +} + int64 Assignment::EndMin(const IntervalVar* const v) const { return interval_var_container_.Element(v).EndMin(); } @@ -357,6 +365,10 @@ int64 Assignment::EndMax(const IntervalVar* const v) const { return interval_var_container_.Element(v).EndMax(); } +int64 Assignment::EndValue(const IntervalVar* const v) const { + return interval_var_container_.Element(v).EndValue(); +} + int64 Assignment::PerformedMin(const IntervalVar* const v) const { return interval_var_container_.Element(v).PerformedMin(); } @@ -365,6 +377,10 @@ int64 Assignment::PerformedMax(const IntervalVar* const v) const { return interval_var_container_.Element(v).PerformedMax(); } +int64 Assignment::PerformedValue(const IntervalVar* const v) const { + return interval_var_container_.Element(v).PerformedValue(); +} + void Assignment::SetStartMin(const IntervalVar* const v, int64 m) { interval_var_container_.MutableElement(v).SetStartMin(m); } diff --git a/constraint_solver/constraint_solver.h b/constraint_solver/constraint_solver.h index cb661cf002..1b4bc366d7 100644 --- a/constraint_solver/constraint_solver.h +++ b/constraint_solver/constraint_solver.h @@ -2183,6 +2183,21 @@ class SolutionCollector : public SearchMonitor { // Returns the objective value of the nth solution. int64 objective_value(int n) const; + // This is a short-cut to get the Value of 'var' in the nth solution. + int64 Value(int n, IntVar* const var) const; + + // This is a short-cut to get the StartValue of 'var' in the nth solution. + int64 StartValue(int n, IntervalVar* const var) const; + + // This is a short-cut to get the DurationValue of 'var' in the nth solution. + int64 EndValue(int n, IntervalVar* const var) const; + + // This is a short-cut to get the StartValue of 'var' in the nth solution. + int64 DurationValue(int n, IntervalVar* const var) const; + + // This is a short-cut to get the PerformedValue of 'var' in the nth solution. + int64 PerformedValue(int n, IntervalVar* const var) const; + protected: // Push the current state as a new solution. void PushSolution(); @@ -2508,12 +2523,28 @@ class IntervalVarElement : public AssignmentElement { int64 StartMin() const { return start_min_; } int64 StartMax() const { return start_max_; } + int64 StartValue() const { + CHECK_EQ(start_max_, start_min_); + return start_max_; + } int64 DurationMin() const { return duration_min_; } int64 DurationMax() const { return duration_max_; } + int64 DurationValue() const { + CHECK_EQ(duration_max_, duration_min_); + return duration_max_; + } int64 EndMin() const { return end_min_; } int64 EndMax() const { return end_max_; } + int64 EndValue() const { + CHECK_EQ(end_max_, end_min_); + return end_max_; + } int64 PerformedMin() const { return performed_min_; } int64 PerformedMax() const { return performed_max_; } + int64 PerformedValue() const { + CHECK_EQ(performed_max_, performed_min_); + return performed_max_; + } void SetStartMin(int64 m) { start_min_ = m; } void SetStartMax(int64 m) { start_max_ = m; } void SetStartRange(int64 mi, int64 ma) { @@ -2726,12 +2757,16 @@ class Assignment : public PropagationBaseObject { IntervalVarElement& FastAdd(IntervalVar* const v); int64 StartMin(const IntervalVar* const v) const; int64 StartMax(const IntervalVar* const v) const; + int64 StartValue(const IntervalVar* const v) const; int64 DurationMin(const IntervalVar* const v) const; int64 DurationMax(const IntervalVar* const v) const; + int64 DurationValue(const IntervalVar* const c) const; int64 EndMin(const IntervalVar* const v) const; int64 EndMax(const IntervalVar* const v) const; + int64 EndValue(const IntervalVar* const v) const; int64 PerformedMin(const IntervalVar* const v) const; int64 PerformedMax(const IntervalVar* const v) const; + int64 PerformedValue(const IntervalVar* const v) const; void SetStartMin(const IntervalVar* const v, int64 m); void SetStartMax(const IntervalVar* const v, int64 m); void SetStartRange(const IntervalVar* const v, int64 mi, int64 ma); diff --git a/constraint_solver/search.cc b/constraint_solver/search.cc index 07430b92cc..9fd92c62f8 100644 --- a/constraint_solver/search.cc +++ b/constraint_solver/search.cc @@ -1703,6 +1703,31 @@ int64 SolutionCollector::objective_value(int n) const { return objective_values_[n]; } +int64 SolutionCollector::Value(int n, IntVar* const var) const { + check_index(n); + return solutions_[n]->Value(var); +} + +int64 SolutionCollector::StartValue(int n, IntervalVar* const var) const { + check_index(n); + return solutions_[n]->StartValue(var); +} + +int64 SolutionCollector::DurationValue(int n, IntervalVar* const var) const { + check_index(n); + return solutions_[n]->DurationValue(var); +} + +int64 SolutionCollector::EndValue(int n, IntervalVar* const var) const { + check_index(n); + return solutions_[n]->EndValue(var); +} + +int64 SolutionCollector::PerformedValue(int n, IntervalVar* const var) const { + check_index(n); + return solutions_[n]->PerformedValue(var); +} + // ----- First Solution Collector ----- // Collect first solution, useful when looking satisfaction problems diff --git a/examples/golomb.cc b/examples/golomb.cc index 01a661ae2c..a948cf8e08 100644 --- a/examples/golomb.cc +++ b/examples/golomb.cc @@ -77,7 +77,7 @@ void GolombRuler(int size) { Solver::ASSIGN_MIN_VALUE); s.Solve(db, collector, length); // go! CHECK_EQ(collector->solution_count(), 1); - const int64 result = collector->solution(0)->Value(ticks[size-1]); + const int64 result = collector->Value(0, ticks[size-1]); const int num_failures = collector->failures(0); printf("N = %d, optimal length = %d (fails:%d)\n", size, static_cast(result), num_failures); @@ -86,7 +86,7 @@ void GolombRuler(int size) { } if (FLAGS_print) { for (int i = 0; i < size; ++i) { - const int64 tick = collector->solution(0)->Value(ticks[i]); + const int64 tick = collector->Value(0, ticks[i]); printf("%d ", static_cast(tick)); } printf("\n"); diff --git a/examples/nqueens.cc b/examples/nqueens.cc index f2d0b87a99..a76fff46bd 100644 --- a/examples/nqueens.cc +++ b/examples/nqueens.cc @@ -225,9 +225,8 @@ void NQueens(int size) { int print_max = FLAGS_print_all ? num_solutions : FLAGS_print ? 1 : 0; for (int n = 0; n < print_max; ++n) { printf("--- solution #%d\n", n); - const Assignment * const b = c2->solution(n); for (int i = 0; i < size; ++i) { - const int pos = static_cast(b->Value(queens[i])); + const int pos = static_cast(c2->Value(n, queens[i])); for (int k = 0; k < pos; ++k) printf(" . "); printf("%2d ", i); for (int k = pos + 1; k < size; ++k) printf(" . "); diff --git a/python/golomb8.py b/python/golomb8.py index 806f3ee5e7..d71327a7f9 100644 --- a/python/golomb8.py +++ b/python/golomb8.py @@ -62,8 +62,7 @@ def main(unused_argv): solver.ASSIGN_MIN_VALUE), [objective, collector]) for i in range(0, collector.solution_count()): - current = collector.solution(i) - obj_value = current.Value(marks[size -1]) + obj_value = collector.Value(i, marks[size -1]) time = collector.wall_time(i) branches = collector.branches(i) failures = collector.failures(i) diff --git a/python/simple_meeting.py b/python/simple_meeting.py index 2fa1a36da6..86771324b8 100644 --- a/python/simple_meeting.py +++ b/python/simple_meeting.py @@ -174,12 +174,18 @@ def main(unused_argv): for c in all_calendars: solver.Add(c) + # Build decision builder. + # Chosse the location. vars_phase = solver.Phase([meeting_location, people_count], solver.INT_VAR_SIMPLE, solver.INT_VALUE_SIMPLE) + # Solve people calendars conflicts. sequence_phase = solver.Phase(all_calendars, solver.SEQUENCE_DEFAULT) - main_phase = solver.Compose([sequence_phase, vars_phase]) + # Schedule meeting at the earliest possible time. + meeting_phase = solver.Phase([meeting], solver.INTERVAL_DEFAULT) + # And compose. + main_phase = solver.Compose([sequence_phase, vars_phase, meeting_phase]) solution = solver.Assignment() solution.Add(meeting_location) @@ -194,12 +200,11 @@ def main(unused_argv): solver.Solve(main_phase, [collector, search_log, objective]) if collector.solution_count() > 0: - current = collector.solution(0) print ('we could schedule %d persons in room %d starting at quarter %d' % - (current.Value(people_count), - current.Value(meeting_location), - current.StartMin(meeting))) + (collector.Value(0, people_count), + collector.Value(0, meeting_location), + collector.StartValue(0, meeting))) if __name__ == '__main__': diff --git a/python/sudoku.py b/python/sudoku.py index 2d254edc66..7d002c564d 100644 --- a/python/sudoku.py +++ b/python/sudoku.py @@ -83,9 +83,8 @@ def main(unused_argv): solver.Solve(vars_phase, [collector]) if collector.solution_count() == 1: - current = collector.solution(0) for i in line: - print [int(current.Value(grid[(i, j)])) for j in line] + print [int(collector.Value(0, grid[(i, j)])) for j in line] if __name__ == '__main__':