利用AVL树实现搬箱问题的best fit策略

  1 //my.h

  2 //定义两个数据类型,货物Goods,箱子Box

  3 

  4 #include <vector>

  5 #include <cstddef>

  7 #include <iostream>

  8 struct Goods

  9 {

 10     int id;

 11     double weight;

 12     Goods(int i,double w):id(i),weight(w) { }

 13     ~Goods()

 14     { };

 15 };

 16 

 17 struct Box

 18 {

 19     int id;

 20     std::vector<Goods*> vG;

 21     double space;

 22     Box(int i,double f,Goods* x = NULL)

 23     {

 24         id = i;

 25         space = f;

 26         if(x != NULL)

 27             vG.push_back(x);

 28     }

 29 

 30     Box& operator-= (Goods& rhs)

 31     {

 32         space -= rhs.weight;

 33         vG.push_back(&rhs);

 34         return *this;

 35     }

42 Box(Box& rhs) 43 { 44 operator=(rhs); 45 } 46 47 48 Box& operator= (const Box& rhs) 49 { 50 if(this == &rhs) 51 return *this; 52 id = rhs.id; 53 space = rhs.space; 54 vG = rhs.vG; 55 return *this; 56 } 57 58 ~Box() 59 { 60 int n = vG.size(); 61 for(int i = 0; i < n; ++i) 62 delete vG[i]; 63 } 64 65 }; 66 67 bool operator< (const Box& lhs, const Box& rhs) 68 { 69 return (lhs.space < rhs.space); 70 } 71 bool operator== (const Box& lhs,const Box& rhs) 72 { 73 return (lhs.space == rhs.space && lhs.id == rhs.id); 74 } 75 bool operator<= (const Box& lhs,const Box& rhs) 76 { 77 return !(rhs < lhs); 78 } 79 bool operator> (const Box& lhs,int a) 80 { 81 return (lhs.space > a); 82 } 83 bool operator< (const Box& lhs,const Goods& rhs) 84 { 85 return (lhs.space < rhs.weight); 86 } 87 bool operator< (const Goods& lhs, const Box& rhs) 88 { 89 return (lhs.weight < rhs.space); 90 } 91 bool operator== (const Box& lhs,const Goods& rhs) 92 { 93 return (lhs.space == rhs.weight); 94 } 95 96 std::ostream& operator<< (std::ostream& out,const Box& b) 97 { 98 out << "Box: " << b.id << std::endl; 99 int n = b.vG.size(); 100 if( n > 0) 101 { 102 for(int i = 0; i < n-1; ++i) 103 out << "\t" << b.vG[i]->id << " " << b.vG[i]->weight << std::endl; 104 out << "\t" << b.vG[n-1]->id << " " << b.vG[n-1]->weight; 105 } 106 return out; 107 }

 

  1 //avl.h

  2 //主体部分,建立一个AVL树,实现best fit

  3 

  4 #include "my.h"

  5 #include <algorithm>

  6 //#include <utility>

  7 

  8 template<class T,class V>

  9 class Avl

 10 {

 11 public:

 12     Avl():root(NULL),len(0) { }

 13     Avl(const Avl& rhs)

 14     {

 15         operator= (rhs);

 16     }

 17 

 18     ~Avl()

 19     {

 20         makeEmpty();

 21     }

 22     void makeEmpty();

 23 

 24     void insert( V* x); //GOODS

 25 

 26     const Avl& operator= (const Avl& rhs)

 27     {

 28         if(this == &rhs)

 29             return *this;

 30         Avl temp(rhs);

 31         swap(*this,temp);

 32         return *this;

 33     }

 34 

 35     void output()

 36     {

 37         for(int i = 0; i < vT.size(); ++i)

 38             std::cout << *(vT[i]) << std::endl;

 39         output(root);

 40     }

 41 private:

 42     struct Node

 43     {

 44         T* element;

 45         Node *left;

 46         Node *right;

 47         int height;

 48 

 49         Node(T* x,Node *lt,Node *rt,int h = 0)

 50             :element(x),left(lt),right(rt),height(h) { }

 51         ~Node()

 52         {

 53             delete element;

 54             element = NULL;

 55         }

 56     };

 57     Node *root;

 58     int len;

 59     std::vector<T*> vT;

 60 

 61     int height(const Node* t) const

 62     { return t == NULL ? -1 : t->height; }

 63     

 64     void insert(T* x, Node* &t); //BOX

 65     //void insert(V* x, Node* &t); //GOODS

 66     void remove(Node* p,Node* &t);

 67     void percolateDown(Node* t);

 68     Node* find(V* x,Node* t);

 69     Node* findmin(Node* t) const;

 70     Node* findmax(Node* t) const;  //can't use const Node* t

 71     void rotateWithLeftChild(Node* & k2);

 72     void rotateWithRightChild(Node* & k2);

 73     void doubleWithLeftChild(Node* & k3);

 74     void doubleWithRightChild(Node* & k3);

 75     void makeEmpty(Node* & t);

 76     void output(Node* t)

 77     {

 78         if(t != NULL)

 79         {

 80             output(t->left);

 81             output(t->right);

 82             std::cout << *(t->element) << std::endl;

 83         }

 84     }

 85 };

 86 

 87 template<class T,class V>

 88 void Avl<T,V>::insert(V* x)

 89 {

 90     Node* t = find(x,root);

 91     if(t != NULL)

 92     {

 93         *(t->element) -= *x;

 94         //t->element->insert(x);

 95         if(*(t->element) > 1e-5)

 96             percolateDown(t);

 97         else

 98         {

 99             Node* p = t;

100             if(t->right)

101                 p = findmin(t->right);

102             else

103                 p = findmax(t->left);

104             remove(p,root);

105             swap(t->element,p->element);

106             vT.push_back(p->element);

107         }

108     }

109     else

110     {

111         T* b = new Box(len+1,1-x->weight,x);

112         //b->insert(x);

113         ++len;

114         insert(b,root);

115     }

116         

117 }

