gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Unify sources
0 2 0
r1.1.5 1.1
2 files changed with 2 insertions and 2 deletions:
↑ Collapse diff ↑
Ignore white space 1024 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/list_graph.h>
20 20
#include <lemon/lgf_reader.h>
21 21
#include "test_tools.h"
22 22

	
23 23
using namespace lemon;
24 24

	
25 25
char test_lgf[] =
26 26
  "@nodes\n"
27 27
  "label\n"
28 28
  "0\n"
29 29
  "1\n"
30 30
  "@arcs\n"
31 31
  "     label\n"
32 32
  "0 1  0\n"
33 33
  "1 0  1\n"
34 34
  "@attributes\n"
35 35
  "source 0\n"
36 36
  "target 1\n";
37 37

	
38 38
char test_lgf_nomap[] =
39 39
  "@nodes\n"
40 40
  "label\n"
41 41
  "0\n"
42 42
  "1\n"
43 43
  "@arcs\n"
44 44
  "     -\n"
45 45
  "0 1\n";
46 46

	
47 47
char test_lgf_bad1[] =
48 48
  "@nodes\n"
49 49
  "label\n"
50 50
  "0\n"
51 51
  "1\n"
52 52
  "@arcs\n"
53 53
  "     - another\n"
54 54
  "0 1\n";
55 55

	
56 56
char test_lgf_bad2[] =
57 57
  "@nodes\n"
58 58
  "label\n"
59 59
  "0\n"
60 60
  "1\n"
61 61
  "@arcs\n"
62 62
  "     label -\n"
63 63
  "0 1\n";
