4 * Copyright: (c) Universitaet Karlsruhe
5 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
13 * These must comply to the enum cst_t in lpp.h
15 static const char *mps_cst_encoding[4] = {"N", "E", "L", "G"};
18 * Diffferent line styles which can be used in a mps file
21 l_raw, l_ind_name, l_ind_objs, l_ind_rows, l_ind_cols, l_ind_rhs, l_ind_end,
22 l_data_row, l_data_col1, l_data_col2, l_data_mst, l_marker
25 static void mps_write_line(FILE *out, lpp_mps_style_t style,
26 mps_line_t line_type, ...)
31 assert(style == s_mps_fixed || style == s_mps_free);
32 va_start(args, line_type);
34 if (style == s_mps_fixed) {
35 /* white spaces are important! */
37 case l_raw: fmt = "%s\n"; break;
38 case l_ind_name: fmt = "NAME %s\n"; break;
39 case l_ind_objs: fmt = "OBJSENSE\n"; break;
40 case l_ind_rows: fmt = "ROWS\n"; break;
41 case l_ind_cols: fmt = "COLUMNS\n"; break;
42 case l_ind_rhs: fmt = "RHS\n"; break;
43 case l_ind_end: fmt = "ENDATA\n"; break;
44 case l_data_row: fmt = " %-2s %-8s\n"; break; /* Field 1-2 */
45 case l_data_col1: fmt = " %-8s %-8s %12g\n"; break; /* Field 2-4 */
46 case l_data_col2: fmt = " %-8s %-8s %12g %-8s %12g\n"; break; /* Field 2-6 */
47 case l_data_mst: fmt = " %-8s %12g\n"; break; /* Field 3-4 */
48 case l_marker: fmt = " M%-7d 'MARKER' '%s'\n"; break; /* Field 2,3,5 */
53 case l_raw: fmt = "%s\n"; break;
54 case l_ind_name: fmt = "NAME %s\n"; break;
55 case l_ind_objs: fmt = "OBJSENSE\n"; break;
56 case l_ind_rows: fmt = "ROWS\n"; break;
57 case l_ind_cols: fmt = "COLUMNS\n"; break;
58 case l_ind_rhs: fmt = "RHS\n"; break;
59 case l_ind_end: fmt = "ENDATA\n"; break;
60 case l_data_row: fmt = " %s\t%s\n"; break;
61 case l_data_col1: fmt = " %s\t%s\t%g\n"; break;
62 case l_data_col2: fmt = " %s\t%s\t%g\t%s\t%g\n"; break;
63 case l_data_mst: fmt = " %s\t%g\n"; break;
64 case l_marker: fmt = " M%d\t'MARKER'\t'%s'\n"; break;
69 vfprintf(out, fmt, args);
73 static int mps_insert_markers(FILE *out, lpp_mps_style_t style, lpp_var_t curr,
74 lpp_var_t last, int marker_nr)
76 assert(style == s_mps_fixed || style == s_mps_free);
78 /* print end-marker for last */
79 if (last == lpp_binary)
80 mps_write_line(out, style, l_marker, marker_nr++, "INTEND");
82 /* print begin-marker for curr */
83 if (curr == lpp_binary)
84 mps_write_line(out, style, l_marker, marker_nr++, "INTORG");
89 void mps_write_mps(lpp_t *lpp, lpp_mps_style_t style, FILE *out)
91 int i, count, marker_nr = 0;
92 const lpp_name_t *curr;
93 const matrix_elem_t *before = NULL;
95 assert(style == s_mps_fixed || style == s_mps_free);
98 mps_write_line(out, style, l_ind_name, lpp->name);
101 if (lpp->opt_type == lpp_maximize) {
102 mps_write_line(out, style, l_ind_objs);
103 mps_write_line(out, style, l_raw, " MAX");
107 mps_write_line(out, style, l_ind_rows);
108 for(i=0; i<lpp->cst_next; ++i) {
110 mps_write_line(out, style, l_data_row, mps_cst_encoding[curr->type.cst_type], curr->name);
114 mps_write_line(out, style, l_ind_cols);
115 last_type = lpp_invalid;
116 for(i=1; i<lpp->var_next; ++i) { /* column 0 is rhs */
120 marker_nr = mps_insert_markers(out, style, curr->type.var_type, last_type, marker_nr);
121 last_type = curr->type.var_type;
123 /* participation in constraints */
125 matrix_foreach_in_col(lpp->m, curr->nr, elem) {
130 mps_write_line(out, style, l_data_col2, curr->name, lpp->csts[before->row]->name, (double)before->val, lpp->csts[elem->row]->name, (double)elem->val);
135 mps_write_line(out, style, l_data_col1, curr->name, lpp->csts[before->row]->name, (double)before->val);
137 mps_insert_markers(out, style, lpp_invalid, last_type, marker_nr); /* potential end-marker */
140 mps_write_line(out, style, l_ind_rhs);
142 matrix_foreach_in_col(lpp->m, 0, elem) {
147 mps_write_line(out, style, l_data_col2, "rhs", lpp->csts[before->row]->name, (double)before->val, lpp->csts[elem->row]->name, (double)elem->val);
152 mps_write_line(out, style, l_data_col1, "rhs", lpp->csts[before->row]->name, (double)before->val);
155 mps_write_line(out, style, l_ind_end);
158 void mps_write_mst(lpp_t *lpp, lpp_mps_style_t style, FILE *out)
161 mps_write_line(out, style, l_ind_name, "");
162 for (i=0; i<lpp->var_next; ++i) {
163 const lpp_name_t *var = lpp->vars[i];
164 if (var->value_kind == lpp_value_start)
165 mps_write_line(out, style, l_data_mst, var->name, (double)var->value);
167 mps_write_line(out, style, l_ind_end);