118 

119 template<class T,class V>

120 void Avl<T,V>::remove(Node* p, Node* & t)

121 {

122     if(t == NULL)

123         return;

124     else if(*(p->element) < *(t->element))

125     {

126         remove(p,t->left);        

127         if(height(t->left) - height(t->right) == -2)

128             rotateWithRightChild(t);

129 

130     }

131     else if(*(t->element) < *(p->element))

132     {

133         remove(p,t->right);

134         if(height(t->left) - height(t->right) == 2)

135             rotateWithLeftChild(t);

136     }

137     else

138     {

139         t = t->left != NULL ? t->left : t->right;

140         p->left = NULL;

141         p->right = NULL;

142         return;

143     }

144     t->height = max(height(t->left),height(t->right)) + 1;

145 }

146 

147 template<class T,class V>

148 void Avl<T,V>::insert(T* x, Node* &t)

149 {

150     if(t == NULL)

151         t = new Node(x,NULL,NULL);

152     else if( *x < *(t->element))

153     {

154         insert(x,t->left);

155         if(height(t->left) - height(t->right) == 2)

156         {

157             if(*x < *(t->left->element))

158                 rotateWithLeftChild(t);

159             else

160                 doubleWithLeftChild(t);

161         }

162     }

163     else

164     {

165         insert(x,t->right);

166         if(height(t->right) - height(t->left) == 2)

167         {

168             if( *(t->right->element) <= *x)

169                 rotateWithRightChild(t);

170             else

171                 doubleWithRightChild(t);

172         }

173     }

174     t->height = max(height(t->left),height(t->right)) + 1;

175 }

176 

177 template<class T,class V>

178 typename Avl<T,V>::Node* Avl<T,V>::find(V* x,Node* t)

179 {

180     Node* p = NULL;

181     while(t != NULL)

182     {   

183         if( *(t->element) < *x)

184         {

185             t = t->right;

186         }

187         else if( *x < *(t->element))

188         {

189             p = t;

190             t = t->left;

191         }   

192         else

193         {

194             p = t;

195             break;

196         }

197     }

198     return p;

199 }

200 

201 template<class T,class V>

202 void Avl<T,V>::percolateDown(Node* t)

203 {

204     while(t->left != NULL || t->right != NULL)

205     {

206         if(t->left != NULL && (*(t->element) < *(t->left->element)))

207         {

208             swap(t->element,t->left->element);

209             t = t->left;

210         }

211         else if(t->right != NULL && (*(t->right->element) < *(t->element)))

212         {

213             swap(t->element,t->right->element);

214             t = t->right;

215         }

216         else

217             break;

218     }

219 }

