15 #ifndef PAAL_KNAPSACK_FPTAS_COMMON_HPP
16 #define PAAL_KNAPSACK_FPTAS_COMMON_HPP
27 template <
typename Objects,
typename Functor>
29 double lowerBound, Functor,
31 double n = boost::distance(objects);
32 auto ret = n / (epsilon * lowerBound);
33 static const double SMALLEST_MULTIPLIER = 1.;
34 if (ret > SMALLEST_MULTIPLIER)
return boost::none;
43 template <
typename Objects,
typename Functor>
45 double lowerBound, Functor f,
48 double n = int(
double(lowerBound) * (1. + epsilon) / minF +
50 auto ret = n / (epsilon * lowerBound);
51 static const double SMALLEST_MULTIPLIER = 1.;
52 if (ret > SMALLEST_MULTIPLIER)
return boost::none;
56 template <
typename KnapsackData,
typename IsZeroOne,
typename RetrieveSolution,
57 typename ReturnType =
typename KnapsackData::return_type>
58 ReturnType knapsack_general_on_value_fptas(
double epsilon,
59 KnapsackData knap_data,
61 RetrieveSolution retrieve_solution) {
62 using ObjectRef =
typename KnapsackData::object_ref;
63 using Value =
typename KnapsackData::value;
64 using Size =
typename KnapsackData::size;
66 auto &&objects = knap_data.get_objects();
68 if (boost::empty(objects)) {
73 detail::get_value_bound(knap_data, is_0_1_Tag, lower_tag{});
75 knap_data.get_value(), is_0_1_Tag);
78 return knapsack_check_integrality(std::move(knap_data), is_0_1_Tag,
82 auto newValue = utils::make_scale_functor<double, Value>(
83 knap_data.get_value(), *multiplier);
84 auto ret = knapsack_check_integrality(
85 detail::make_knapsack_data(objects, knap_data.get_capacity(),
86 knap_data.get_size(), newValue,
87 knap_data.get_output_iter()),
88 is_0_1_Tag, retrieve_solution);
89 return std::make_pair(Value(
double(ret.first) / *multiplier), ret.second);
92 template <
typename KnapsackData,
typename IsZeroOne,
typename RetrieveSolution,
93 typename ReturnType =
typename KnapsackData::return_type>
94 ReturnType knapsack_general_on_size_fptas(
double epsilon,
95 KnapsackData knap_data,
97 RetrieveSolution retrieve_solution) {
98 using ObjectRef =
typename KnapsackData::object_ref;
99 using Size =
typename KnapsackData::size;
101 auto &&objects = knap_data.get_objects();
103 if (boost::empty(objects)) {
107 auto multiplier =
get_multiplier(objects, epsilon, knap_data.get_capacity(),
108 knap_data.get_size(), is_0_1_Tag);
111 return knapsack_check_integrality(std::move(knap_data), is_0_1_Tag,
115 auto newSize = utils::make_scale_functor<double, Size>(knap_data.get_size(),
117 auto ret = knapsack_check_integrality(
118 detail::make_knapsack_data(
119 objects, Size(knap_data.get_capacity() * *multiplier), newSize,
120 knap_data.get_value(), knap_data.get_output_iter()),
121 is_0_1_Tag, retrieve_solution);
122 return ReturnType(ret.first,
double(ret.second) / *multiplier);
125 template <
typename KnapsackData,
typename IsZeroOne>
126 typename KnapsackData::return_type
127 knapsack_general_on_value_fptas_retrieve(
double epsilon, KnapsackData knap_data,
128 IsZeroOne is_0_1_Tag) {
129 using ObjectRef =
typename KnapsackData::object_ref;
130 using Value =
typename KnapsackData::value;
133 auto addValue = [&](ObjectRef obj) {
134 realValue += knap_data.get_value(obj);
139 auto newOut = boost::make_function_output_iterator(addValue);
141 auto reducedReturn = knapsack_general_on_value_fptas(
142 epsilon, detail::make_knapsack_data(
143 knap_data.get_objects(), knap_data.get_capacity(),
144 knap_data.get_size(), knap_data.get_value(), newOut),
145 is_0_1_Tag, retrieve_solution_tag{});
146 return std::make_pair(realValue, reducedReturn.second);
149 template <
typename KnapsackData,
typename IsZeroOne,
150 typename ReturnType =
typename KnapsackData::return_type>
151 ReturnType knapsack_general_on_size_fptas_retrieve(
double epsilon,
152 KnapsackData knap_data,
153 IsZeroOne is_0_1_Tag) {
154 using ObjectRef =
typename KnapsackData::object_ref;
155 using Size =
typename KnapsackData::size;
158 auto add_size = [&](ObjectRef obj) {
159 realSize += knap_data.get_size(obj);
164 auto newOut = boost::make_function_output_iterator(add_size);
166 auto reducedReturn = knapsack_general_on_size_fptas(
167 epsilon, detail::make_knapsack_data(
168 knap_data.get_objects(), knap_data.get_capacity(),
169 knap_data.get_size(), knap_data.get_value(), newOut),
170 is_0_1_Tag, retrieve_solution_tag{});
171 return ReturnType(reducedReturn.first, realSize);
177 #endif // PAAL_KNAPSACK_FPTAS_COMMON_HPP
auto min_element_functor(Range &&range, Functor f)
combination of boost::min_element and boost::adaptors::transformed
boost::optional< double > get_multiplier(Objects &&objects, double epsilon, double lowerBound, Functor, detail::zero_one_tag)
computes multiplier for FPTAS, version for 0/1