sat: Add symmetry_util_test.cc
This commit is contained in:
138
cmake/cpp.cmake
138
cmake/cpp.cmake
@@ -141,6 +141,78 @@ if(MSVC)
|
||||
)
|
||||
endif()
|
||||
|
||||
################
|
||||
## C++ Test ##
|
||||
################
|
||||
# ortools_cxx_test()
|
||||
# CMake function to generate and build C++ test.
|
||||
# Parameters:
|
||||
# FILE_NAME: the C++ filename
|
||||
# COMPONENT_NAME: name of the ortools/ subdir where the test is located
|
||||
# note: automatically determined if located in ortools/<component>/
|
||||
# e.g.:
|
||||
# ortools_cxx_test(
|
||||
# FILE_NAME
|
||||
# ${PROJECT_SOURCE_DIR}/ortools/foo/foo_test.cc
|
||||
# COMPONENT_NAME
|
||||
# foo
|
||||
# DEPS
|
||||
# GTest::gmock
|
||||
# GTest::gtest_main
|
||||
# )
|
||||
function(ortools_cxx_test)
|
||||
set(options "")
|
||||
set(oneValueArgs "FILE_NAME;COMPONENT_NAME")
|
||||
set(multiValueArgs "DEPS")
|
||||
cmake_parse_arguments(TEST
|
||||
"${options}"
|
||||
"${oneValueArgs}"
|
||||
"${multiValueArgs}"
|
||||
${ARGN}
|
||||
)
|
||||
if(NOT TEST_FILE_NAME)
|
||||
message(FATAL_ERROR "no FILE_NAME provided")
|
||||
endif()
|
||||
get_filename_component(TEST_NAME ${TEST_FILE_NAME} NAME_WE)
|
||||
|
||||
message(STATUS "Configuring test ${TEST_FILE_NAME} ...")
|
||||
|
||||
if(NOT TEST_COMPONENT_NAME)
|
||||
# test is located in ortools/<component_name>/
|
||||
get_filename_component(COMPONENT_DIR ${TEST_FILE_NAME} DIRECTORY)
|
||||
get_filename_component(COMPONENT_NAME ${COMPONENT_DIR} NAME)
|
||||
else()
|
||||
set(COMPONENT_NAME ${TEST_COMPONENT_NAME})
|
||||
endif()
|
||||
|
||||
add_executable(${TEST_NAME} ${TEST_FILE_NAME})
|
||||
target_include_directories(${TEST_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_compile_features(${TEST_NAME} PRIVATE cxx_std_17)
|
||||
target_link_libraries(${TEST_NAME} PRIVATE
|
||||
${PROJECT_NAMESPACE}::ortools
|
||||
${TEST_DEPS}
|
||||
)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
if(APPLE)
|
||||
set_target_properties(${TEST_NAME} PROPERTIES INSTALL_RPATH
|
||||
"@loader_path/../${CMAKE_INSTALL_LIBDIR};@loader_path")
|
||||
elseif(UNIX)
|
||||
cmake_path(RELATIVE_PATH CMAKE_INSTALL_FULL_LIBDIR
|
||||
BASE_DIRECTORY ${CMAKE_INSTALL_FULL_BINDIR}
|
||||
OUTPUT_VARIABLE libdir_relative_path)
|
||||
set_target_properties(${TEST_NAME} PROPERTIES
|
||||
INSTALL_RPATH "$ORIGIN/${libdir_relative_path}")
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_test(
|
||||
NAME cxx_${COMPONENT_NAME}_${TEST_NAME}
|
||||
COMMAND ${TEST_NAME})
|
||||
endif()
|
||||
message(STATUS "Configuring test ${TEST_FILE_NAME} ...DONE")
|
||||
endfunction()
|
||||
|
||||
##################
|
||||
## PROTO FILE ##
|
||||
##################
|
||||
@@ -556,72 +628,6 @@ install(DIRECTORY ortools/routing/docs/
|
||||
PATTERN "*.md")
|
||||
endif()
|
||||
|
||||
################
|
||||
## C++ Test ##
|
||||
################
|
||||
# add_cxx_test()
|
||||
# CMake function to generate and build C++ test.
|
||||
# Parameters:
|
||||
# FILE_NAME: the C++ filename
|
||||
# COMPONENT_NAME: name of the ortools/ subdir where the test is located
|
||||
# note: automatically determined if located in ortools/<component>/
|
||||
# e.g.:
|
||||
# add_cxx_test(
|
||||
# FILE_NAME
|
||||
# ${PROJECT_SOURCE_DIR}/ortools/foo/foo_test.cc
|
||||
# COMPONENT_NAME
|
||||
# foo
|
||||
# )
|
||||
function(add_cxx_test)
|
||||
set(options "")
|
||||
set(oneValueArgs FILE_NAME COMPONENT_NAME)
|
||||
set(multiValueArgs "")
|
||||
cmake_parse_arguments(TEST
|
||||
"${options}"
|
||||
"${oneValueArgs}"
|
||||
"${multiValueArgs}"
|
||||
${ARGN}
|
||||
)
|
||||
if(NOT TEST_FILE_NAME)
|
||||
message(FATAL_ERROR "no FILE_NAME provided")
|
||||
endif()
|
||||
get_filename_component(TEST_NAME ${TEST_FILE_NAME} NAME_WE)
|
||||
|
||||
message(STATUS "Configuring test ${TEST_FILE_NAME} ...")
|
||||
|
||||
if(NOT TEST_COMPONENT_NAME)
|
||||
# test is located in ortools/<component_name>/
|
||||
get_filename_component(COMPONENT_DIR ${TEST_FILE_NAME} DIRECTORY)
|
||||
get_filename_component(COMPONENT_NAME ${COMPONENT_DIR} NAME)
|
||||
else()
|
||||
set(COMPONENT_NAME ${TEST_COMPONENT_NAME})
|
||||
endif()
|
||||
|
||||
add_executable(${TEST_NAME} ${TEST_FILE_NAME})
|
||||
target_include_directories(${TEST_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_compile_features(${TEST_NAME} PRIVATE cxx_std_17)
|
||||
target_link_libraries(${TEST_NAME} PRIVATE ${PROJECT_NAMESPACE}::ortools)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
if(APPLE)
|
||||
set_target_properties(${TEST_NAME} PROPERTIES INSTALL_RPATH
|
||||
"@loader_path/../${CMAKE_INSTALL_LIBDIR};@loader_path")
|
||||
elseif(UNIX)
|
||||
cmake_path(RELATIVE_PATH CMAKE_INSTALL_FULL_LIBDIR
|
||||
BASE_DIRECTORY ${CMAKE_INSTALL_FULL_BINDIR}
|
||||
OUTPUT_VARIABLE libdir_relative_path)
|
||||
set_target_properties(${TEST_NAME} PROPERTIES
|
||||
INSTALL_RPATH "$ORIGIN/${libdir_relative_path}")
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_test(
|
||||
NAME cxx_${COMPONENT_NAME}_${TEST_NAME}
|
||||
COMMAND ${TEST_NAME})
|
||||
endif()
|
||||
message(STATUS "Configuring test ${TEST_FILE_NAME} ...DONE")
|
||||
endfunction()
|
||||
|
||||
##################
|
||||
## C++ Sample ##
|
||||
##################
|
||||
|
||||
@@ -18,7 +18,7 @@ endif()
|
||||
if(BUILD_CXX_EXAMPLES)
|
||||
file(GLOB CXX_SRCS "*.cc")
|
||||
foreach(FILE_NAME IN LISTS CXX_SRCS)
|
||||
add_cxx_test(FILE_NAME ${FILE_NAME})
|
||||
ortools_cxx_test(FILE_NAME ${FILE_NAME})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1035,6 +1035,17 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "symmetry_util_test",
|
||||
size = "small",
|
||||
srcs = ["symmetry_util_test.cc"],
|
||||
deps = [
|
||||
":symmetry_util",
|
||||
"//ortools/algorithms:sparse_permutation",
|
||||
"//ortools/base:gmock_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "var_domination",
|
||||
srcs = ["var_domination.cc"],
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
file(GLOB _SRCS "*.h" "*.cc")
|
||||
list(FILTER _SRCS EXCLUDE REGEX ".*/.*_test.cc")
|
||||
list(REMOVE_ITEM _SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/opb_reader.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sat_cnf_reader.h
|
||||
@@ -39,6 +40,19 @@ target_link_libraries(${NAME} PRIVATE
|
||||
${PROJECT_NAMESPACE}::ortools_proto)
|
||||
#add_library(${PROJECT_NAMESPACE}::sat ALIAS ${NAME})
|
||||
|
||||
if(BUILD_TESTING)
|
||||
file(GLOB _TEST_SRCS "*_test.cc")
|
||||
foreach(FILE_NAME IN LISTS _TEST_SRCS)
|
||||
ortools_cxx_test(
|
||||
FILE_NAME
|
||||
${FILE_NAME}
|
||||
DEPS
|
||||
GTest::gmock
|
||||
GTest::gtest_main
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Sat Runner
|
||||
add_executable(sat_runner)
|
||||
target_sources(sat_runner PRIVATE "sat_runner.cc")
|
||||
|
||||
134
ortools/sat/symmetry_util_test.cc
Normal file
134
ortools/sat/symmetry_util_test.cc
Normal file
@@ -0,0 +1,134 @@
|
||||
// Copyright 2010-2024 Google LLC
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "ortools/sat/symmetry_util.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "ortools/algorithms/sparse_permutation.h"
|
||||
#include "ortools/base/gmock.h"
|
||||
|
||||
namespace operations_research {
|
||||
namespace sat {
|
||||
namespace {
|
||||
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(GetOrbitsTest, BasicExample) {
|
||||
const int n = 10;
|
||||
std::vector<std::unique_ptr<SparsePermutation>> generators;
|
||||
generators.push_back(std::make_unique<SparsePermutation>(n));
|
||||
generators[0]->AddToCurrentCycle(0);
|
||||
generators[0]->AddToCurrentCycle(1);
|
||||
generators[0]->AddToCurrentCycle(2);
|
||||
generators[0]->CloseCurrentCycle();
|
||||
generators[0]->AddToCurrentCycle(7);
|
||||
generators[0]->AddToCurrentCycle(8);
|
||||
generators[0]->CloseCurrentCycle();
|
||||
|
||||
generators.push_back(std::make_unique<SparsePermutation>(n));
|
||||
generators[1]->AddToCurrentCycle(3);
|
||||
generators[1]->AddToCurrentCycle(2);
|
||||
generators[1]->AddToCurrentCycle(7);
|
||||
generators[1]->CloseCurrentCycle();
|
||||
const std::vector<int> orbits = GetOrbits(n, generators);
|
||||
for (const int i : std::vector<int>{0, 1, 2, 3, 7, 8}) {
|
||||
EXPECT_EQ(orbits[i], 0);
|
||||
}
|
||||
for (const int i : std::vector<int>{4, 5, 6, 9}) {
|
||||
EXPECT_EQ(orbits[i], -1);
|
||||
}
|
||||
}
|
||||
|
||||
// Recover for generators (in a particular form)
|
||||
// [0, 1, 2]
|
||||
// [4, 5, 3]
|
||||
// [8, 7, 6]
|
||||
TEST(BasicOrbitopeExtractionTest, BasicExample) {
|
||||
const int n = 10;
|
||||
std::vector<std::unique_ptr<SparsePermutation>> generators;
|
||||
|
||||
generators.push_back(std::make_unique<SparsePermutation>(n));
|
||||
generators[0]->AddToCurrentCycle(0);
|
||||
generators[0]->AddToCurrentCycle(1);
|
||||
generators[0]->CloseCurrentCycle();
|
||||
generators[0]->AddToCurrentCycle(4);
|
||||
generators[0]->AddToCurrentCycle(5);
|
||||
generators[0]->CloseCurrentCycle();
|
||||
generators[0]->AddToCurrentCycle(8);
|
||||
generators[0]->AddToCurrentCycle(7);
|
||||
generators[0]->CloseCurrentCycle();
|
||||
|
||||
generators.push_back(std::make_unique<SparsePermutation>(n));
|
||||
generators[1]->AddToCurrentCycle(2);
|
||||
generators[1]->AddToCurrentCycle(1);
|
||||
generators[1]->CloseCurrentCycle();
|
||||
generators[1]->AddToCurrentCycle(5);
|
||||
generators[1]->AddToCurrentCycle(3);
|
||||
generators[1]->CloseCurrentCycle();
|
||||
generators[1]->AddToCurrentCycle(6);
|
||||
generators[1]->AddToCurrentCycle(7);
|
||||
generators[1]->CloseCurrentCycle();
|
||||
|
||||
const std::vector<std::vector<int>> orbitope =
|
||||
BasicOrbitopeExtraction(generators);
|
||||
ASSERT_EQ(orbitope.size(), 3);
|
||||
EXPECT_THAT(orbitope[0], ElementsAre(0, 1, 2));
|
||||
EXPECT_THAT(orbitope[1], ElementsAre(4, 5, 3));
|
||||
EXPECT_THAT(orbitope[2], ElementsAre(8, 7, 6));
|
||||
}
|
||||
|
||||
// This one is trickier and is not an orbitope because 8 appear twice. So it
|
||||
// would be incorrect to "grow" the first two columns with the 3rd one.
|
||||
// [0, 1, 2]
|
||||
// [4, 5, 8]
|
||||
// [8, 7, 9]
|
||||
TEST(BasicOrbitopeExtractionTest, NotAnOrbitopeBecauseOfDuplicates) {
|
||||
const int n = 10;
|
||||
std::vector<std::unique_ptr<SparsePermutation>> generators;
|
||||
|
||||
generators.push_back(std::make_unique<SparsePermutation>(n));
|
||||
generators[0]->AddToCurrentCycle(0);
|
||||
generators[0]->AddToCurrentCycle(1);
|
||||
generators[0]->CloseCurrentCycle();
|
||||
generators[0]->AddToCurrentCycle(4);
|
||||
generators[0]->AddToCurrentCycle(5);
|
||||
generators[0]->CloseCurrentCycle();
|
||||
generators[0]->AddToCurrentCycle(8);
|
||||
generators[0]->AddToCurrentCycle(7);
|
||||
generators[0]->CloseCurrentCycle();
|
||||
|
||||
generators.push_back(std::make_unique<SparsePermutation>(n));
|
||||
generators[1]->AddToCurrentCycle(1);
|
||||
generators[1]->AddToCurrentCycle(2);
|
||||
generators[1]->CloseCurrentCycle();
|
||||
generators[1]->AddToCurrentCycle(5);
|
||||
generators[1]->AddToCurrentCycle(8);
|
||||
generators[1]->CloseCurrentCycle();
|
||||
generators[1]->AddToCurrentCycle(6);
|
||||
generators[1]->AddToCurrentCycle(9);
|
||||
generators[1]->CloseCurrentCycle();
|
||||
|
||||
const std::vector<std::vector<int>> orbitope =
|
||||
BasicOrbitopeExtraction(generators);
|
||||
ASSERT_EQ(orbitope.size(), 3);
|
||||
EXPECT_THAT(orbitope[0], ElementsAre(0, 1));
|
||||
EXPECT_THAT(orbitope[1], ElementsAre(4, 5));
|
||||
EXPECT_THAT(orbitope[2], ElementsAre(8, 7));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace sat
|
||||
} // namespace operations_research
|
||||
Reference in New Issue
Block a user