this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Christian Schulte <schulte@gecode.org>
5 *
6 * Copyright:
7 * Christian Schulte, 2010
8 *
9 * This file is part of Gecode, the generic constraint
10 * development environment:
11 * http://www.gecode.org
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining
14 * a copy of this software and associated documentation files (the
15 * "Software"), to deal in the Software without restriction, including
16 * without limitation the rights to use, copy, modify, merge, publish,
17 * distribute, sublicense, and/or sell copies of the Software, and to
18 * permit persons to whom the Software is furnished to do so, subject to
19 * the following conditions:
20 *
21 * The above copyright notice and this permission notice shall be
22 * included in all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 *
32 */
33
34namespace Gecode { namespace Int { namespace BinPacking {
35
36 /*
37 * Item
38 *
39 */
40 forceinline
41 Item::Item(void)
42 : s(0) {}
43 forceinline
44 Item::Item(IntView b, int s0)
45 : DerivedView<IntView>(b), s(s0) {}
46
47 forceinline IntView
48 Item::bin(void) const {
49 return x;
50 }
51 forceinline
52 void Item::bin(IntView b) {
53 x = b;
54 }
55 forceinline int
56 Item::size(void) const {
57 return s;
58 }
59 forceinline void
60 Item::size(int s0) {
61 s = s0;
62 }
63
64 forceinline void
65 Item::update(Space& home, Item& i) {
66 x.update(home,i.x);
67 s = i.s;
68 }
69
70
71 forceinline bool
72 operator ==(const Item& i, const Item& j) {
73 return (i.bin() == j.bin()) && (i.size() == j.size());
74 }
75 forceinline bool
76 operator !=(const Item& i, const Item& j) {
77 return !(i == j);
78 }
79
80 /// For sorting according to size
81 forceinline bool
82 operator <(const Item& i, const Item& j) {
83 return i.size() > j.size();
84 }
85
86
87 /*
88 * Size set
89 *
90 */
91 forceinline
92 SizeSet::SizeSet(void) {}
93 forceinline
94 SizeSet::SizeSet(Region& region, int n_max)
95 : n(0), t(0), s(region.alloc<int>(n_max)) {}
96 forceinline void
97 SizeSet::add(int s0) {
98 t += s0; s[n++] = s0;
99 }
100 forceinline int
101 SizeSet::card(void) const {
102 return n;
103 }
104 forceinline int
105 SizeSet::total(void) const {
106 return t;
107 }
108 forceinline int
109 SizeSet::operator [](int i) const {
110 return s[i];
111 }
112
113 forceinline
114 SizeSetMinusOne::SizeSetMinusOne(void) {}
115 forceinline
116 SizeSetMinusOne::SizeSetMinusOne(Region& region, int n_max)
117 : SizeSet(region,n_max), p(-1) {}
118 forceinline void
119 SizeSetMinusOne::minus(int s0) {
120 // This rests on the fact that items are removed in order
121 do
122 p++;
123 while (s[p] > s0);
124 assert(p < n);
125 }
126 forceinline int
127 SizeSetMinusOne::card(void) const {
128 assert(p >= 0);
129 return n - 1;
130 }
131 forceinline int
132 SizeSetMinusOne::total(void) const {
133 assert(p >= 0);
134 return t - s[p];
135 }
136 forceinline int
137 SizeSetMinusOne::operator [](int i) const {
138 assert(p >= 0);
139 return s[(i < p) ? i : i+1];
140 }
141
142
143
144 /*
145 * Packing propagator
146 *
147 */
148
149 forceinline
150 Pack::Pack(Home home, ViewArray<OffsetView>& l0, ViewArray<Item>& bs0)
151 : Propagator(home), l(l0), bs(bs0), t(0) {
152 l.subscribe(home,*this,PC_INT_BND);
153 bs.subscribe(home,*this,PC_INT_DOM);
154 for (int i=0; i<bs.size(); i++)
155 t += bs[i].size();
156 }
157
158 forceinline
159 Pack::Pack(Space& home, Pack& p)
160 : Propagator(home,p), t(p.t) {
161 l.update(home,p.l);
162 bs.update(home,p.bs);
163 }
164
165 forceinline size_t
166 Pack::dispose(Space& home) {
167 l.cancel(home,*this,PC_INT_BND);
168 bs.cancel(home,*this,PC_INT_DOM);
169 (void) Propagator::dispose(home);
170 return sizeof(*this);
171 }
172
173 template<class SizeSet>
174 forceinline bool
175 Pack::nosum(const SizeSet& s, int a, int b, int& ap, int& bp) {
176 if ((a <= 0) || (b >= s.total()))
177 return false;
178 int n=s.card()-1;
179 int sc=0;
180 int kp=0;
181 while (sc + s[n-kp] < a) {
182 sc += s[n-kp];
183 kp++;
184 }
185 int k=0;
186 int sa=0, sb = s[n-kp];
187 while ((sa < a) && (sb <= b)) {
188 sa += s[k++];
189 if (sa < a) {
190 kp--;
191 sb += s[n-kp];
192 sc -= s[n-kp];
193 while (sa + sc >= a) {
194 kp--;
195 sc -= s[n-kp];
196 sb += s[n-kp] - s[n-kp-k-1];
197 }
198 }
199 }
200 ap = sa + sc; bp = sb;
201 return sa < a;
202 }
203
204 template<class SizeSet>
205 forceinline bool
206 Pack::nosum(const SizeSet& s, int a, int b) {
207 int ap, bp;
208 return nosum(s, a, b, ap, bp);
209 }
210
211}}}
212
213// STATISTICS: int-prop
214