1/* $Id: CoinLpIO.hpp 1448 2011-06-19 15:34:41Z stefan $ */
2// Last edit: 11/5/08
3//
4// Name: CoinLpIO.hpp; Support for Lp files
5// Author: Francois Margot
6// Tepper School of Business
7// Carnegie Mellon University, Pittsburgh, PA 15213
8// email: fmargot@andrew.cmu.edu
9// Date: 12/28/03
10//-----------------------------------------------------------------------------
11// Copyright (C) 2003, Francois Margot, International Business Machines
12// Corporation and others. All Rights Reserved.
13// This code is licensed under the terms of the Eclipse Public License (EPL).
14
15
16#include <cstdio>
17
18class CoinPackedMatrix;
19#include "CoinMessage.hpp"
20
21typedef int COINColumnIndex;
22
23 /** Class to read and write Lp files
24
25 Lp file format:
26
27/ this is a comment <BR>
28\ this too <BR>
29 Min<BR>
30 obj: x0 + x1 + 3 x2 - 4.5 xyr + 1 <BR>
31 s.t. <BR>
32 cons1: x0 - x2 - 2.3 x4 <= 4.2 / this is another comment <BR>
33 c2: x1 + x2 >= 1 <BR>
34 cc: x1 + x2 + xyr = 2 <BR>
35 Bounds <BR>
36 0 <= x1 <= 3 <BR>
37 1 >= x2 <BR>
38 x3 = 1 <BR>
39 -2 <= x4 <= Inf <BR>
40 xyr free <BR>
41 Integers <BR>
42 x0 <BR>
43 Generals <BR>
44 x1 xyr <BR>
45 Binaries <BR>
46 x2 <BR>
47 End
48
49Notes: <UL>
50 <LI> Keywords are: Min, Max, Minimize, Maximize, s.t., Subject To,
51 Bounds, Integers, Generals, Binaries, End, Free, Inf.
52 <LI> Keywords are not case sensitive and may be in plural or singular form.
53 They should not be used as objective, row or column names.
54 <LI> Bounds, Integers, Generals, Binaries sections are optional.
55 <LI> Generals and Integers are synonymous.
56 <LI> Bounds section (if any) must come before Integers, Generals, and
57 Binaries sections.
58 <LI> Row names must be followed by ':' without blank space.
59 Row names are optional. If row names are present,
60 they must be distinct (if the k-th constraint has no given name, its name
61 is set automatically to "consk" for k=0,...,).
62 For valid row names, see the method is_invalid_name().
63 <LI> Column names must be followed by a blank space. They must be distinct.
64 For valid column names, see the method is_invalid_name().
65 <LI> The objective function name must be followed by ':' without blank space.
66 Objective function name is optional (if no objective function name
67 is given, it is set to "obj" by default).
68 For valid objective function names, see the method is_invalid_name().
69 <LI> Ranged constraints are written as two constraints.
70 If a name is given for a ranged constraint, the upper bound constraint
71 has that name and the lower bound constraint has that name with "_low"
72 as suffix. This should be kept in mind when assigning names to ranged
73 constraint, as the resulting name must be distinct from all the other
74 names and be considered valid by the method is_invalid_name().
75 <LI> At most one constant term may appear in the objective function;
76 if present, it must appear last.
77 <LI> Default bounds are 0 for lower bound and +infinity for upper bound.
78 <LI> Free variables get default lower bound -infinity and
79 default upper bound +infinity. Writing "x0 Free" in an
80 LP file means "set lower bound on x0 to -infinity".
81 <LI> If more than one upper (resp. lower) bound on a variable appears in
82 the Bounds section, the last one is the one taken into
83 account. The bounds for a binary variable are set to 0/1 only if this
84 bound is stronger than the bound obtained from the Bounds section.
85 <LI> Numbers larger than DBL_MAX (or larger than 1e+400) in the input file
86 might crash the code.
87 <LI> A comment must start with '\' or '/'. That symbol must either be
88 the first character of a line or be preceded by a blank space. The
89 comment ends at the end of the
90 line. Comments are skipped while reading an Lp file and they may be
91 inserted anywhere.
92</UL>
93*/
94class CoinLpIO {
95
96public:
97
98 /**@name Constructor and Destructor */
99 //@{
100 /// Default Constructor
101 CoinLpIO();
102
103 /// Destructor
104 ~CoinLpIO();
105
106 /** Free the vector previous_names_[section] and set
107 card_previous_names_[section] to 0.
108 section = 0 for row names,
109 section = 1 for column names.
110 */
111 void freePreviousNames(const int section);
112
113 /// Free all memory (except memory related to hash tables and objName_).
114 void freeAll();
115 //@}
116
117 /** A quick inlined function to convert from lb/ub style constraint
118 definition to sense/rhs/range style */
119 inline void
120 convertBoundToSense(const double lower, const double upper,
121 char& sense, double& right, double& range) const;
122
123 /**@name Queries */
124 //@{
125
126 /// Get the problem name
127 const char * getProblemName() const;
128
129 /// Set problem name
130 void setProblemName(const char *name);
131
132 /// Get number of columns
133 int getNumCols() const;
134
135 /// Get number of rows
136 int getNumRows() const;
137
138 /// Get number of nonzero elements
139 int getNumElements() const;
140
141 /// Get pointer to array[getNumCols()] of column lower bounds
142 const double * getColLower() const;
143
144 /// Get pointer to array[getNumCols()] of column upper bounds
145 const double * getColUpper() const;
146
147 /// Get pointer to array[getNumRows()] of row lower bounds
148 const double * getRowLower() const;
149
150 /// Get pointer to array[getNumRows()] of row upper bounds
151 const double * getRowUpper() const;
152 /** Get pointer to array[getNumRows()] of constraint senses.
153 <ul>
154 <li>'L': <= constraint
155 <li>'E': = constraint
156 <li>'G': >= constraint
157 <li>'R': ranged constraint
158 <li>'N': free constraint
159 </ul>
160 */
161 const char * getRowSense() const;
162
163 /** Get pointer to array[getNumRows()] of constraint right-hand sides.
164
165 Given constraints with upper (rowupper) and/or lower (rowlower) bounds,
166 the constraint right-hand side (rhs) is set as
167 <ul>
168 <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i]
169 <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i]
170 <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i]
171 <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0
172 </ul>
173 */
174 const double * getRightHandSide() const;
175
176 /** Get pointer to array[getNumRows()] of row ranges.
177
178 Given constraints with upper (rowupper) and/or lower (rowlower) bounds,
179 the constraint range (rowrange) is set as
180 <ul>
181 <li> if rowsense()[i] == 'R' then
182 rowrange()[i] == rowupper()[i] - rowlower()[i]
183 <li> if rowsense()[i] != 'R' then
184 rowrange()[i] is 0.0
185 </ul>
186 Put another way, only ranged constraints have a nontrivial value for
187 rowrange.
188 */
189 const double * getRowRange() const;
190
191 /// Get pointer to array[getNumCols()] of objective function coefficients
192 const double * getObjCoefficients() const;
193
194 /// Get pointer to row-wise copy of the coefficient matrix
195 const CoinPackedMatrix * getMatrixByRow() const;
196
197 /// Get pointer to column-wise copy of the coefficient matrix
198 const CoinPackedMatrix * getMatrixByCol() const;
199
200 /// Get objective function name
201 const char * getObjName() const;
202
203 /// Get pointer to array[*card_prev] of previous row names.
204 /// The value of *card_prev might be different than getNumRows()+1 if
205 /// non distinct
206 /// row names were present or if no previous names were saved or if
207 /// the object was holding a different problem before.
208 void getPreviousRowNames(char const * const * prev,
209 int *card_prev) const;
210
211 /// Get pointer to array[*card_prev] of previous column names.
212 /// The value of *card_prev might be different than getNumCols() if non
213 /// distinct column names were present of if no previous names were saved,
214 /// or if the object was holding a different problem before.
215 void getPreviousColNames(char const * const * prev,
216 int *card_prev) const;
217
218 /// Get pointer to array[getNumRows()+1] of row names, including
219 /// objective function name as last entry.
220 char const * const * getRowNames() const;
221
222 /// Get pointer to array[getNumCols()] of column names
223 char const * const *getColNames() const;
224
225 /// Return the row name for the specified index.
226 /// Return the objective function name if index = getNumRows().
227 /// Return 0 if the index is out of range or if row names are not defined.
228 const char * rowName(int index) const;
229
230 /// Return the column name for the specified index.
231 /// Return 0 if the index is out of range or if column names are not
232 /// defined.
233 const char * columnName(int index) const;
234
235 /// Return the index for the specified row name.
236 /// Return getNumRows() for the objective function name.
237 /// Return -1 if the name is not found.
238 int rowIndex(const char * name) const;
239
240 /// Return the index for the specified column name.
241 /// Return -1 if the name is not found.
242 int columnIndex(const char * name) const;
243
244 ///Returns the (constant) objective offset
245 double objectiveOffset() const;
246
247 /// Set objective offset
248 inline void setObjectiveOffset(double value)
249 { objectiveOffset_ = value;}
250
251 /// Return true if a column is an integer (binary or general
252 /// integer) variable
253 bool isInteger(int columnNumber) const;
254
255 /// Get characteristic vector of integer variables
256 const char * integerColumns() const;
257 //@}
258
259 /**@name Parameters */
260 //@{
261 /// Get infinity
262 double getInfinity() const;
263
264 /// Set infinity. Any number larger is considered infinity.
265 /// Default: DBL_MAX
266 void setInfinity(const double);
267
268 /// Get epsilon
269 double getEpsilon() const;
270
271 /// Set epsilon.
272 /// Default: 1e-5.
273 void setEpsilon(const double);
274
275 /// Get numberAcross, the number of monomials to be printed per line
276 int getNumberAcross() const;
277
278 /// Set numberAcross.
279 /// Default: 10.
280 void setNumberAcross(const int);
281
282 /// Get decimals, the number of digits to write after the decimal point
283 int getDecimals() const;
284
285 /// Set decimals.
286 /// Default: 5
287 void setDecimals(const int);
288 //@}
289
290 /**@name Public methods */
291 //@{
292 /** Set the data of the object.
293 Set it from the coefficient matrix m, the lower bounds
294 collb, the upper bounds colub, objective function obj_coeff,
295 integrality vector integrality, lower/upper bounds on the constraints.
296 The sense of optimization of the objective function is assumed to be
297 a minimization.
298 Numbers larger than DBL_MAX (or larger than 1e+400)
299 might crash the code.
300 */
301 void setLpDataWithoutRowAndColNames(
302 const CoinPackedMatrix& m,
303 const double* collb, const double* colub,
304 const double* obj_coeff,
305 const char* integrality,
306 const double* rowlb, const double* rowub);
307
308 /** Return 0 if buff is a valid name for a row, a column or objective
309 function, return a positive number otherwise.
310 If parameter ranged = true, the name is intended for a ranged
311 constraint. <BR>
312 Return 1 if the name has more than 100 characters (96 characters
313 for a ranged constraint name, as "_low" will be added to the name).<BR>
314 Return 2 if the name starts with a number.<BR>
315 Return 3 if the name is not built with
316 the letters a to z, A to Z, the numbers 0 to 9 or the characters
317 " ! # $ % & ( ) . ; ? @ _ ' ` { } ~ <BR>
318 Return 4 if the name is a keyword.<BR>
319 Return 5 if the name is empty or NULL. */
320 int is_invalid_name(const char *buff, const bool ranged) const;
321
322 /** Return 0 if each of the card_vnames entries of vnames is a valid name,
323 return a positive number otherwise. The return value, if not 0, is the
324 return value of is_invalid_name() for the last invalid name
325 in vnames. If check_ranged = true, the names are row names and
326 names for ranged constaints must be checked for additional restrictions
327 since "_low" will be added to the name if an Lp file is written.
328 When check_ranged = true, card_vnames must have getNumRows()+1 entries,
329 with entry vnames[getNumRows()] being the
330 name of the objective function.
331 For a description of valid names and return values, see the method
332 is_invalid_name().
333
334 This method must not be called with check_ranged = true before
335 setLpDataWithoutRowAndColNames() has been called, since access
336 to the indices of all the ranged constraints is required.
337 */
338 int are_invalid_names(char const * const *vnames,
339 const int card_vnames,
340 const bool check_ranged) const;
341
342 /// Set objective function name to the default "obj" and row
343 /// names to the default "cons0", "cons1", ...
344 void setDefaultRowNames();
345
346 /// Set column names to the default "x0", "x1", ...
347 void setDefaultColNames();
348
349 /** Set the row and column names.
350 The array rownames must either be NULL or have exactly getNumRows()+1
351 distinct entries,
352 each of them being a valid name (see is_invalid_name()) and the
353 last entry being the intended name for the objective function.
354 If rownames is NULL, existing row names and objective function
355 name are not changed.
356 If rownames is deemed invalid, default row names and objective function
357 name are used (see setDefaultRowNames()). The memory location of
358 array rownames (or its entries) should not be related
359 to the memory location of the array (or entries) obtained from
360 getRowNames() or getPreviousRowNames(), as the call to
361 setLpDataRowAndColNames() modifies the corresponding arrays.
362 Unpredictable results
363 are obtained if this requirement is ignored.
364
365 Similar remarks apply to the array colnames, which must either be
366 NULL or have exactly getNumCols() entries.
367 */
368 void setLpDataRowAndColNames(char const * const * const rownames,
369 char const * const * const colnames);
370
371 /** Write the data in Lp format in the file with name filename.
372 Coefficients with value less than epsilon away from an integer value
373 are written as integers.
374 Write at most numberAcross monomials on a line.
375 Write non integer numbers with decimals digits after the decimal point.
376 Write objective function name and row names if useRowNames = true.
377
378 Ranged constraints are written as two constraints.
379 If row names are used, the upper bound constraint has the
380 name of the original ranged constraint and the
381 lower bound constraint has for name the original name with
382 "_low" as suffix. If doing so creates two identical row names,
383 default row names are used (see setDefaultRowNames()).
384 */
385 int writeLp(const char *filename,
386 const double epsilon,
387 const int numberAcross,
388 const int decimals,
389 const bool useRowNames = true);
390
391 /** Write the data in Lp format in the file pointed to by the paramater fp.
392 Coefficients with value less than epsilon away from an integer value
393 are written as integers.
394 Write at most numberAcross monomials on a line.
395 Write non integer numbers with decimals digits after the decimal point.
396 Write objective function name and row names if useRowNames = true.
397
398 Ranged constraints are written as two constraints.
399 If row names are used, the upper bound constraint has the
400 name of the original ranged constraint and the
401 lower bound constraint has for name the original name with
402 "_low" as suffix. If doing so creates two identical row names,
403 default row names are used (see setDefaultRowNames()).
404 */
405 int writeLp(FILE *fp,
406 const double epsilon,
407 const int numberAcross,
408 const int decimals,
409 const bool useRowNames = true);
410
411 /// Write the data in Lp format in the file with name filename.
412 /// Write objective function name and row names if useRowNames = true.
413 int writeLp(const char *filename, const bool useRowNames = true);
414
415 /// Write the data in Lp format in the file pointed to by the parameter fp.
416 /// Write objective function name and row names if useRowNames = true.
417 int writeLp(FILE *fp, const bool useRowNames = true);
418
419 /// Read the data in Lp format from the file with name filename, using
420 /// the given value for epsilon. If the original problem is
421 /// a maximization problem, the objective function is immediadtly
422 /// flipped to get a minimization problem.
423 void readLp(const char *filename, const double epsilon);
424
425 /// Read the data in Lp format from the file with name filename.
426 /// If the original problem is
427 /// a maximization problem, the objective function is immediadtly
428 /// flipped to get a minimization problem.
429 void readLp(const char *filename);
430
431 /// Read the data in Lp format from the file stream, using
432 /// the given value for epsilon.
433 /// If the original problem is
434 /// a maximization problem, the objective function is immediadtly
435 /// flipped to get a minimization problem.
436 void readLp(FILE *fp, const double epsilon);
437
438 /// Read the data in Lp format from the file stream.
439 /// If the original problem is
440 /// a maximization problem, the objective function is immediadtly
441 /// flipped to get a minimization problem.
442 void readLp(FILE *fp);
443
444 /// Dump the data. Low level method for debugging.
445 void print() const;
446 //@}
447/**@name Message handling */
448//@{
449 /** Pass in Message handler
450
451 Supply a custom message handler. It will not be destroyed when the
452 CoinMpsIO object is destroyed.
453 */
454 void passInMessageHandler(CoinMessageHandler * handler);
455
456 /// Set the language for messages.
457 void newLanguage(CoinMessages::Language language);
458
459 /// Set the language for messages.
460 inline void setLanguage(CoinMessages::Language language) {newLanguage(language);}
461
462 /// Return the message handler
463 inline CoinMessageHandler * messageHandler() const {return handler_;}
464
465 /// Return the messages
466 inline CoinMessages messages() {return messages_;}
467 /// Return the messages pointer
468 inline CoinMessages * messagesPointer() {return & messages_;}
469//@}
470
471protected:
472 /// Problem name
473 char * problemName_;
474
475 /// Message handler
476 CoinMessageHandler * handler_;
477 /** Flag to say if the message handler is the default handler.
478
479 If true, the handler will be destroyed when the CoinMpsIO
480 object is destroyed; if false, it will not be destroyed.
481 */
482 bool defaultHandler_;
483 /// Messages
484 CoinMessages messages_;
485
486 /// Number of rows
487 int numberRows_;
488
489 /// Number of columns
490 int numberColumns_;
491
492 /// Number of elements
493 int numberElements_;
494
495 /// Pointer to column-wise copy of problem matrix coefficients.
496 mutable CoinPackedMatrix *matrixByColumn_;
497
498 /// Pointer to row-wise copy of problem matrix coefficients.
499 CoinPackedMatrix *matrixByRow_;
500
501 /// Pointer to dense vector of row lower bounds
502 double * rowlower_;
503
504 /// Pointer to dense vector of row upper bounds
505 double * rowupper_;
506
507 /// Pointer to dense vector of column lower bounds
508 double * collower_;
509
510 /// Pointer to dense vector of column upper bounds
511 double * colupper_;
512
513 /// Pointer to dense vector of row rhs
514 mutable double * rhs_;
515
516 /** Pointer to dense vector of slack variable upper bounds for ranged
517 constraints (undefined for non-ranged constraints)
518 */
519 mutable double *rowrange_;
520
521 /// Pointer to dense vector of row senses
522 mutable char * rowsense_;
523
524 /// Pointer to dense vector of objective coefficients
525 double * objective_;
526
527 /// Constant offset for objective value
528 double objectiveOffset_;
529
530 /// Pointer to dense vector specifying if a variable is continuous
531 /// (0) or integer (1).
532 char * integerType_;
533
534 /// Current file name
535 char * fileName_;
536
537 /// Value to use for infinity
538 double infinity_;
539
540 /// Value to use for epsilon
541 double epsilon_;
542
543 /// Number of monomials printed in a row
544 int numberAcross_;
545
546 /// Number of decimals printed for coefficients
547 int decimals_;
548
549 /// Objective function name
550 char *objName_;
551
552 /** Row names (including objective function name)
553 and column names when stopHash() for the corresponding
554 section was last called or for initial names (deemed invalid)
555 read from a file.<BR>
556 section = 0 for row names,
557 section = 1 for column names. */
558 char **previous_names_[2];
559
560 /// card_previous_names_[section] holds the number of entries in the vector
561 /// previous_names_[section].
562 /// section = 0 for row names,
563 /// section = 1 for column names.
564 int card_previous_names_[2];
565
566 /// Row names (including objective function name)
567 /// and column names (linked to Hash tables).
568 /// section = 0 for row names,
569 /// section = 1 for column names.
570 char **names_[2];
571
572 typedef struct {
573 int index, next;
574 } CoinHashLink;
575
576 /// Maximum number of entries in a hash table section.
577 /// section = 0 for row names,
578 /// section = 1 for column names.
579 int maxHash_[2];
580
581 /// Number of entries in a hash table section.
582 /// section = 0 for row names,
583 /// section = 1 for column names.
584 int numberHash_[2];
585
586 /// Hash tables with two sections.
587 /// section = 0 for row names (including objective function name),
588 /// section = 1 for column names.
589 mutable CoinHashLink *hash_[2];
590
591 /// Build the hash table for the given names. The parameter number is
592 /// the cardinality of parameter names. Remove duplicate names.
593 ///
594 /// section = 0 for row names,
595 /// section = 1 for column names.
596 void startHash(char const * const * const names,
597 const COINColumnIndex number,
598 int section);
599
600 /// Delete hash storage. If section = 0, it also frees objName_.
601 /// section = 0 for row names,
602 /// section = 1 for column names.
603 void stopHash(int section);
604
605 /// Return the index of the given name, return -1 if the name is not found.
606 /// Return getNumRows() for the objective function name.
607 /// section = 0 for row names (including objective function name),
608 /// section = 1 for column names.
609 COINColumnIndex findHash(const char *name, int section) const;
610
611 /// Insert thisName in the hash table if not present yet; does nothing
612 /// if the name is already in.
613 /// section = 0 for row names,
614 /// section = 1 for column names.
615 void insertHash(const char *thisName, int section);
616
617 /// Write a coefficient.
618 /// print_1 = 0 : do not print the value 1.
619 void out_coeff(FILE *fp, double v, int print_1) const;
620
621 /// Locate the objective function.
622 /// Return 1 if found the keyword "Minimize" or one of its variants,
623 /// -1 if found keyword "Maximize" or one of its variants.
624 int find_obj(FILE *fp) const;
625
626 /// Return an integer indicating if the keyword "subject to" or one
627 /// of its variants has been read.
628 /// Return 1 if buff is the keyword "s.t" or one of its variants.
629 /// Return 2 if buff is the keyword "subject" or one of its variants.
630 /// Return 0 otherwise.
631 int is_subject_to(const char *buff) const;
632
633 /// Return 1 if the first character of buff is a number.
634 /// Return 0 otherwise.
635 int first_is_number(const char *buff) const;
636
637 /// Return 1 if the first character of buff is '/' or '\'.
638 /// Return 0 otherwise.
639 int is_comment(const char *buff) const;
640
641 /// Read the file fp until buff contains an end of line
642 void skip_comment(char *buff, FILE *fp) const;
643
644 /// Put in buff the next string that is not part of a comment
645 void scan_next(char *buff, FILE *fp) const;
646
647 /// Return 1 if buff is the keyword "free" or one of its variants.
648 /// Return 0 otherwise.
649 int is_free(const char *buff) const;
650
651 /// Return 1 if buff is the keyword "inf" or one of its variants.
652 /// Return 0 otherwise.
653 int is_inf(const char *buff) const;
654
655 /// Return an integer indicating the inequality sense read.
656 /// Return 0 if buff is '<='.
657 /// Return 1 if buff is '='.
658 /// Return 2 if buff is '>='.
659 /// Return -1 otherwise.
660 int is_sense(const char *buff) const;
661
662 /// Return an integer indicating if one of the keywords "Bounds", "Integers",
663 /// "Generals", "Binaries", "End", or one
664 /// of their variants has been read.
665 /// Return 1 if buff is the keyword "Bounds" or one of its variants.
666 /// Return 2 if buff is the keyword "Integers" or "Generals" or one of their
667 /// variants.
668 /// Return 3 if buff is the keyword "Binaries" or one of its variants.
669 /// Return 4 if buff is the keyword "End" or one of its variants.
670 /// Return 0 otherwise.
671 int is_keyword(const char *buff) const;
672
673 /// Read a monomial of the objective function.
674 /// Return 1 if "subject to" or one of its variants has been read.
675 int read_monom_obj(FILE *fp, double *coeff, char **name, int *cnt,
676 char **obj_name);
677
678 /// Read a monomial of a constraint.
679 /// Return a positive number if the sense of the inequality has been
680 /// read (see method is_sense() for the return code).
681 /// Return -1 otherwise.
682 int read_monom_row(FILE *fp, char *start_str, double *coeff, char **name,
683 int cnt_coeff) const;
684
685 /// Reallocate vectors related to number of coefficients.
686 void realloc_coeff(double **coeff, char ***colNames, int *maxcoeff) const;
687
688 /// Reallocate vectors related to rows.
689 void realloc_row(char ***rowNames, int **start, double **rhs,
690 double **rowlow, double **rowup, int *maxrow) const;
691
692 /// Reallocate vectors related to columns.
693 void realloc_col(double **collow, double **colup, char **is_int,
694 int *maxcol) const;
695
696 /// Read a constraint.
697 void read_row(FILE *fp, char *buff, double **pcoeff, char ***pcolNames,
698 int *cnt_coeff, int *maxcoeff,
699 double *rhs, double *rowlow, double *rowup,
700 int *cnt_row, double inf) const;
701
702 /** Check that current objective name and all row names are distinct
703 including row names obtained by adding "_low" for ranged constraints.
704 If there is a conflict in the names, they are replaced by default
705 row names (see setDefaultRowNames()).
706
707 This method must not be called before
708 setLpDataWithoutRowAndColNames() has been called, since access
709 to the indices of all the ranged constraints is required.
710
711 This method must not be called before
712 setLpDataRowAndColNames() has been called, since access
713 to all the row names is required.
714 */
715 void checkRowNames();
716
717 /** Check that current column names are distinct.
718 If not, they are replaced by default
719 column names (see setDefaultColNames()).
720
721 This method must not be called before
722 setLpDataRowAndColNames() has been called, since access
723 to all the column names is required.
724 */
725 void checkColNames();
726
727};
728