64 64

	
65 65

	
66 66
int main()
67 67
{
68 68
  {
69 69
    ListDigraph d;
70 70
    ListDigraph::Node s,t;
71 71
    ListDigraph::ArcMap<int> label(d);
72 72
    std::istringstream input(test_lgf);
73 73
    digraphReader(d, input).
74 74
      node("source", s).
75 75
      node("target", t).
76 76
      arcMap("label", label).
77 77
      run();
78 78
    check(countNodes(d) == 2,"There should be 2 nodes");
79 79
    check(countArcs(d) == 2,"There should be 2 arcs");
80 80
  }
81 81
  {
82 82
    ListGraph g;
83 83
    ListGraph::Node s,t;
84 84
    ListGraph::EdgeMap<int> label(g);
85 85
    std::istringstream input(test_lgf);
86 86
    graphReader(g, input).
87 87
      node("source", s).
88 88
      node("target", t).
89 89
      edgeMap("label", label).
90 90
      run();
91 91
    check(countNodes(g) == 2,"There should be 2 nodes");
92 92
    check(countEdges(g) == 2,"There should be 2 arcs");
93 93
  }
94 94

	
95 95
  {
96 96
    ListDigraph d;
97 97
    std::istringstream input(test_lgf_nomap);
98 98
    digraphReader(d, input).
99 99
      run();
100 100
    check(countNodes(d) == 2,"There should be 2 nodes");
101 101
    check(countArcs(d) == 1,"There should be 1 arc");
102 102
  }
103 103
  {
104 104
    ListGraph g;
105 105
    std::istringstream input(test_lgf_nomap);
106 106
    graphReader(g, input).
107 107
      run();
108 108
    check(countNodes(g) == 2,"There should be 2 nodes");
109 109
    check(countEdges(g) == 1,"There should be 1 edge");
110 110
  }
111 111

	
112 112
  {
113 113
    ListDigraph d;
114 114
    std::istringstream input(test_lgf_bad1);
115 115
    bool ok=false;
116 116
    try {
117 117
      digraphReader(d, input).
118 118
        run();
119 119
    }
120
    catch (FormatError&) 
120
    catch (FormatError&)
121 121
      {
122 122
        ok = true;
123 123
      }
124 124
    check(ok,"FormatError exception should have occured");
125 125
  }
126 126
  {
127 127
    ListGraph g;
128 128
    std::istringstream input(test_lgf_bad1);
129 129
    bool ok=false;
130 130
    try {
131 131
      graphReader(g, input).
132 132
        run();
133 133
    }
134 134
    catch (FormatError&)
135 135
      {
136 136
        ok = true;
137 137
      }
138 138
    check(ok,"FormatError exception should have occured");
139 139
  }
140 140

	
141 141
  {
142 142
    ListDigraph d;
143 143
    std::istringstream input(test_lgf_bad2);
144 144
    bool ok=false;
145 145
    try {
146 146
      digraphReader(d, input).
147 147
        run();
148 148
    }
149 149
    catch (FormatError&)
150 150
      {
151 151
        ok = true;
152 152
      }
153 153
    check(ok,"FormatError exception should have occured");
154 154
  }
155 155
  {
156 156
    ListGraph g;
157 157
    std::istringstream input(test_lgf_bad2);
158 158
    bool ok=false;
159 159
    try {
160 160
      graphReader(g, input).
161 161
        run();
162 162
    }
163 163
    catch (FormatError&)
164 164
      {
165 165
        ok = true;
166 166
      }
167 167
    check(ok,"FormatError exception should have occured");
168 168
  }
169 169
}
Ignore white space 1024 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2009
5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <sstream>
20 20
#include <lemon/lp_skeleton.h>
21 21
#include "test_tools.h"
22 22
#include <lemon/tolerance.h>
23 23

	
24 24
#include <lemon/config.h>
25 25

	
26 26
#ifdef LEMON_HAVE_GLPK
27 27
#include <lemon/glpk.h>
28 28
#endif
29 29

	
30 30
#ifdef LEMON_HAVE_CPLEX
31 31
#include <lemon/cplex.h>
32 32
#endif
33 33

	
34 34
#ifdef LEMON_HAVE_SOPLEX
35 35
#include <lemon/soplex.h>
36 36
#endif
37 37

	
38 38
#ifdef LEMON_HAVE_CLP
39 39
#include <lemon/clp.h>
40 40
#endif
41 41

	
42 42
using namespace lemon;
43 43

	
44 44
void lpTest(LpSolver& lp)
45 45
{
46 46

	
47 47
  typedef LpSolver LP;
48 48

	
49 49
  std::vector<LP::Col> x(10);
50 50
  //  for(int i=0;i<10;i++) x.push_back(lp.addCol());
51 51
  lp.addColSet(x);
52 52
  lp.colLowerBound(x,1);
53 53
  lp.colUpperBound(x,1);
54 54
  lp.colBounds(x,1,2);
55 55

	
56 56
  std::vector<LP::Col> y(10);
57 57
  lp.addColSet(y);
58 58

	
59 59
  lp.colLowerBound(y,1);
60 60
  lp.colUpperBound(y,1);
61 61
  lp.colBounds(y,1,2);
62 62

	
63 63
  std::map<int,LP::Col> z;
64 64

	
65 65
  z.insert(std::make_pair(12,INVALID));
66 66
  z.insert(std::make_pair(2,INVALID));
67 67
  z.insert(std::make_pair(7,INVALID));
68 68
  z.insert(std::make_pair(5,INVALID));
69 69

	
70 70
  lp.addColSet(z);
71 71

	
72 72
  lp.colLowerBound(z,1);
73 73
  lp.colUpperBound(z,1);
74 74
  lp.colBounds(z,1,2);
75 75

	
76 76
  {
77 77
    LP::Expr e,f,g;
78 78
    LP::Col p1,p2,p3,p4,p5;
79 79
    LP::Constr c;
80 80

	
81 81
    p1=lp.addCol();
82 82
    p2=lp.addCol();
83 83
    p3=lp.addCol();
84 84
    p4=lp.addCol();
85 85
    p5=lp.addCol();
86 86

	
87 87
    e[p1]=2;
88 88
    *e=12;
89 89
    e[p1]+=2;
90 90
    *e+=12;
91 91
    e[p1]-=2;
92 92
    *e-=12;
93 93

	
94 94
    e=2;
95 95
    e=2.2;
96 96
    e=p1;
97 97
    e=f;
98 98

	
99 99
    e+=2;
100 100
    e+=2.2;
101 101
    e+=p1;
102 102
    e+=f;
103 103

	
104 104
    e-=2;
105 105
    e-=2.2;
106 106
    e-=p1;
107 107
    e-=f;
108 108

	
109 109
    e*=2;
110 110
    e*=2.2;
111 111
    e/=2;
112 112
    e/=2.2;
113 113

	
114 114
    e=((p1+p2)+(p1-p2)+(p1+12)+(12+p1)+(p1-12)+(12-p1)+
115 115
       (f+12)+(12+f)+(p1+f)+(f+p1)+(f+g)+
116 116
       (f-12)+(12-f)+(p1-f)+(f-p1)+(f-g)+
117 117
       2.2*f+f*2.2+f/2.2+
118 118
       2*f+f*2+f/2+
119 119
       2.2*p1+p1*2.2+p1/2.2+
120 120
       2*p1+p1*2+p1/2
121 121
       );
122 122

	
123 123

	
124 124
    c = (e  <= f  );
125 125
    c = (e  <= 2.2);
126 126
    c = (e  <= 2  );
127 127
    c = (e  <= p1 );
128 128
    c = (2.2<= f  );
129 129
    c = (2  <= f  );
130 130
    c = (p1 <= f  );
131 131
    c = (p1 <= p2 );
132 132
    c = (p1 <= 2.2);
133 133
    c = (p1 <= 2  );
134 134
    c = (2.2<= p2 );
135 135
    c = (2  <= p2 );
136 136

	
137 137
    c = (e  >= f  );
138 138
    c = (e  >= 2.2);
139 139
    c = (e  >= 2  );
140 140
    c = (e  >= p1 );
141 141
    c = (2.2>= f  );
142 142
    c = (2  >= f  );
143 143
    c = (p1 >= f  );
144 144
    c = (p1 >= p2 );
145 145
    c = (p1 >= 2.2);
146 146
    c = (p1 >= 2  );
147 147
    c = (2.2>= p2 );
148 148
    c = (2  >= p2 );
149 149

	
150 150
    c = (e  == f  );
151 151
    c = (e  == 2.2);
152 152
    c = (e  == 2  );
153 153
    c = (e  == p1 );
154 154
    c = (2.2== f  );
155 155
    c = (2  == f  );
156 156
    c = (p1 == f  );
157 157
    //c = (p1 == p2 );
158 158
    c = (p1 == 2.2);
159 159
    c = (p1 == 2  );
160 160
    c = (2.2== p2 );
161 161
    c = (2  == p2 );
162 162

	
163 163
    c = ((2 <= e) <= 3);
164 164
    c = ((2 <= p1) <= 3);
165 165

	
166 166
    c = ((2 >= e) >= 3);
167 167
    c = ((2 >= p1) >= 3);
168 168

	
169 169
    { //Tests for #430
170 170
      LP::Col v=lp.addCol();
171 171
      LP::Constr c = v >= -3;
172 172
      c = c <= 4;
173 173
      LP::Constr c2;
174 174
      c2 = -3 <= v <= 4;
175 175
    }
176 176

	
177 177
    e[x[3]]=2;
178 178
    e[x[3]]=4;
179 179
    e[x[3]]=1;
180 180
    *e=12;
181 181

	
182 182
    lp.addRow(-LP::INF,e,23);
183 183
    lp.addRow(-LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
184 184
    lp.addRow(-LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
185 185

	
186 186
    lp.addRow(x[1]+x[3]<=x[5]-3);
187 187
    lp.addRow((-7<=x[1]+x[3]-12)<=3);
188 188
    lp.addRow(x[1]<=x[5]);
189 189

	
190 190
    std::ostringstream buf;
191 191

	
192 192

	
193 193
    e=((p1+p2)+(p1-0.99*p2));
194 194
    //e.prettyPrint(std::cout);
195 195
    //(e<=2).prettyPrint(std::cout);
196 196
    double tolerance=0.001;
197 197
    e.simplify(tolerance);
198 198
    buf << "Coeff. of p2 should be 0.01";
199 199
    check(e[p2]>0, buf.str());
200 200

	
201 201
    tolerance=0.02;
202 202
    e.simplify(tolerance);
203 203
    buf << "Coeff. of p2 should be 0";
204 204
    check(const_cast<const LpSolver::Expr&>(e)[p2]==0, buf.str());
205 205

	
206 206
    //Test for clone/new
207 207
    LP* lpnew = lp.newSolver();
208 208
    LP* lpclone = lp.cloneSolver();
209 209
    delete lpnew;
210 210
    delete lpclone;
211 211

	
212 212
  }
213 213

	
214 214
  {
215 215
    LP::DualExpr e,f,g;
216 216
    LP::Row p1 = INVALID, p2 = INVALID, p3 = INVALID,
217 217
      p4 = INVALID, p5 = INVALID;
218 218

	
219 219
    e[p1]=2;
220 220
    e[p1]+=2;
221 221
    e[p1]-=2;
222 222

	
223 223
    e=p1;
224 224
    e=f;
225 225

	
226 226
    e+=p1;
227 227
    e+=f;
228 228

	
229 229
    e-=p1;
230 230
    e-=f;
231 231

	
232 232
    e*=2;
233 233
    e*=2.2;
234 234
    e/=2;
235 235
    e/=2.2;
236 236

	
237 237
    e=((p1+p2)+(p1-p2)+
238 238
       (p1+f)+(f+p1)+(f+g)+
239 239
       (p1-f)+(f-p1)+(f-g)+
240 240
       2.2*f+f*2.2+f/2.2+
241 241
       2*f+f*2+f/2+
242 242
       2.2*p1+p1*2.2+p1/2.2+
243 243
       2*p1+p1*2+p1/2
244 244
       );
245 245
  }
246 246

	
247 247
}
248 248

	
249 249
void solveAndCheck(LpSolver& lp, LpSolver::ProblemType stat,
250 250
                   double exp_opt) {
251 251
  using std::string;
252 252
  lp.solve();
253 253

	
254 254
  std::ostringstream buf;
255 255
  buf << "PrimalType should be: " << int(stat) << int(lp.primalType());
256 256

	
257 257
  check(lp.primalType()==stat, buf.str());
258 258

	
259 259
  if (stat ==  LpSolver::OPTIMAL) {
260 260
    std::ostringstream sbuf;
261 261
    sbuf << "Wrong optimal value (" << lp.primal() <<") with "
262 262
         << lp.solverName() <<"\n     the right optimum is " << exp_opt;
263 263
    check(std::abs(lp.primal()-exp_opt) < 1e-3, sbuf.str());
264 264
  }
265 265
}
266 266

	
267 267
void aTest(LpSolver & lp)
268 268
{
269 269
  typedef LpSolver LP;
270 270

	
271 271
 //The following example is very simple
272 272

	
273 273
  typedef LpSolver::Row Row;
274 274
  typedef LpSolver::Col Col;
275 275

	
276 276

	
277 277
  Col x1 = lp.addCol();
278 278
  Col x2 = lp.addCol();
279 279

	
280 280

	
281 281
  //Constraints
282 282
  Row upright=lp.addRow(x1+2*x2 <=1);
283 283
  lp.addRow(x1+x2 >=-1);
284 284
  lp.addRow(x1-x2 <=1);
285 285
  lp.addRow(x1-x2 >=-1);
286 286
  //Nonnegativity of the variables
287 287
  lp.colLowerBound(x1, 0);
288 288
  lp.colLowerBound(x2, 0);
289 289
  //Objective function
290 290
  lp.obj(x1+x2);
291 291

	
292 292
  lp.sense(lp.MAX);
293 293

	
294 294
  //Testing the problem retrieving routines
295 295
  check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!");
296 296
  check(lp.sense() == lp.MAX,"This is a maximization!");
297 297
  check(lp.coeff(upright,x1)==1,"The coefficient in question is 1!");
298 298
  check(lp.colLowerBound(x1)==0,
299 299
        "The lower bound for variable x1 should be 0.");
300 300
  check(lp.colUpperBound(x1)==LpSolver::INF,
301 301
        "The upper bound for variable x1 should be infty.");
302 302
  check(lp.rowLowerBound(upright) == -LpSolver::INF,
303 303
        "The lower bound for the first row should be -infty.");
304 304
  check(lp.rowUpperBound(upright)==1,
305 305
        "The upper bound for the first row should be 1.");
306 306
  LpSolver::Expr e = lp.row(upright);
307 307
  check(e[x1] == 1, "The first coefficient should 1.");
308 308
  check(e[x2] == 2, "The second coefficient should 1.");
309 309

	
310 310
  lp.row(upright, x1+x2 <=1);
311 311
  e = lp.row(upright);
312 312
  check(e[x1] == 1, "The first coefficient should 1.");
313 313
  check(e[x2] == 1, "The second coefficient should 1.");
314 314

	
315 315
  LpSolver::DualExpr de = lp.col(x1);
316 316
  check(  de[upright] == 1, "The first coefficient should 1.");
317 317

	
318 318
  LpSolver* clp = lp.cloneSolver();
319 319

	
320 320
  //Testing the problem retrieving routines
321 321
  check(clp->objCoeff(x1)==1,"First term should be 1 in the obj function!");
322 322
  check(clp->sense() == clp->MAX,"This is a maximization!");
323 323
  check(clp->coeff(upright,x1)==1,"The coefficient in question is 1!");
324 324
  //  std::cout<<lp.colLowerBound(x1)<<std::endl;
325 325
  check(clp->colLowerBound(x1)==0,
326 326
        "The lower bound for variable x1 should be 0.");
327 327
  check(clp->colUpperBound(x1)==LpSolver::INF,
328 328
        "The upper bound for variable x1 should be infty.");
329 329

	
330 330
  check(lp.rowLowerBound(upright)==-LpSolver::INF,
331 331
        "The lower bound for the first row should be -infty.");
332 332
  check(lp.rowUpperBound(upright)==1,
333 333
        "The upper bound for the first row should be 1.");
334 334
  e = clp->row(upright);
335 335
  check(e[x1] == 1, "The first coefficient should 1.");
336 336
  check(e[x2] == 1, "The second coefficient should 1.");
337 337

	
338 338
  de = clp->col(x1);
339 339
  check(de[upright] == 1, "The first coefficient should 1.");
340 340

	
341 341
  delete clp;
342 342

	
343 343
  //Maximization of x1+x2
344 344
  //over the triangle with vertices (0,0) (0,1) (1,0)
345 345
  double expected_opt=1;
346 346
  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
347 347

	
348 348
  //Minimization
349 349
  lp.sense(lp.MIN);
350 350
  expected_opt=0;
351 351
  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
352 352

	
353 353
  //Vertex (-1,0) instead of (0,0)
354 354
  lp.colLowerBound(x1, -LpSolver::INF);
355 355
  expected_opt=-1;
356 356
  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
357 357

	
358 358
  //Erase one constraint and return to maximization
359 359
  lp.erase(upright);
360 360
  lp.sense(lp.MAX);
361 361
  expected_opt=LpSolver::INF;
362 362
  solveAndCheck(lp, LpSolver::UNBOUNDED, expected_opt);
363 363

	
364 364
  //Infeasibilty
365 365
  lp.addRow(x1+x2 <=-2);
366 366
  solveAndCheck(lp, LpSolver::INFEASIBLE, expected_opt);
367 367

	
368 368
}
369 369

	
370 370
template<class LP>
371 371
void cloneTest()
372 372
{
373 373
  //Test for clone/new
374 374

	
375 375
  LP* lp = new LP();
376 376
  LP* lpnew = lp->newSolver();
377 377
  LP* lpclone = lp->cloneSolver();
378 378
  delete lp;
379 379
  delete lpnew;
380 380
  delete lpclone;
381 381
}
382 382

	
383 383
int main()
384 384
{
385 385
  LpSkeleton lp_skel;
386 386
  lpTest(lp_skel);
387 387

	
388 388
#ifdef LEMON_HAVE_GLPK
389 389
  {
390 390
    GlpkLp lp_glpk1,lp_glpk2;
391 391
    lpTest(lp_glpk1);
392 392
    aTest(lp_glpk2);
393 393
    cloneTest<GlpkLp>();
394 394
  }
395 395
#endif
396 396

	
397 397
#ifdef LEMON_HAVE_CPLEX
398 398
  try {
399 399
    CplexLp lp_cplex1,lp_cplex2;
400 400
    lpTest(lp_cplex1);
401 401
    aTest(lp_cplex2);
402 402
    cloneTest<CplexLp>();
403 403
  } catch (CplexEnv::LicenseError& error) {
404 404
    check(false, error.what());
405 405
  }
406 406
#endif
407 407

	
408 408
#ifdef LEMON_HAVE_SOPLEX
409 409
  {
410 410
    SoplexLp lp_soplex1,lp_soplex2;
411 411
    lpTest(lp_soplex1);
412 412
    aTest(lp_soplex2);
413 413
    cloneTest<SoplexLp>();
414 414
  }
415 415
#endif
416 416

	
417 417
#ifdef LEMON_HAVE_CLP
418 418
  {
419 419
    ClpLp lp_clp1,lp_clp2;
420 420
    lpTest(lp_clp1);
421 421
    aTest(lp_clp2);
422 422
    cloneTest<ClpLp>();
423 423
  }
424 424
#endif
425 425

	
426 426
  return 0;
427 427
}
0 comments (0 inline)