source: trunk/Test/Cbc_ampl.cpp @ 295

Last change on this file since 295 was 295, checked in by forrest, 16 years ago

for ampl

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.4 KB
Line 
1/****************************************************************
2Copyright (C) 1997-2000 Lucent Technologies
3Modifications for Coin -  Copyright (C) 2006, International Business Machines Corporation and others.
4All Rights Reserved
5
6Permission to use, copy, modify, and distribute this software and
7its documentation for any purpose and without fee is hereby
8granted, provided that the above copyright notice appear in all
9copies and that both that the copyright notice and this
10permission notice and warranty disclaimer appear in supporting
11documentation, and that the name of Lucent or any of its entities
12not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior
14permission.
15
16LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
18IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
19SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
21IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
23THIS SOFTWARE.
24****************************************************************/
25#ifdef CBC_AMPL
26#include "getstub.h"
27#include "Cbc_ampl.h"
28#include "unistd.h"
29#include <string>
30/* so decodePhrase and clpCheck can access */
31static ampl_info * saveInfo=NULL;
32// Set to 1 if algorithm found
33static char algFound[20]="";
34static char*
35checkPhrase(Option_Info *oi, keyword *kw, char *v)
36{
37  if (strlen(v))
38    printf("string %s\n",v);
39  // Say algorithm found
40  strcpy(algFound,kw->desc);;
41  return v;
42}
43static char*
44checkPhrase2(Option_Info *oi, keyword *kw, char *v)
45{
46  if (strlen(v))
47    printf("string %s\n",v);
48  // put out keyword
49  saveInfo->arguments=(char **) realloc(saveInfo->arguments,(saveInfo->numberArguments+1)*sizeof(char *));
50  saveInfo->arguments[saveInfo->numberArguments++]=strdup(kw->desc);
51  return v;
52}
53static fint
54decodePhrase(char * phrase,ftnlen length)
55{
56  char * blank = strchr(phrase,' ');
57  if (blank) {
58    /* split arguments */
59    *blank='\0';
60    saveInfo->arguments=(char **) realloc(saveInfo->arguments,(saveInfo->numberArguments+2)*sizeof(char *));
61    saveInfo->arguments[saveInfo->numberArguments++]=strdup(phrase);
62    *blank=' ';
63    phrase=blank+1; /* move on */
64    saveInfo->arguments[saveInfo->numberArguments++]=strdup(phrase);
65  } else {
66    saveInfo->arguments=(char **) realloc(saveInfo->arguments,(saveInfo->numberArguments+1)*sizeof(char *));
67    saveInfo->arguments[saveInfo->numberArguments++]=strdup(phrase);
68  }
69  return 0;
70}
71static char xxxxxx[20];
72#define VP (char*)
73 static keyword keywds[] = { /* must be sorted */
74        { "barrier",    checkPhrase,            (char *) xxxxxx ,"-barrier" },
75        { "dual",       checkPhrase,            (char *) xxxxxx , "-dualsimplex"},
76        { "help",       checkPhrase2,           (char *) xxxxxx , "-?"},
77        { "initial",    checkPhrase,            (char *) xxxxxx , "-initialsolve"},
78        { "max",        checkPhrase2,           (char *) xxxxxx , "-maximize"},
79        { "maximize",   checkPhrase2,           (char *) xxxxxx , "-maximize"},
80        { "primal",     checkPhrase,            (char *) xxxxxx , "-primalsimplex"},
81        { "quit",       checkPhrase2,           (char *) xxxxxx , "-quit"},
82        { "wantsol",    WS_val,         NULL, "write .sol file (without -AMPL)" }
83        };
84static Option_Info Oinfo = {"cbc", "Cbc 1.01", "cbc_options", keywds, nkeywds, 0, "",
85                                0,decodePhrase,0,0,0, 20060130 };
86// strdup used to avoid g++ compiler warning
87 static SufDecl
88suftab[] = {
89#if 0
90        { "current", 0, ASL_Sufkind_con | ASL_Sufkind_outonly },
91        { "current", 0, ASL_Sufkind_var | ASL_Sufkind_outonly },
92        { "direction", 0, ASL_Sufkind_var },
93        { "down", 0, ASL_Sufkind_con | ASL_Sufkind_outonly },
94        { "down", 0, ASL_Sufkind_var | ASL_Sufkind_outonly },
95        { "priority", 0, ASL_Sufkind_var },
96        { "ref", 0, ASL_Sufkind_var | ASL_Sufkind_real },
97        { "sos", 0, ASL_Sufkind_var },
98        { "sos", 0, ASL_Sufkind_con },
99        { "sosno", 0, ASL_Sufkind_var | ASL_Sufkind_real },
100        { "sosref", 0, ASL_Sufkind_var | ASL_Sufkind_real },
101#endif
102        { "direction", 0, ASL_Sufkind_var },
103        { "downPseudocost", 0, ASL_Sufkind_var | ASL_Sufkind_real },
104        { "priority", 0, ASL_Sufkind_var },
105        { strdup("sstatus"), 0, ASL_Sufkind_var, 0 },
106        { strdup("sstatus"), 0, ASL_Sufkind_con, 0 },
107        { "upPseudocost", 0, ASL_Sufkind_var | ASL_Sufkind_real }
108#if 0
109        { "unbdd", 0, ASL_Sufkind_var | ASL_Sufkind_outonly},
110        { "up", 0, ASL_Sufkind_con | ASL_Sufkind_outonly },
111        { "up", 0, ASL_Sufkind_var | ASL_Sufkind_outonly }
112#endif
113        };
114#include "float.h"
115#include "limits.h"
116static ASL *asl=NULL;
117static FILE *nl=NULL;
118
119static void
120mip_stuff(void)
121{
122  int i;
123  double *pseudoUp, *pseudoDown;
124  int *priority, *direction;
125  SufDesc *dpup, *dpdown, *dpri, *ddir;
126 
127  ddir = suf_get("direction", ASL_Sufkind_var);
128  direction = ddir->u.i;
129  dpri = suf_get("priority", ASL_Sufkind_var);
130  priority = dpri->u.i;
131  dpdown = suf_get("downPseudocost", ASL_Sufkind_var);
132  pseudoDown = dpdown->u.r;
133  dpup = suf_get("upPseudocost", ASL_Sufkind_var);
134  pseudoUp = dpup->u.r;
135  assert(saveInfo);
136  int numberColumns = saveInfo->numberColumns;
137  if (direction) {
138    int baddir=0;
139    saveInfo->branchDirection = (int *) malloc(numberColumns*sizeof(int));
140    for (i=0;i<numberColumns;i++) {
141      int value = direction[i];
142      if (value<-1||value>1) {
143        baddir++;
144        value=0;
145      }
146      saveInfo->branchDirection[i]=value;
147    }
148    if (baddir)
149      fprintf(Stderr,
150              "Treating %d .direction values outside [-1, 1] as 0.\n",
151              baddir);
152  }
153  if (priority) {
154    int badpri=0;
155    saveInfo->priorities= (int *) malloc(numberColumns*sizeof(int));
156    for (i=0;i<numberColumns;i++) {
157      int value = priority[i];
158      if (value<0) {
159        badpri++;
160        value=0;
161      }
162      saveInfo->priorities[i]=value;
163    }
164    if (badpri)
165      fprintf(Stderr,
166              "Treating %d negative .priority values as 0\n",
167              badpri);
168  }
169  if (pseudoDown||pseudoUp) {
170    int badpseudo=0;
171    if (!pseudoDown||!pseudoUp)
172      fprintf(Stderr,
173              "Only one set of pseudocosts - assumed same\n");
174    saveInfo->pseudoDown= (double *) malloc(numberColumns*sizeof(double));
175    saveInfo->pseudoUp = (double *) malloc(numberColumns*sizeof(double));
176    for (i=0;i<numberColumns;i++) {
177      double valueD=0.0, valueU=0.0;
178      if (pseudoDown) {
179        valueD = pseudoDown[i];
180        if (valueD<0) {
181          badpseudo++;
182          valueD=0.0;
183        }
184      }
185      if (pseudoUp) {
186        valueU = pseudoUp[i];
187        if (valueU<0) {
188          badpseudo++;
189          valueU=0.0;
190        }
191      }
192      if (!valueD)
193        valueD=valueU;
194      if (!valueU)
195        valueU=valueD;
196      saveInfo->pseudoDown[i]=valueD;
197      saveInfo->pseudoUp[i]=valueU;
198    }
199    if (badpseudo)
200      fprintf(Stderr,
201              "Treating %d negative pseudoCosts as 0.0\n",badpseudo);
202  }
203}
204static void
205stat_map(int *stat, int n, int *map, int mx, const char *what)
206{
207  int bad, i, i1=0, j, j1=0;
208  static char badfmt[] = "Coin driver: %s[%d] = %d\n";
209 
210  for(i = bad = 0; i < n; i++) {
211    if ((j = stat[i]) >= 0 && j <= mx)
212      stat[i] = map[j];
213    else {
214      stat[i] = 0;
215      i1 = i;
216      j1 = j;
217      if (!bad++)
218        fprintf(Stderr, badfmt, what, i, j);
219    }
220  }
221  if (bad > 1) {
222    if (bad == 2)
223      fprintf(Stderr, badfmt, what, i1, j1);
224    else
225      fprintf(Stderr,
226              "Coin driver: %d messages about bad %s values suppressed.\n",
227              bad-1, what);
228  }
229}
230int
231readAmpl(ampl_info * info, int argc, char **argv)
232{
233  char *stub;
234  ograd *og;
235  int i;
236  SufDesc *csd;
237  SufDesc *rsd;
238  /*bool *basis, *lower;*/
239  /*double *LU, *c, lb, objadj, *rshift, *shift, t, ub, *x, *x0, *x1;*/
240  char * environment = getenv("cbc_options");
241  char tempBuffer[20];
242  double * obj;
243  double * columnLower;
244  double * columnUpper;
245  double * rowLower;
246  double * rowUpper;
247  char ** saveArgv=argv;
248  int saveArgc = argc;
249  memset(info,0,sizeof(ampl_info));
250  /* save so can be accessed by decodePhrase */
251  saveInfo = info;
252  info->numberArguments=0;
253  info->arguments=(char **) malloc(2*sizeof(char *));
254  info->arguments[info->numberArguments++]=strdup("ampl");
255  info->arguments[info->numberArguments++]=strdup("cbc");
256  asl = ASL_alloc(ASL_read_f);
257  stub = getstub(&argv, &Oinfo);
258  if (!stub)
259    usage_ASL(&Oinfo, 1);
260  nl = jac0dim(stub, 0);
261  /*void * specialOrderedInfo = sos_add(nl,0);*/
262  suf_declare(suftab, sizeof(suftab)/sizeof(SufDecl));
263 
264  /* set A_vals to get the constraints column-wise (malloc so can be freed) */
265  A_vals = (double *) malloc(nzc*sizeof(double));
266  if (!A_vals) {
267    printf("no memory\n");
268    return 1;
269  }
270  /* say we want primal solution */
271  want_xpi0=1;
272  /* for basis info */
273  info->columnStatus = (int *) malloc(n_var*sizeof(int));
274  info->rowStatus = (int *) malloc(n_con*sizeof(int));
275  csd = suf_iput("sstatus", ASL_Sufkind_var, info->columnStatus);
276  rsd = suf_iput("sstatus", ASL_Sufkind_con, info->rowStatus);
277  /* read linear model*/
278  f_read(nl,0);
279
280  /*sos_finish(&specialOrderedInfo, 0, &j, 0, 0, 0, 0, 0);*/
281  Oinfo.uinfo = tempBuffer;
282  if (getopts(argv, &Oinfo))
283    return 1;
284  /* objective*/
285  obj = (double *) malloc(n_var*sizeof(double));
286  for (i=0;i<n_var;i++)
287    obj[i]=0.0;;
288  if (n_obj) {
289    for (og = Ograd[0];og;og = og->next)
290      obj[og->varno] = og->coef;
291  }
292  if (objtype[0])
293    info->direction=-1.0;
294  else
295    info->direction=1.0;
296  info->offset=objconst(0);
297  /* Column bounds*/
298  columnLower = (double *) malloc(n_var*sizeof(double));
299  columnUpper = (double *) malloc(n_var*sizeof(double));
300#define COIN_DBL_MAX DBL_MAX
301  for (i=0;i<n_var;i++) {
302    columnLower[i]=LUv[2*i];
303    if (columnLower[i]<= negInfinity)
304      columnLower[i]=-COIN_DBL_MAX;
305    columnUpper[i]=LUv[2*i+1];
306    if (columnUpper[i]>= Infinity)
307      columnUpper[i]=COIN_DBL_MAX;
308  }
309  /* Row bounds*/
310  rowLower = (double *) malloc(n_con*sizeof(double));
311  rowUpper = (double *) malloc(n_con*sizeof(double));
312  for (i=0;i<n_con;i++) {
313    rowLower[i]=LUrhs[2*i];
314    if (rowLower[i]<= negInfinity)
315      rowLower[i]=-COIN_DBL_MAX;
316    rowUpper[i]=LUrhs[2*i+1];
317    if (rowUpper[i]>= Infinity)
318      rowUpper[i]=COIN_DBL_MAX;
319  }
320  info->numberRows=n_con;
321  info->numberColumns=n_var;
322  info->numberElements=nzc;;
323  info->numberBinary=nbv;
324  info->numberIntegers=niv;
325  info->objective=obj;
326  info->rowLower=rowLower;
327  info->rowUpper=rowUpper;
328  info->columnLower=columnLower;
329  info->columnUpper=columnUpper;
330  info->starts=A_colstarts;
331  /*A_colstarts=NULL;*/
332  info->rows=A_rownos;
333  /*A_rownos=NULL;*/
334  info->elements=A_vals;
335  /*A_vals=NULL;*/
336  info->primalSolution=NULL;
337  /* put in primalSolution if exists */
338  if (X0) {
339    info->primalSolution=(double *) malloc(n_var*sizeof(double));
340    memcpy(info->primalSolution,X0,n_var*sizeof(double));
341  }
342  info->dualSolution=NULL;
343  if (niv+nbv>0)
344    mip_stuff(); // get any extra info
345  if ((!(niv+nbv)&&(csd->kind & ASL_Sufkind_input))
346      ||(rsd->kind & ASL_Sufkind_input)) {
347    /* convert status - need info on map */
348    static int map[] = {1, 3, 1, 1, 2, 1, 1};
349    stat_map(info->columnStatus, n_var, map, 6, "incoming columnStatus");
350    stat_map(info->rowStatus, n_con, map, 6, "incoming rowStatus");
351  } else {
352    /* all slack basis */
353    free(info->rowStatus);
354    info->rowStatus=NULL;
355    free(info->columnStatus);
356    info->columnStatus=NULL;
357  }
358  /* add -solve - unless something there already
359   - also check for sleep=yes */
360  {
361    int found=0;
362    int foundLog=0;
363    int foundSleep=0;
364    const char * something[]={"solve","branch","duals","primals"};
365    for (i=0;i<info->numberArguments;i++) {
366      unsigned int j;
367      const char * argument = info->arguments[i];
368      for (j=0;j<sizeof(something)/sizeof(char *);j++) {
369        const char * check = something[j];
370        if (!strncmp(argument,check,sizeof(check))) {
371          found=(int)(j+1);
372        } else if (!strncmp(argument,"log",3)) {
373          foundLog=1;
374        } else if (!strncmp(argument,"sleep",5)) {
375          foundSleep=1;
376        }
377      }
378    }
379    if (foundLog) {
380      /* print options etc */
381      for (i=0;i<saveArgc;i++)
382        printf("%s ",saveArgv[i]);
383      printf("\n");
384      if (environment)
385        printf("env %s\n",environment);
386      /*printf("%d rows %d columns %d elements\n",n_con,n_var,nzc);*/
387    }
388    if (!found) {
389      if (!strlen(algFound)) {
390        info->arguments=(char **) realloc(info->arguments,(info->numberArguments+1)*sizeof(char *));
391        info->arguments[info->numberArguments++]=strdup("-solve");
392      } else {
393        // use algorithm from keyword
394        info->arguments=(char **) realloc(info->arguments,(info->numberArguments+1)*sizeof(char *));
395        info->arguments[info->numberArguments++]=strdup(algFound);
396      }
397    }
398    if (foundSleep) {
399      /* let user copy .nl file */
400      fprintf(stderr,"You can copy .nl file %s for debug purposes or attach debugger\n",saveArgv[1]);
401      fprintf(stderr,"Type q to quit, anything else to continue\n");
402      char getChar = getc(stdin);
403      if (getChar=='q'||getChar=='Q')
404        exit(1);
405    }
406  }
407  /* add -quit */
408  info->arguments=(char **) realloc(info->arguments,(info->numberArguments+1)*sizeof(char *));
409  info->arguments[info->numberArguments++]=strdup("-quit");
410  return 0;
411}
412void freeArrays1(ampl_info * info)
413{
414  free(info->objective);
415  info->objective=NULL;
416  free(info->rowLower);
417  info->rowLower=NULL;
418  free(info->rowUpper);
419  info->rowUpper=NULL;
420  free(info->columnLower);
421  info->columnLower=NULL;
422  free(info->columnUpper);
423  info->columnUpper=NULL;
424  /* this one not freed by ASL_free */
425  free(info->elements);
426  info->elements=NULL;
427  free(info->primalSolution);
428  info->primalSolution=NULL;
429  free(info->dualSolution);
430  info->dualSolution=NULL;
431  /*free(info->rowStatus);
432  info->rowStatus=NULL;
433  free(info->columnStatus);
434  info->columnStatus=NULL;*/
435}
436void freeArrays2(ampl_info * info)
437{
438  free(info->primalSolution);
439  info->primalSolution=NULL;
440  free(info->dualSolution);
441  info->dualSolution=NULL;
442  free(info->rowStatus);
443  info->rowStatus=NULL;
444  free(info->columnStatus);
445  info->columnStatus=NULL;
446  free(info->priorities);
447  info->priorities=NULL;
448  free(info->branchDirection);
449  info->branchDirection=NULL;
450  free(info->pseudoDown);
451  info->pseudoDown=NULL;
452  free(info->pseudoUp);
453  info->pseudoUp=NULL;
454  ASL_free(&asl);
455}
456void freeArgs(ampl_info * info)
457{
458  int i;
459  for ( i=0; i<info->numberArguments;i++)
460    free(info->arguments[i]);
461  free(info->arguments);
462}
463int ampl_obj_prec()
464{
465  return obj_prec();
466}
467void writeAmpl(ampl_info * info)
468{
469  char buf[1000];
470  typedef struct { const char *msg; int code; int wantObj; } Sol_info;
471  static Sol_info solinfo[] = {
472    { "optimal solution",                       000, 1 },
473    { "infeasible",                             200, 1 },
474    { "unbounded",                              300, 0 },
475    { "iteration limit etc",                    400, 1 },
476    { "solution limit",                         401, 1 },
477    { "ran out of space",                       500, 0 },
478    { "status unknown",                         501, 1 },
479    { "bug!",                                   502, 0 },
480    { "best MIP solution so far restored",      101, 1 },
481    { "failed to restore best MIP solution",    503, 1 },
482    { "optimal (?) solution",                   100, 1 }
483  };
484  /* convert status - need info on map */
485  static int map[] = {0, 3, 4, 1};
486  sprintf(buf,"%s %s",Oinfo.bsname,info->buffer);
487  solve_result_num = solinfo[info->problemStatus].code;
488  if (info->columnStatus) {
489    stat_map(info->columnStatus, n_var, map, 4, "outgoing columnStatus");
490    stat_map(info->rowStatus, n_con, map, 4, "outgoing rowStatus");
491    suf_iput("sstatus", ASL_Sufkind_var, info->columnStatus);
492    suf_iput("sstatus", ASL_Sufkind_con, info->rowStatus);
493  }
494  write_sol(buf,info->primalSolution,info->dualSolution,&Oinfo);
495}
496
497#endif
Note: See TracBrowser for help on using the repository browser.