/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* */ /* This file is part of the program and library */ /* PaPILO --- Parallel Presolve for Integer and Linear Optimization */ /* */ /* Copyright (C) 2020-2022 Konrad-Zuse-Zentrum */ /* fuer Informationstechnik Berlin */ /* */ /* This program is free software: you can redistribute it and/or modify */ /* it under the terms of the GNU Lesser General Public License as published */ /* by the Free Software Foundation, either version 3 of the License, or */ /* (at your option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU Lesser General Public License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License */ /* along with this program. If not, see . */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef _PAPILO_CORE_VARIABLE_DOMAINS_HPP_ #define _PAPILO_CORE_VARIABLE_DOMAINS_HPP_ #include "papilo/misc/Flags.hpp" #include "papilo/misc/MultiPrecision.hpp" #include "papilo/misc/Vec.hpp" #include "papilo/misc/compress_vector.hpp" #ifdef PAPILO_TBB #include "papilo/misc/tbb.hpp" #endif namespace papilo { enum class ColFlag : uint8_t { kNone = 0, kLbInf = 1 << 0, kLbHuge = 1 << 1, kUbInf = 1 << 2, kUbHuge = 1 << 3, kIntegral = 1 << 4, kFixed = 1 << 5, kSubstituted = 1 << 6, kImplInt = 1 << 7, kUnbounded = static_cast( ColFlag::kLbInf ) | static_cast( ColFlag::kUbInf ), kInactive = static_cast( ColFlag::kFixed ) | static_cast( ColFlag::kSubstituted ), kLbUseless = static_cast( ColFlag::kLbInf ) | static_cast( ColFlag::kLbHuge ), kUbUseless = static_cast( ColFlag::kUbInf ) | static_cast( ColFlag::kUbHuge ), }; using ColFlags = Flags; /// Type to store the domains for the variables in a problem. /// This includes the lower and upper bounds, and whether the /// variable is constraint to integral values. template struct VariableDomains { Vec lower_bounds; Vec upper_bounds; Vec flags; void compress( const Vec& colmapping, bool full = false ); bool isBinary( int col ) const { return flags[col].test( ColFlag::kIntegral ) && !flags[col].test( ColFlag::kLbUseless, ColFlag::kUbUseless, ColFlag::kInactive ) && lower_bounds[col] == 0 && upper_bounds[col] == 1; } template void serialize( Archive& ar, const unsigned int version ) { ar& lower_bounds; ar& upper_bounds; ar& flags; } }; #ifdef PAPILO_USE_EXTERN_TEMPLATES extern template struct VariableDomains; extern template struct VariableDomains; extern template struct VariableDomains; #endif template void VariableDomains::compress( const Vec& colmapping, bool full ) { #ifdef PAPILO_TBB tbb::parallel_invoke( [this, &colmapping, full]() { compress_vector( colmapping, lower_bounds ); if( full ) lower_bounds.shrink_to_fit(); }, [this, &colmapping, full]() { compress_vector( colmapping, upper_bounds ); if( full ) upper_bounds.shrink_to_fit(); }, [this, &colmapping, full]() { compress_vector( colmapping, flags ); if( full ) flags.shrink_to_fit(); } ); #else compress_vector( colmapping, lower_bounds ); compress_vector( colmapping, upper_bounds ); compress_vector( colmapping, flags ); if( full ) { flags.shrink_to_fit(); upper_bounds.shrink_to_fit(); lower_bounds.shrink_to_fit(); } #endif } } // namespace papilo #endif