fixes
This commit is contained in:
@@ -101,7 +101,10 @@ NeighborhoodGeneratorHelper::NeighborhoodGeneratorHelper(
|
||||
}
|
||||
|
||||
void NeighborhoodGeneratorHelper::Synchronize() {
|
||||
if (global_time_limit_->LimitReached()) return;
|
||||
if (shared_response_->ProblemIsSolved() ||
|
||||
global_time_limit_->LimitReached()) {
|
||||
return;
|
||||
}
|
||||
if (shared_bounds_ != nullptr) {
|
||||
std::vector<int> model_variables;
|
||||
std::vector<int64_t> new_lower_bounds;
|
||||
|
||||
@@ -58,10 +58,11 @@ TEST(NeighborhoodGeneratorHelperTest, ActiveVariables) {
|
||||
const CpSolverResponse solution = SolveCpModel(proto, &model);
|
||||
EXPECT_EQ(solution.status(), CpSolverStatus::OPTIMAL);
|
||||
|
||||
auto* shared_response_manager = model.GetOrCreate<SharedResponseManager>();
|
||||
SharedBoundsManager shared_bounds_manager(proto);
|
||||
SatParameters params;
|
||||
Model main_model;
|
||||
auto* shared_response_manager =
|
||||
main_model.GetOrCreate<SharedResponseManager>();
|
||||
ModelSharedTimeLimit time_limit(&main_model);
|
||||
NeighborhoodGeneratorHelper helper(&proto, ¶ms, shared_response_manager,
|
||||
&time_limit, &shared_bounds_manager);
|
||||
@@ -113,10 +114,11 @@ TYPED_TEST(GeneratorTest, BasicContract) {
|
||||
EXPECT_EQ(solution.status(), CpSolverStatus::OPTIMAL);
|
||||
|
||||
SatParameters params;
|
||||
auto* shared_response_manager = model.GetOrCreate<SharedResponseManager>();
|
||||
shared_response_manager->InitializeObjective(proto);
|
||||
Model main_model;
|
||||
ModelSharedTimeLimit time_limit(&main_model);
|
||||
auto* shared_response_manager =
|
||||
main_model.GetOrCreate<SharedResponseManager>();
|
||||
shared_response_manager->InitializeObjective(proto);
|
||||
NeighborhoodGeneratorHelper helper(&proto, ¶ms, shared_response_manager,
|
||||
&time_limit);
|
||||
TypeParam generator(&helper, "test");
|
||||
@@ -150,8 +152,9 @@ TYPED_TEST(GeneratorTest, NoReduction) {
|
||||
EXPECT_EQ(solution.status(), CpSolverStatus::OPTIMAL);
|
||||
|
||||
SatParameters params;
|
||||
auto* shared_response_manager = model.GetOrCreate<SharedResponseManager>();
|
||||
Model main_model;
|
||||
auto* shared_response_manager =
|
||||
main_model.GetOrCreate<SharedResponseManager>();
|
||||
ModelSharedTimeLimit time_limit(&main_model);
|
||||
NeighborhoodGeneratorHelper helper(&proto, ¶ms, shared_response_manager,
|
||||
&time_limit);
|
||||
@@ -187,9 +190,10 @@ TYPED_TEST(GeneratorTest, ReadyToGenerate) {
|
||||
const CpSolverResponse solution = SolveWithParameters(proto, params);
|
||||
|
||||
Model model;
|
||||
auto* shared_response_manager = model.GetOrCreate<SharedResponseManager>();
|
||||
shared_response_manager->InitializeObjective(proto);
|
||||
Model main_model;
|
||||
auto* shared_response_manager =
|
||||
main_model.GetOrCreate<SharedResponseManager>();
|
||||
shared_response_manager->InitializeObjective(proto);
|
||||
ModelSharedTimeLimit time_limit(&main_model);
|
||||
NeighborhoodGeneratorHelper helper(&proto, model.GetOrCreate<SatParameters>(),
|
||||
shared_response_manager, &time_limit);
|
||||
@@ -215,8 +219,9 @@ TYPED_TEST(GeneratorTest, ModelWithoutConstraintDoNotCrash) {
|
||||
EXPECT_EQ(solution.status(), CpSolverStatus::OPTIMAL);
|
||||
|
||||
SatParameters params;
|
||||
auto* shared_response_manager = model.GetOrCreate<SharedResponseManager>();
|
||||
Model main_model;
|
||||
auto* shared_response_manager =
|
||||
main_model.GetOrCreate<SharedResponseManager>();
|
||||
ModelSharedTimeLimit time_limit(&main_model);
|
||||
NeighborhoodGeneratorHelper helper(&proto, ¶ms, shared_response_manager,
|
||||
&time_limit);
|
||||
@@ -242,8 +247,9 @@ TEST(GeneratorTest, UCBScore) {
|
||||
EXPECT_EQ(solution.status(), CpSolverStatus::OPTIMAL);
|
||||
|
||||
SatParameters params;
|
||||
auto* shared_response_manager = model.GetOrCreate<SharedResponseManager>();
|
||||
Model main_model;
|
||||
auto* shared_response_manager =
|
||||
main_model.GetOrCreate<SharedResponseManager>();
|
||||
ModelSharedTimeLimit time_limit(&main_model);
|
||||
NeighborhoodGeneratorHelper helper(&proto, ¶ms, shared_response_manager,
|
||||
&time_limit);
|
||||
@@ -273,13 +279,14 @@ TEST(RelaxationInducedNeighborhoodGeneratorTest, NoNeighborhoodGeneratedRINS) {
|
||||
proto.mutable_objective()->add_coeffs(1);
|
||||
|
||||
Model model;
|
||||
auto* shared_response_manager = model.GetOrCreate<SharedResponseManager>();
|
||||
shared_response_manager->InitializeObjective(proto);
|
||||
SharedLPSolutionRepository lp_solutions(/*num_solutions_to_keep=*/1);
|
||||
SharedIncompleteSolutionManager incomplete_solutions;
|
||||
|
||||
SatParameters params;
|
||||
Model main_model;
|
||||
auto* shared_response_manager =
|
||||
main_model.GetOrCreate<SharedResponseManager>();
|
||||
shared_response_manager->InitializeObjective(proto);
|
||||
ModelSharedTimeLimit time_limit(&main_model);
|
||||
NeighborhoodGeneratorHelper helper(&proto, ¶ms, shared_response_manager,
|
||||
&time_limit);
|
||||
@@ -315,12 +322,13 @@ TEST(RelaxationInducedNeighborhoodGeneratorTest, NoNeighborhoodGeneratedRENS) {
|
||||
proto.mutable_objective()->add_coeffs(1);
|
||||
|
||||
Model model;
|
||||
auto* shared_response_manager = model.GetOrCreate<SharedResponseManager>();
|
||||
SharedLPSolutionRepository lp_solutions(/*num_solutions_to_keep=*/1);
|
||||
SharedIncompleteSolutionManager incomplete_solutions;
|
||||
|
||||
SatParameters params;
|
||||
Model main_model;
|
||||
auto* shared_response_manager =
|
||||
main_model.GetOrCreate<SharedResponseManager>();
|
||||
ModelSharedTimeLimit time_limit(&main_model);
|
||||
NeighborhoodGeneratorHelper helper(&proto, ¶ms, shared_response_manager,
|
||||
&time_limit);
|
||||
@@ -360,8 +368,9 @@ TEST(RelaxationInducedNeighborhoodGeneratorTest, ValueOutOfDomain) {
|
||||
lp_solutions.Synchronize();
|
||||
|
||||
SatParameters params;
|
||||
auto* shared_response_manager = model.GetOrCreate<SharedResponseManager>();
|
||||
Model main_model;
|
||||
auto* shared_response_manager =
|
||||
main_model.GetOrCreate<SharedResponseManager>();
|
||||
ModelSharedTimeLimit time_limit(&main_model);
|
||||
NeighborhoodGeneratorHelper helper(&proto, ¶ms, shared_response_manager,
|
||||
&time_limit);
|
||||
@@ -410,12 +419,13 @@ TEST(LocalBranchingNeighborhoodGeneratorTest,
|
||||
solution: [ 0, 0, 0 ])pb");
|
||||
|
||||
Model model;
|
||||
auto* shared_response_manager = model.GetOrCreate<SharedResponseManager>();
|
||||
SharedBoundsManager shared_bounds_manager(proto);
|
||||
shared_response_manager->InitializeObjective(proto);
|
||||
|
||||
SatParameters params;
|
||||
Model main_model;
|
||||
auto* shared_response_manager =
|
||||
main_model.GetOrCreate<SharedResponseManager>();
|
||||
shared_response_manager->InitializeObjective(proto);
|
||||
ModelSharedTimeLimit time_limit(&main_model);
|
||||
NeighborhoodGeneratorHelper helper(&proto, ¶ms, shared_response_manager,
|
||||
&time_limit);
|
||||
@@ -479,12 +489,13 @@ TEST(LocalBranchingNeighborhoodGeneratorTest,
|
||||
solution: [ 1, 1, 2 ])pb");
|
||||
|
||||
Model model;
|
||||
auto* shared_response_manager = model.GetOrCreate<SharedResponseManager>();
|
||||
SharedBoundsManager shared_bounds_manager(proto);
|
||||
shared_response_manager->InitializeObjective(proto);
|
||||
|
||||
SatParameters params;
|
||||
Model main_model;
|
||||
auto* shared_response_manager =
|
||||
main_model.GetOrCreate<SharedResponseManager>();
|
||||
shared_response_manager->InitializeObjective(proto);
|
||||
ModelSharedTimeLimit time_limit(&main_model);
|
||||
NeighborhoodGeneratorHelper helper(&proto, ¶ms, shared_response_manager,
|
||||
&time_limit);
|
||||
@@ -537,8 +548,9 @@ TEST(NeighborhoodGeneratorHelperTest, BoundAreUpdatedOnSynchronize) {
|
||||
SharedBoundsManager shared_bounds_manager(proto);
|
||||
|
||||
SatParameters params;
|
||||
auto* shared_response_manager = model.GetOrCreate<SharedResponseManager>();
|
||||
Model main_model;
|
||||
auto* shared_response_manager =
|
||||
main_model.GetOrCreate<SharedResponseManager>();
|
||||
ModelSharedTimeLimit time_limit(&main_model);
|
||||
NeighborhoodGeneratorHelper helper(&proto, ¶ms, shared_response_manager,
|
||||
&time_limit, &shared_bounds_manager);
|
||||
@@ -594,11 +606,12 @@ TEST(NeighborhoodGeneratorHelperTest, FixGivenVariables) {
|
||||
solution: [ 2, 3, 4 ])pb");
|
||||
|
||||
Model model;
|
||||
auto* shared_response_manager = model.GetOrCreate<SharedResponseManager>();
|
||||
SharedBoundsManager shared_bounds_manager(proto);
|
||||
|
||||
SatParameters params;
|
||||
Model main_model;
|
||||
auto* shared_response_manager =
|
||||
main_model.GetOrCreate<SharedResponseManager>();
|
||||
ModelSharedTimeLimit time_limit(&main_model);
|
||||
NeighborhoodGeneratorHelper helper(&proto, ¶ms, shared_response_manager,
|
||||
&time_limit, &shared_bounds_manager);
|
||||
@@ -646,11 +659,12 @@ TEST(NeighborhoodGeneratorHelperTest, InfeasibleCopyAndFixVariables) {
|
||||
solution: [ 2, 3, -2 ])pb");
|
||||
|
||||
Model model;
|
||||
auto* shared_response_manager = model.GetOrCreate<SharedResponseManager>();
|
||||
SharedBoundsManager shared_bounds_manager(proto);
|
||||
|
||||
SatParameters params;
|
||||
Model main_model;
|
||||
auto* shared_response_manager =
|
||||
main_model.GetOrCreate<SharedResponseManager>();
|
||||
ModelSharedTimeLimit time_limit(&main_model);
|
||||
NeighborhoodGeneratorHelper helper(&proto, ¶ms, shared_response_manager,
|
||||
&time_limit, &shared_bounds_manager);
|
||||
@@ -800,12 +814,13 @@ TEST(NeighborhoodGeneratorHelperTest, GetSchedulingPrecedences) {
|
||||
solution: [ 0, 0, 2, 3, 3, 4, 5, 5, 5, 6, 8, 8, 9 ])pb");
|
||||
|
||||
Model model;
|
||||
auto* shared_response_manager = model.GetOrCreate<SharedResponseManager>();
|
||||
SharedBoundsManager shared_bounds_manager(proto);
|
||||
|
||||
SatParameters params;
|
||||
Model main_model;
|
||||
ModelSharedTimeLimit time_limit(&main_model);
|
||||
auto* shared_response_manager =
|
||||
main_model.GetOrCreate<SharedResponseManager>();
|
||||
NeighborhoodGeneratorHelper helper(&proto, ¶ms, shared_response_manager,
|
||||
&time_limit, &shared_bounds_manager);
|
||||
random_engine_t random;
|
||||
|
||||
@@ -13231,11 +13231,10 @@ namespace {
|
||||
|
||||
// Updates the solution hint in the proto with the crushed solution values.
|
||||
void UpdateHintInProto(PresolveContext* context) {
|
||||
CpModelProto* proto = context->working_model;
|
||||
if (!proto->has_solution_hint()) return;
|
||||
if (context->ModelIsUnsat()) return;
|
||||
|
||||
SolutionCrush& crush = context->solution_crush();
|
||||
if (!crush.SolutionIsLoaded()) return;
|
||||
const int num_vars = context->working_model->variables().size();
|
||||
for (int i = 0; i < num_vars; ++i) {
|
||||
// If the initial hint is incomplete or infeasible, the crushed hint might
|
||||
@@ -13251,7 +13250,7 @@ void UpdateHintInProto(PresolveContext* context) {
|
||||
i, {{relation.representative, relation.coeff}}, relation.offset);
|
||||
}
|
||||
}
|
||||
crush.StoreSolutionAsHint(*proto);
|
||||
crush.StoreSolutionAsHint(*context->working_model);
|
||||
}
|
||||
|
||||
// Canonicalizes the routes constraints node expressions. In particular,
|
||||
|
||||
@@ -7921,6 +7921,26 @@ TEST(PresolveCpModelTest, InnerObjectiveLowerBound) {
|
||||
EXPECT_EQ(r.inner_objective_lower_bound(), 8);
|
||||
}
|
||||
|
||||
TEST(PresolveCpModelTest, ModelWithoutVariables) {
|
||||
const CpModelProto cp_model = ParseTestProto(
|
||||
R"pb(
|
||||
constraints {
|
||||
all_diff {
|
||||
exprs { offset: 1 }
|
||||
exprs { offset: 2 }
|
||||
}
|
||||
}
|
||||
)pb");
|
||||
|
||||
SatParameters params;
|
||||
params.set_log_search_progress(true);
|
||||
params.set_debug_crash_if_presolve_breaks_hint(true);
|
||||
params.set_cp_model_presolve(false);
|
||||
|
||||
CpSolverResponse response = SolveWithParameters(cp_model, params);
|
||||
EXPECT_EQ(response.status(), CpSolverStatus::OPTIMAL);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sat
|
||||
} // namespace operations_research
|
||||
|
||||
@@ -4751,6 +4751,57 @@ TEST(PresolveCpModelTest, CumulativeBug3) {
|
||||
EXPECT_EQ(response.inner_objective_lower_bound(), -6);
|
||||
}
|
||||
|
||||
TEST(PresolveCpModelTest, CumulativeBug4) {
|
||||
const CpModelProto cp_model = ParseTestProto(
|
||||
R"pb(
|
||||
variables { domain: 0 domain: 1 }
|
||||
variables { domain: 0 domain: 6 }
|
||||
variables { domain: -920 domain: -15 domain: 1540 domain: 1692 }
|
||||
variables { domain: 0 domain: 6 }
|
||||
variables { domain: 0 domain: 1 }
|
||||
variables { domain: -1 domain: 0 domain: 4096 domain: 4096 }
|
||||
variables { domain: 0 domain: 17 }
|
||||
constraints {
|
||||
enforcement_literal: 0
|
||||
interval {
|
||||
start { vars: 1 coeffs: 1 }
|
||||
end { vars: 3 coeffs: 1 }
|
||||
size { vars: 2 coeffs: 1 offset: 2 }
|
||||
}
|
||||
}
|
||||
constraints {
|
||||
enforcement_literal: 4
|
||||
interval {
|
||||
start { offset: 2 }
|
||||
end { vars: 6 coeffs: 1 }
|
||||
size { vars: 5 coeffs: 1 }
|
||||
}
|
||||
}
|
||||
constraints {
|
||||
cumulative {
|
||||
capacity { offset: 1 }
|
||||
intervals: 1
|
||||
demands { vars: 6 coeffs: 1 }
|
||||
}
|
||||
}
|
||||
constraints { bool_xor { literals: 0 literals: 4 } }
|
||||
)pb");
|
||||
|
||||
SatParameters params;
|
||||
params.set_log_search_progress(true);
|
||||
params.set_debug_crash_if_presolve_breaks_hint(true);
|
||||
params.set_cp_model_presolve(false);
|
||||
params.set_cp_model_probing_level(0);
|
||||
params.set_symmetry_level(0);
|
||||
|
||||
CpSolverResponse response = SolveWithParameters(cp_model, params);
|
||||
EXPECT_EQ(response.status(), CpSolverStatus::OPTIMAL);
|
||||
|
||||
params.set_cp_model_presolve(true);
|
||||
response = SolveWithParameters(cp_model, params);
|
||||
EXPECT_EQ(response.status(), CpSolverStatus::OPTIMAL);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sat
|
||||
} // namespace operations_research
|
||||
|
||||
@@ -82,7 +82,7 @@ std::function<void(Model*)> Cumulative(
|
||||
// If the interval can be of size zero, it currently do not count towards
|
||||
// the capacity. TODO(user): Change that since we have optional interval
|
||||
// for this.
|
||||
if (intervals->MinSize(vars[i]) == 0) {
|
||||
if (intervals->MinSize(vars[i]) <= 0) {
|
||||
enforcement_literals.push_back(encoder->GetOrCreateAssociatedLiteral(
|
||||
intervals->Size(vars[i]).GreaterOrEqual(IntegerValue(1))));
|
||||
}
|
||||
|
||||
@@ -1376,9 +1376,10 @@ void PresolveContext::InitializeNewDomains() {
|
||||
}
|
||||
|
||||
void PresolveContext::LoadSolutionHint() {
|
||||
absl::flat_hash_map<int, int64_t> hint_values;
|
||||
if (working_model->has_solution_hint()) {
|
||||
const int num_vars = working_model->variables().size();
|
||||
if (working_model->has_solution_hint() || num_vars == 0) {
|
||||
const auto hint_proto = working_model->solution_hint();
|
||||
absl::flat_hash_map<int, int64_t> hint_values;
|
||||
int num_changes = 0;
|
||||
for (int i = 0; i < hint_proto.vars().size(); ++i) {
|
||||
const int var = hint_proto.vars(i);
|
||||
@@ -1393,13 +1394,13 @@ void PresolveContext::LoadSolutionHint() {
|
||||
if (num_changes > 0) {
|
||||
UpdateRuleStats("hint: moved var hint within its domain.", num_changes);
|
||||
}
|
||||
for (int i = 0; i < working_model->variables().size(); ++i) {
|
||||
for (int i = 0; i < num_vars; ++i) {
|
||||
if (!hint_values.contains(i) && IsFixed(i)) {
|
||||
hint_values[i] = FixedValue(i);
|
||||
}
|
||||
}
|
||||
solution_crush_.LoadSolution(num_vars, hint_values);
|
||||
}
|
||||
solution_crush_.LoadSolution(working_model->variables().size(), hint_values);
|
||||
}
|
||||
|
||||
void PresolveContext::CanonicalizeDomainOfSizeTwo(int var) {
|
||||
|
||||
@@ -629,6 +629,7 @@ void SolutionCrush::AssignVariableToPackingArea(
|
||||
const CompactVectorVector<int, Rectangle>& areas, const CpModelProto& model,
|
||||
absl::Span<const int> x_intervals, absl::Span<const int> y_intervals,
|
||||
absl::Span<const BoxInAreaLiteral> box_in_area_lits) {
|
||||
if (!solution_is_loaded_) return;
|
||||
struct RectangleTypeAndIndex {
|
||||
enum class Type {
|
||||
kHintedBox,
|
||||
|
||||
Reference in New Issue
Block a user