All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Macros Pages
get_bound.hpp
Go to the documentation of this file.
1 //=======================================================================
2 // Copyright (c) 2013 Piotr Wygocki
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //=======================================================================
15 #ifndef PAAL_GET_BOUND_HPP
16 #define PAAL_GET_BOUND_HPP
17 
21 
22 #include <boost/function_output_iterator.hpp>
23 
24 namespace paal {
25 namespace detail {
26 
27 template <typename SizeType, typename ValueType>
28 using GetIntegralTag = typename std::conditional<
29  std::is_integral<SizeType>::value && std::is_integral<ValueType>::value,
30  integral_value_and_size_tag,
31  typename std::conditional<
32  std::is_integral<SizeType>::value, integral_size_tag,
33  typename std::conditional<
34  std::is_integral<ValueType>::value, integral_value_tag,
35  non_integral_value_and_size_tag>::type>::type>::type;
36 
37 template <typename SizeType>
38 using Getarithmetic_size_tag = typename std::conditional<
39  std::is_arithmetic<SizeType>::value, arithmetic_size_tag,
40  Nonarithmetic_size_tag>::type;
41 
42 // this overloads checks if SizeType and ValueType are integral
43 
44 struct upper_tag{};
45 struct lower_tag{};
46 
52 template <typename KnapsackData >
53 typename KnapsackData::value get_density_based_value_upper_bound(KnapsackData knap_data) {
54  using Size = typename KnapsackData::size;
55  using ObjectRef = typename KnapsackData::object_ref;
56  auto density = knap_data.get_density();
57 
58  // this filters are really needed only in 0/1 case
59  // in unbounded case, there is a guarantee that sizes are not 0
60  auto not_zero_sizel = [=](ObjectRef obj) {return knap_data.get_size(obj) > Size{};};
61  auto not_zero_size = utils::make_assignable_functor(not_zero_sizel);
62  auto zeroSize = utils::make_not_functor(not_zero_size);
63 
64  auto not_zeros = knap_data.get_objects() | boost::adaptors::filtered(not_zero_size);
65  auto zeros = knap_data.get_objects() | boost::adaptors::filtered(zeroSize );
66 
67  auto maxElement = *max_element_functor(not_zeros, density);
68  return knap_data.get_capacity() * maxElement + sum_functor(zeros, knap_data.get_value());
69 }
70 
71 //non-arithmetic size, upper bound
72 template <typename KnapsackData,
73  typename Is_0_1_Tag>
74 typename KnapsackData::value get_value_bound(
75  KnapsackData knap_data,
76  Nonarithmetic_size_tag, Is_0_1_Tag, upper_tag) {
77  return get_density_based_value_upper_bound(std::move(knap_data));
78 }
79 
80 //arithmetic size, upper bound
81 template <typename KnapsackData, typename Is_0_1_Tag>
82 typename KnapsackData::value get_value_bound(
83  KnapsackData knap_data,
84  arithmetic_size_tag, Is_0_1_Tag is_0_1_Tag, upper_tag) {
85  return std::min(2 * get_value_bound(knap_data, is_0_1_Tag, lower_tag{}),
87 }
88 
89 //non-arithmetic size, lower bound
90 template <typename KnapsackData, typename Is_0_1_Tag>
91 typename KnapsackData::value get_value_bound(KnapsackData knap_data,
92  Nonarithmetic_size_tag, Is_0_1_Tag, lower_tag) {
93  //computes lower bound as value of the most valuable element
94  return *max_element_functor(knap_data.get_objects(), knap_data.get_value()).base();
95 }
96 
97 //arithmetic size, lower bound
98 template <typename KnapsackData, typename Is_0_1_Tag>
99 typename KnapsackData::value get_value_bound(KnapsackData knap_data,
100  arithmetic_size_tag, Is_0_1_Tag is_0_1_Tag, lower_tag) {
101  auto out = boost::make_function_output_iterator(utils::skip_functor{});
102  return knapsack_general_two_app(detail::make_knapsack_data(knap_data.get_objects(),
103  knap_data.get_capacity(), knap_data.get_size(), knap_data.get_value(), out), is_0_1_Tag).first;
104 }
105 
106 //decide whether size is arithmetic or not
107 template <typename KnapsackData, typename Is_0_1_Tag, typename BoundType>
108 typename KnapsackData::value get_value_bound(KnapsackData knap_data,
109  Is_0_1_Tag is_0_1_tag, BoundType bound_type_tag) {
110  return get_value_bound(std::move(knap_data),
111  Getarithmetic_size_tag<typename KnapsackData::size>{},
112  is_0_1_tag, bound_type_tag);
113 }
114 
115 }
116 }
117 #endif // PAAL_GET_BOUND_HPP
auto max_element_functor(Range &&range, Functor f)
combination of boost::max_element and boost::adaptors::transformed
auto make_assignable_functor(Functor &f)
make function for assignable_functor
Definition: functors.hpp:421
KnapsackData::value get_density_based_value_upper_bound(KnapsackData knap_data)
upper bound is computed as biggest density times capacity + values for all elements with size 0...
Definition: get_bound.hpp:53
auto make_not_functor(Functor functor)
make for Not
Definition: functors.hpp:922
Functor does nothing.
Definition: functors.hpp:52
density functor, for given value and size
auto sum_functor(const Range &rng, Functor f)
sum of functor values over the range elements