220 

221 template<class T,class V>

222 typename Avl<T,V>::Node* Avl<T,V>::findmin(Node* t) const  //can't use const Node* t

223 {

224     if(t != NULL)

225         while(t->left != NULL)

226             t = t->left;

227     return t;

228 }

229 

230 template<class T,class V>

231 typename Avl<T,V>::Node* Avl<T,V>::findmax(Node* t) const

232 {

233     if(t != NULL)

234         while(t->right != NULL)

235             t = t->right;

236     return t;

237 }

238 

239 template<class T,class V>

240 void Avl<T,V>::rotateWithLeftChild(Node* & k2)

241 {

242     Node* k1 = k2->left;

243     k2->left = k1->right;

244     k1->right = k2;

245     k2->height = max(height(k2->left),height(k2->right)) + 1;

246     k1->height = max(height(k1->left),k2->height) + 1;

247     k2 = k1;

248 }

249 

250 template<class T,class V>

251 void Avl<T,V>::rotateWithRightChild(Node* & k2)

252 {

253     Node* k1 = k2->right;

254     k2->right = k1->left;

255     k1->left = k2;

256     k2->height = max(height(k2->left),height(k2->right)) + 1;

257     k1->height = max(height(k1->left),k2->height) + 1;

258     k2 = k1;

259 }

260 

261 template<class T,class V>

262 void Avl<T,V>::doubleWithLeftChild(Node* & k3)

263 {

264     rotateWithRightChild(k3->left);

265     rotateWithLeftChild(k3);

266 }

267 

268 template<class T,class V>

269 void Avl<T,V>::doubleWithRightChild(Node* & k3)

270 {

271     rotateWithLeftChild(k3->right);

272     rotateWithRightChild(k3);

273 }

274 

275 template<class T,class V>

276 void Avl<T,V>::makeEmpty()

277 {

278     makeEmpty(root);

279 }

280 

281 template<class T,class V>

282 void Avl<T,V>::makeEmpty(Node* & t)

283 {

284     if(t != NULL)

285     {

286         makeEmpty(t->left);

287         makeEmpty(t->right);

288         delete t;

289     }

290     t = NULL;

291     for(int i = 0; i < vT.size(); ++i)

292         delete vT[i];

293 }

 

 1 //main.cpp

 2 /***********************************

 3 装箱问题:利用AVL树

 4 1、实现首次适配算法

 5 2、实现最佳适配算法

 6 作者:陈卫安

 7 时间:2014-04-09

 8 ***********************************/

 9 #include "avl.h"

10 //#include <iostream>

11 using namespace std;

12 

13 void inputGoods(vector<Goods*>& G)

14 {

15     double w;

16     int i = 0;

17     Goods* p = NULL;

18     while(cin)

19     {

20         cin >> w;

21         p = new Goods(i,w);

22         G.push_back(p);

23         i++;

24     }

25 }

26 

27 void FirstFit(Avl<Box,Goods>& boxtree,const vector<Goods*>& G)

28 {

29     for(int i = 0; i < G.size(); i++)

30         boxtree.insert(G[i]);

31 }

32 

33 int main()

34 {

35     Avl<Box,Goods> boxtree;

36     vector<Goods*> G;

37     inputGoods(G);

38     FirstFit(boxtree,G);

39     boxtree.output();

40     return 0;

41 }

 

思路:

  1、当树为空时,建立一个新节点(即开辟一个新箱子);

  2、若不为空,寻找最适合的节点(箱子),space =  1 - weight,然后下滤到合适位置;

  3、若箱子容量为0,从树中删除该节点(箱子),存到数组。

  4、若没有找到能够容下该货品的节点(箱子),开辟一个箱子,插入到树里。

编程时遇到的一些问题:

  1、函数形参Node* 前面不能加cosnt,如果加了const,只能传递const类型的数据指针作为实参。这点和传值Node& 不一样,const Node& 表示即可以传const类型的数据,也可以传非const类似的数据。

  2、Node* find()  返回一个类里面定义的数据类型,这是一个类型成员,类似vector<int>::size_type,需要在返回类型前面加类限定符,

  改为 typename Avl<T,V>::Node*  find()  ;需要在前面加typename限制,表明这是一个类型成员。

你可能感兴趣的:(Fit)