CONOPT
Loading...
Searching...
No Matches
mp_qpbandb.c
Go to the documentation of this file.
1
9
10#include <stdlib.h>
11#include <stdio.h>
12#include <math.h>
13#include <string.h>
14#include <omp.h>
15#include "coiheader.h"
16#include "comdecl.h"
17
18#ifdef _MSC_VER
19#pragma warning (disable : 3280)
20#endif
21
22/* QP Model: Min (x-target)*Q*(x-target)/2
23 s.t.
24 sum( x ) = 1;
25 x(i) =l= bin(i);
26 sum( bin ) <= maxbin
27 where x is a vector of non-negative variables of length NN
28 bin is a vector of binary variables of length NN
29 target is a vector of +10, and
30 Q is a matrix with +1 on the diagonal and 0.1 on the
31 first upper and lower bi-diagonal
32 maxbin is a constant upper bound on the number of x-components
33 that can be nonzero */
34
35/* Define Size of the QP model */
36#define NN 32
37#define NVAR (NN*2) /* Number of All variables, continuous and binary */
38#define NBIN NN /* Number of binary variables */
39#define MAXBIN 15 /* Max number of nonzero X-variables */
40#define NOBS 60 /* Number of observations used to estimate Q */
41#define NQ (NN*(NN+1)/2) /* Number of nonzeros in triangle of Q */
42double Q[NQ];
43double Mean[NN];
44double Target;
46int seed = 12359;
47
48coiHandle_t *CntVect1; /* Pointers to CONOPT control vectors, one for each thread.
49 Is global so it can be used in the
50 Solve_Workpool routine */
51
52void c_log( char *msgt, int code )
53/* This routine has some of the same functionality as the c_log routine in std.c
54 but it does not call coiCreate and CoiFree. This is done in the main program. */
55{
56 FILE *fc;
57 int i;
58 int c;
59
60 if ( code == START )
61 {
62 i = 0; /* Read the name of the program without extension from stdin */
63 while ( (c = getchar()) != EOF && i < MAXLINE ) pname[i++] = (char)c;
64 pname[i-1] = '\0'; /* remove eof and new-line chars */
65 strcpy(fname,pname); strcat(fname,".lst" );
66 fd = fopen(fname,"w");
67 strcpy(fname,pname); strcat(fname,".sta" );
68 fs = fopen(fname,"w");
69 };
70 strcpy(fname,pname); strcat(fname,".rc" );
71 fc = fopen(fname,"w");
72 fprintf(fc,"%s: %s.\n", pname, msgt );
73 fclose(fc);
74 if ( code != START )
75 {
76 fclose(fd);
77 fclose(fs);
78 if ( code == OK )
79 exit(0);
80 else
81 exit(code);
82 }
83}
84
85/* The following global data are general data structures used to manage
86 a Branch and Bound process */
87
88struct BBNode {
89 double *values;/* Solution value or initial values */
90 int *fixed; /* Binary: 0=fixed zero, 1=fixed 1, -1 not fixed. */
91 struct BBNode *prvnode; /* Pointer forward and backward in */
92 struct BBNode *nxtnode; /* double-linked list of active nodes. */
93 double object; /* Objective value (if solved) or lower bound if
94 not yet solved */
95 int node_stat; /* Node Status:
96 0 - created but not solved
97 1 - solved */
98 int solstat; /* Solution status. Initialized to -1 and
99 redefined when the model has been solved */
100 int modstat; /* Model status. Initialized to -1 and
101 redefined when the model has been solved */
102 int number; /* Sequense number of the node. */
103 int depth; /* Depth of the node in the B&B tree */
104 int isinteger; /* Is true iff the solution is integer */
105}; /* end struct BBNode */
106
107double bintol = 1.0e-7;
108int totnodes; /* Total number of nodes in use */
109int freenodes; /* Number of active nodes */
110int actnodes; /* Number of free nodes in a free list */
111int numsolve; /* Counter for finished Solves. */
112/*
113 Data for best solution
114*/
115int intfound; /* Global flag indicating whether we already have an
116 integer feasible solution. */
117int numintfound; /* Number of integer solutions found */
118double bestint; /* Objective value for the best integer solution
119 found so far. */
120double solution[NVAR]; /* The solution corresponding to BestInt */
121/*
122 Data for managing the Branch and Bound Tree
123*/
124struct BBNode *actnode; /* Pointer to first node in a list of active
125 untested noded */
126struct BBNode *freenode; /* Pointer to first node in a freelist */
127/*
128 Data for managing a WorkPool with the nodes selected for the next
129 set of parallel Solves
130*/
131#define maxmaxpool 64 /* Allocation size for WorkPool */
132int maxpool; /* Largest size of WorkPool selected by user */
133int workpool; /* Size of the actual workpool */
134struct BBNode *work_node[maxmaxpool]; /* Pointers to vector of selected nodes
135 in the WorkPool */
136int parallel; /* If set then run the COI_Solve loop over
137 the nodes in the WorkPool in parallel */
138double stime; /* Accumulated time in Solve Loop */
139
140/* --------------START OF GENERAL BRANCH AND BOUND ROUTINES */
141/* The following routines are general Branch and Bound routines
142 based on the global data above */
143
144void list_node( struct BBNode *node)
145{
146
147 if ( node )
148 printf("list_node: number= %d node_stat= %d.\n", node->number,node->node_stat);
149 else
150 printf("list_node: node is NULL.\n");
151}
152
154{
155 struct BBNode *node;
156 int n = 0;
157
158 node = actnode;
159 while ( node )
160 {
161 printf("list_nodes: node number= %d node_stat= %d object= %f\n", node->number, node->node_stat, node->object);
162 node = node->nxtnode;
163 n++;
164 }
165 printf("list_nodes: Total= %d.\n", n);
166}
167
168void remove_activenode(struct BBNode *node)
169{
170/* Remove a node from the list of active nodes. */
171
172 if ( node->prvnode )
173 node->prvnode->nxtnode = node->nxtnode;
174 else
175 actnode = node->nxtnode;
176 if ( node->nxtnode)
177 node->nxtnode->prvnode = node->prvnode;
178 actnodes--;
179}
180
181void return_freenode(struct BBNode *node)
182{
183/* Link the node into the free list. The free list does not use
184 prvnode */
185
186 node->nxtnode = freenode;
187 freenode = node;
188 freenodes++;
189}
190
192{
193/* Get a free node to be used in the list of active nodes and
194 initialize the status. */
195
196 struct BBNode *node;
197 if ( freenode )
198 {
199 node = freenode;
200 freenode = freenode->nxtnode;
201 freenodes--;
202 }
203 else
204 {
205 node = (struct BBNode *)malloc( sizeof(struct BBNode) );
206 node->nxtnode = NULL;
207 node->prvnode = NULL;
208 node->values = (double *)malloc( NVAR*sizeof(double) );
209 node->fixed = (int *)malloc( NBIN*sizeof(int) );
210 totnodes++;
211 node->number = totnodes;
212 }
213 node->node_stat = 0;
214 node->solstat =-1;
215 node->modstat =-1;
216 return node;
217}
218
219void add_activenode (struct BBNode *node)
220{
221/* Add a node to the front of the list of Active nodes */
222
223 actnodes++;
224
225 if (actnode)
226 actnode->prvnode = node;
227 node->nxtnode = actnode;
228 node->prvnode = NULL;
229 actnode = node;
230}
231
232void add2workpool( struct BBNode *node )
233{
234/* Add a node to the Workpool list */
235
236 work_node[workpool] = node;
237 workpool++;
238}
239
240int select_var(struct BBNode *node)
241{
242/* Selects variable to branch on, counted in the space of binary
243 variables. Currently there is only one rule, namely to select based
244 on max infeasibility. Other Variable selection rules could be
245 implemented in this routine. */
246
247 int ib = -1, i,j;
248 double dist, maxdist = 0;
249
250 for ( i=0; i<NBIN; i++ )
251 {
252 j = binmap[i];
253 if ( node->values[j] < 1.0-node->values[j] )
254 dist = node->values[j];
255 else
256 dist = 1.0-node->values[j];
257 if ( dist > maxdist )
258 {
259 maxdist = dist;
260 ib = i;
261 }
262 }
263 return ib;
264}
265
267{
268/* Create a workpool of up to MaxPool nodes to be processed in
269 parallel.
270 The nodes are removed from the active list. */
271
272 struct BBNode *node, *curr, *next;
273 double cutoff;
274 int ib; /* Branching variable */
275 int i;
276
277/* printf("Starting create_workpool. maxpool=%d\n", maxpool);
278 list_nodes(); */
279 node = NULL;
280 workpool = 0;
281 while ( workpool < maxpool )
282 {
283 cutoff = 1.e30;
284 curr = actnode;
285/*
286 Run through the linked list of active nodes and find the best.
287 We use the objective but other criteria could be used
288*/
289 node = NULL;
290 while ( curr )
291 {
292 next = curr->nxtnode;
293 if ( curr->object < cutoff )
294 {
295 node = curr;
296 cutoff = curr->object;
297 }
298 curr = next;
299 }
300 if ( node == NULL ) break;
301 printf("Selected node %d with object %f and node_stat %d\n",node->number, node->object, node->node_stat);
302 if ( node->node_stat == 0 )
303 {
304/*
305 The node has been created but not solved.
306 Take it immediately: remove it from the active list and add it
307 to the work_node vector
308*/
309 remove_activenode(node);
310 add2workpool(node);
311 }
312 else
313 {
314/*
315 The node has been solved. Split it in two and take one or both
316 depending on the space left in the workpool
317
318 Get a new node and, select a branching variable, and copy the
319 old node into the new node.
320*/
321 next = get_freenode();
322 ib = select_var( node );
323 for ( i=0; i<NVAR; i++ )
324 next->values[i] = node->values[i];
325 for ( i=0; i<NBIN; i++ )
326 next->fixed[i] = node->fixed[i];
327 next->object = node->object;
328/*
329 Make the two node unsolved and fix the branching variable down and up
330 respectively.
331*/
332 node->node_stat = 0;
333 node->solstat = -1;
334 node->modstat = -1;
335 node->depth++;
336 node->fixed[ib] = 0; /* branch down */
337
338 next->node_stat = 0;
339 next->solstat = -1;
340 next->modstat = -1;
341 next->depth = node->depth;
342 next->fixed[ib] = 1; /* Branch up */
343/*
344 Add the first node to the workpool
345*/
346 remove_activenode(node);
347 add2workpool(node);
348/*
349 Add the second node to the workpool or to the pool of active
350 nodes, depending on space in the workpool
351*/
352 if ( workpool < maxpool )
353 add2workpool(next);
354 else
355 add_activenode(next);
356 }
357 }
358}
359
361{
362/* Solve the models in the WorkPool and integrate the solutions into
363 the active list of nodes. Update the best solution if one is found.*/
364
365 int nw; /* index for active node in the WorkPool */
366 int i;
367 int thread;
368 int COI_Error; /* Local Error counter */
369 coiHandle_t CntVect; /* Local control vector */
370 struct BBNode *node, *curr, *next;
371 int newint;
372 double time0;
373
374 time0 = omp_get_wtime();
375 if ( workpool <= 1 || 0 == parallel )
376 {
377/* This is a serial version */
378 thread = 0;
379 for (nw = 0; nw < workpool; ++nw )
380 {
381 node = work_node[nw];
382/* printf("Starting to solve node %d located at %p.\n",node->number, node); */
383 CntVect = CntVect1[thread];
384 COI_Error = COIDEF_UsrMem( CntVect, (void *)node ); /* Pass the current node through Usrmem */
385 if ( COI_Error )
386 c_log("**** Fatal Error while loading CONOPT Callback routines.", -1 );
388 if ( COI_Error )
389 c_log("**** Fatal Error while solving.", -1);
390 }
391 }
392 else
393/* And this is the corresponding Parallel version of the SOLVE loop. */
394 {
395 COI_Error = 0;
396#pragma omp parallel for default(shared) private(CntVect,thread,node) schedule(dynamic) reduction(+:COI_Error)
397 for (nw = 0; nw < workpool; ++nw )
398 {
399 thread = omp_get_thread_num();
400 node = work_node[nw];
401 printf("Solving node %d with thread %d.\n", node->number, thread);
402 CntVect = CntVect1[thread];
403 COI_Error = COIDEF_UsrMem( CntVect, (void *)node ); /* Pass the current node through Usrmem */
404 if ( !COI_Error )
406 }
407 if ( COI_Error ) /* We cannot exit inside a parallel loop so we wait */
408 c_log("**** Fatal Error inside parallel loop.", -1);
409 }
410/*
411 Endif */
412 stime = stime + omp_get_wtime() - time0;
414/*
415 Process the solutions. The loop is not parallelized so the order here
416 is fixed, independent of the order in which the nodes finished
417 solving.
418*/
419 newint = 0; /* No new integer solution in this pass */
420 for (nw = 0; nw < workpool; ++nw )
421 {
422 node = work_node[nw];
423 printf("Node= %d Solstat= %d Modstat= %d Object= %f Isinteger = %d\n",
424 node->number, node->solstat, node->modstat, node->object, node->isinteger);
425 if ( node->solstat != 1 || node->modstat > 2 )
426 {
427/* The node was not solved to local optimality. Fathom. */
428 printf("Not optimal -- fathom.\n");
429 return_freenode(node);
430 }
431 else if ( intfound )
432 {
433 if ( node->object >= bestint )
434 {
435/* A better solution has been found. Fathom. */
436 printf("Worse than optimal -- fathom.\n");
437 return_freenode(node);
438 }
439 else
440 {
441 if ( node->isinteger )
442 {
443 printf("A: Integer solution stored.\n");
444 numintfound++;
445 newint = 1;
446 bestint = node->object;
447 for ( i = 0; i < NVAR; i++ )
448 solution[i] = node->values[i];
449 return_freenode(node);
450 }
451 else
452 {
453 printf("Non-integer. kept.\n");
454 add_activenode(node);
455 }
456 }
457 }
458 else
459/*
460 An Integer solution has not yet been found. We cannot fathom it.
461*/
462 {
463 if ( node->isinteger )
464 {
465 printf("B: Integer solution stored.\n");
466 numintfound++;
467 intfound = 1;
468 newint = 1;
469 bestint = node->object;
470 for ( i = 0; i < NVAR; i++ )
471 solution[i] = node->values[i];
472 return_freenode(node);
473 }
474 else
475 {
476 printf("Non-integer. kept.\n");
477 add_activenode(node);
478 }
479 }
480 }
481/*
482 If we did find a new integer solution then scan the list of active
483 nodes to check if some of them should be fathomed.
484*/
485 if ( newint )
486 {
487 curr = actnode;
488 while (curr)
489 {
490 next = curr->nxtnode;
491 if ( curr->object > bestint )
492 {
493 printf("Node %d with object= %f fathomed by new objective.\n", curr->number, curr->object);
494 remove_activenode(curr);
495 return_freenode(curr);
496 }
497 curr = next;
498 }
499 }
500}
501
503{
504 int i;
505 struct BBNode *node;
506/*
507 Initialize the first node for B&B tree
508*/
509 numsolve = 0;
510 numintfound = 0;
511 freenode = NULL;
512 actnode = NULL;
513 intfound = 0;
514 totnodes = 0; /* total number of nodes in use */
515 actnodes = 0; /* number of active nodes */
516 freenodes = 0; /* number of free nodes in a free list */
517 stime = 0.0; /* reset solve loop timer */
518
519 node = get_freenode();/* Create a root node with no binaries fixed */
520 node->depth = 0;
521 for ( i = 0; i < NVAR; i++ )
522 node->values[i] = 0.0;
523 for ( i = 0; i < NBIN; i++ )
524 node->fixed[i] = -1;
525 node->object = 1.e29; /* We need a value for the first selection
526 before the node has been solved */
527 add_activenode(node);
528 while ( actnodes > 0 )
529 {
530 printf("Creating WorkPool. Active nodes= %d\n",actnodes);
532 printf("WorkPool with %d nodes selected. Remaining Active nodes= %d.\n",workpool,actnodes);
533 if ( workpool > 0 )
535 else if ( workpool == 0 && actnodes > 0 )
536 c_log("No nodes found but actnodes is positive", -1);
537 }
538
539 if ( intfound )
540 {
541 printf("\nAn integer solution with objective %f has been found.\n\n",bestint);
542 printf("Solution values:\n");
543 for ( ; i < NVAR; i++ )
544 printf(" %d %f \n", i, solution[i]);
545 }
546 else
547 printf("No integer solution has been found\n");
548 printf("Number of Solves: %d\n", numsolve);
549 printf("Number of Integer Solutions: %d\n\n", numintfound);
550
551 while( freenode != NULL )
552 {
553 struct BBNode* n = freenode->nxtnode;
554 free(freenode->values);
555 free(freenode->fixed);
556 free(freenode);
557 freenode = n;
558 }
559}
560/* --------------END OF GENERAL BRANCH AND BOUND ROUTINES */
561float rndx()
562{
563/* Defines a pseudo random number between 0 and 1 */
564
565 seed = (seed*1027+25)%1048576;
566 return ((float)seed)/((float)1048576);
567}
568
570{
571/* Define values Target, Mean, and Q */
572
573 int i, j, j1, k, l;
574 double Sum;
575 double *Xobs;
576
577 Target = 10.0;
578 Xobs = (double *)malloc(NN*NOBS*sizeof(double));
579
580 for (i=0; i< NN; i++)
581 Mean[i] = Target + (rndx()*4.0-2.0);
582/*
583 Create a positive definite matrix computed as the sum of some
584 outer products */
585 j = 0;
586 for (i=0; i< NQ; i++)
587 Q[i] = 0;
588
589 for (i=0; i< NN; i++)
590 {
591 Sum = 0.0;
592 j1 = j;
593 for (k=0; k < NOBS; k++)
594 {
595 Xobs[j] = 100.0*rndx();
596 Sum = Sum + Xobs[j];
597 j++;
598 }
599 Sum = Sum / NOBS;
600 j = j1;
601 for (k=0; k < NOBS; k++)
602 {
603 Xobs[j] = Xobs[j] - Sum;
604 j++;
605 }
606 }
607/* Define the Q-matrix as the sum deviations and store it as a lower
608 triangular matrix stored column-wise in this order
609 0
610 1 NN
611 2 NN+1
612 .
613 NN-1 .. */
614
615 l = 0;
616 for (i=0; i< NN; i++)
617 {
618 for (j=i; j < NN; j++)
619 {
620 Sum = 0.0;
621 for (k=0; k < NOBS; k++)
622 Sum = Sum + Xobs[i*NN+k] * Xobs[j*NN+k];
623 Q[l] = Sum / (NOBS-1);
624 l++;
625 }
626 }
627 free(Xobs);
628 for ( i=0; i<NN; i++ )
629 binmap[i] = NN+i;
630
631}
632
637int COI_CALLCONV QP_ReadMatrix( double LOWER[], double CURR[], double UPPER[], int VSTA[], int TYPE[], double RHS[],
638 int ESTA[], int COLSTA[], int ROWNO[], double VALUE[],
639 int NLFLAG[], int NUMVAR, int NUMCON, int NUMNZ, void* USRMEM )
640{
641 int i, j;
642 struct BBNode *node;
643 node = (struct BBNode *) USRMEM;
644 /* */
645 /* Information about Variables: */
646 /* Default: Lower = -Inf, Curr = 0, and Upper = +inf. */
647 /* Default: the status information in Vsta is not used. */
648 /* */
649 /* Lower bound = 0 on all variables: */
650 /* */
651 for ( i=0; i<NN; i++ )
652 {
653 LOWER[i] = 0.0 ;
654 LOWER[NN+i] = 0.0;
655 UPPER[NN+i] = 1.0;
656 }
657/* Update the current solution and the bounds with information
658 for the current node */
659 for ( i=0; i<NVAR; i++ )
660 {
661 CURR[i] = node->values[i];
662 }
663 for ( i=0; i<NBIN; i++ )
664 {
665 j = binmap[i];
666 if ( node->fixed[i] == 0 )
667 {
668 LOWER[j] = 0.0;
669 UPPER[j] = 0.0;
670 }
671 else if ( node->fixed[i] == 1 )
672 {
673 LOWER[j] = 1.0;
674 UPPER[j] = 1.0;
675 }
676 }
677 /* */
678 /* Information about Constraints: */
679 /* Default: Rhs = 0 */
680 /* Default: the status information in Esta and the function */
681 /* value in FV are not used. */
682 /* Default: Type: There is no default. */
683 /* 0 = Equality, */
684 /* 1 = Greater than or equal, */
685 /* 2 = Less than or equal, */
686 /* 3 = Non binding. */
687 /* */
688 /* Constraint 0 (Objective) */
689 /* Rhs = 0.0 and type Non binding */
690 /* */
691 TYPE[0] = 3 ;
692 /* */
693 /* Constraint 1 (X Sum to 1) */
694 /* Rhs = 1 and type Equality */
695 /* */
696 RHS[1] = 1.0 ;
697 TYPE[1] = 0 ;
698 /* */
699 /* Constraint 2 (Sum X*Mean ) = Target */
700 /* Rhs = 1 and type Equality */
701 /* */
702 RHS[2] = Target;
703 TYPE[2] = 0 ;
704 /* */
705 /* Constraint 3 (Bin Sum to le Maxbin) */
706 /* Rhs = 1 and type Less than or Equal */
707 /* */
708 RHS[3] = MAXBIN ;
709 TYPE[3] = 2 ;
710 /* */
711 /* Constraint group 4 (X le Bin or X - Bin le 0) */
712 /* Rhs = 0 and type Less than or Equal */
713 /* */
714 for ( i=0; i<NN; i++ )
715 {
716 RHS[4+i] = 0.0 ;
717 TYPE[4+i] = 2;
718 }
719
720 /* */
721 /* Information about the Jacobian. We use the standard method with */
722 /* Rowno, Value, Nlflag and Colsta and we do not use Colno. */
723 /* */
724 /* Colsta = Start of column indices (No Defaults): */
725 /* Rowno = Row indices */
726 /* Value = Value of derivative (by default only linear */
727 /* derivatives are used) */
728 /* Nlflag = 0 for linear and 1 for nonlinear derivative */
729 /* (not needed for completely linear models) */
730 /* */
731 j = 0; /* counter for current nonzero */
732 for ( i=0; i<NN; i++ ) { /* X-variables */
733 COLSTA[i] = j;
734 ROWNO[j] = 0; /* Row 0: Objective */
735 NLFLAG[j] = 1;
736 j++;
737 ROWNO[j] = 1; /* Row 1: Sum(X) le 1 */
738 VALUE[j] = 1.0;
739 NLFLAG[j] = 0;
740 j++;
741 ROWNO[j] = 2; /* Row 2: Sum(X*Mean) le Target */
742 VALUE[j] = Mean[i];
743 NLFLAG[j] = 0;
744 j++;
745 ROWNO[j] = 4+i; /* Row group 4: X - Bin le 0 */
746 VALUE[j] = 1.0;
747 NLFLAG[j] = 0;
748 j++;
749 }
750 for ( i=0; i<NN; i++ ) { /* Bin-variables */
751 COLSTA[NN+i] = j;
752 ROWNO[j] = 3; /* Row 3: Sum(Bin) le Maxbin */
753 VALUE[j] = 1.0;
754 NLFLAG[j] = 0;
755 j++;
756 ROWNO[j] = 4+i; /* Row group 4: X - Bin le 0 */
757 VALUE[j] = -1.0;
758 NLFLAG[j] = 0;
759 j++;
760 }
761 COLSTA[2*NN] = j;
762 return 0;
763}
764
765
770int COI_CALLCONV QP_FDEval( const double X[], double* G, double JAC[], int ROWNO, const int JCNM[], int MODE,
771 int IGNERR, int* ERRCNT, int NUMVAR, int NUMJAC, int THREAD, void* USRMEM )
772{
773 int i, j, k;
774 double sum;
775 /* */
776 /* Row 0: the objective function is nonlinear */
777 /* */
778
779 if ( ROWNO == 0 )
780 {
781 /* */
782 /* Mode = 1 or 3. Function value: G = x*Q*x */
783 /* */
784 if ( MODE == 1 || MODE == 3 )
785 {
786 k = 0;
787 sum = 0.0;
788 for (i=0; i< NN; i++)
789 {
790 sum += X[i]*Q[k]*X[i];
791 k++;
792 for (j=i+1; j < NN; j++)
793 {
794 sum += 2*X[i]*Q[k]*X[j];
795 k++;
796 }
797 }
798 *G = sum / 2;
799 }
800 /* */
801 /* Mode = 2 or 3: Derivative values: */
802 /* */
803 if ( MODE == 2 || MODE == 3 )
804 {
805 for ( i=0; i<NN; i++ )
806 JAC[i] = 0.0;
807 k = 0;
808 for (i=0; i < NN; i++)
809 {
810 JAC[i] += Q[k]*X[i];
811 k++;
812 for (j=i+1; j < NN; j++)
813 {
814 JAC[i] += Q[k]*X[j];
815 JAC[j] += Q[k]*X[i];
816 k++;
817 }
818 }
819 }
820 }
821 /* */
822 /* Other rows: These rows are linear and will not be called. */
823 /* */
824
825 return 0;
826}
827
828
833int COI_CALLCONV QP_2DDir( const double X[], const double DX[], double D2G[], int ROWNO,
834 const int JACNUM[], int* NODRV, int NUMVAR, int NUMJAC, int THREAD, void* USRMEM )
835{
836int i, j, k;
837/* */
838/* Is only called for Irow = 0, the nonlinear objective */
839/* Return H*Dx = Q*Dx in D2G */
840/* */
841 if ( ROWNO == 0 )
842 {
843 for ( i=0; i<NN; i++ )
844 D2G[i] = 0.0;
845 k = 0;
846 for (i=0; i< NN; i++)
847 {
848 D2G[i] += Q[k]*DX[i];
849 k++;
850 for (j=i+1; j < NN; j++)
851 {
852 D2G[i] += Q[k]*DX[j];
853 D2G[j] += Q[k]*DX[i];
854 k++;
855 }
856 }
857 }
858 return 0;
859}
860
861
866int COI_CALLCONV QP_2DLagrStr( int HSRW[], int HSCL[], int* NODRV,
867 int NUMVAR, int NUMCON, int NHESS, void* USRMEM )
868{
869 int i, j, k;
870
871 k = 0;
872 for (i=0; i< NN; i++)
873 for (j=i; j < NN; j++)
874 {
875 HSRW[k] = j;
876 HSCL[k] = i;
877 k++;
878 }
879 return 0;
880}
881
882
887int COI_CALLCONV QP_2DLagrVal( const double X[], const double U[], const int HSRW[], const int HSCL[],
888 double HSVL[], int* NODRV, int NUMVAR, int NUMCON, int NHESS, void* USRMEM )
889{
890 int k;
891
892 for ( k=0; k<NQ; k++ )
893 HSVL[k] = Q[k]*U[0];
894 return 0;
895}
896
897int COI_CALLCONV BB_Message( int SMSG, int DMSG, int NMSG, char* MSGV[], void* USRMEM )
898{
899/* Simple implementation that does nothing to avoid mixing output from
900 multiple threads. */
901 return 0;
902}
903
904int COI_CALLCONV BB_ErrMsg( int ROWNO, int COLNO, int POSNO, const char* MSG, void* USRMEM )
905{
906/* Simple implementation that does nothing to avoid mixing output from
907 multiple threads. */
908 return 0;
909}
910
911int COI_CALLCONV BB_Status( int MODSTA, int SOLSTA, int ITER, double OBJVAL, void* USRMEM )
912{
913/*
914 Simple implementation in which we just store the status and
915 objective value in the current node.
916*/
917 struct BBNode *node;
918
919 node = (struct BBNode *) USRMEM;
920
921 stacalls++;
922 node->object = OBJVAL;
923 node->modstat = MODSTA;
924 node->solstat = SOLSTA;
925 node->node_stat = 1;
926 return 0;
927}
928
929int COI_CALLCONV BB_Solution( const double XVAL[], const double XMAR[], const int XBAS[], const int XSTA[],
930 const double YVAL[], const double YMAR[], const int YBAS[], const int YSTA[],
931 int NUMVAR, int NUMCON, void* USRMEM )
932{
933/*
934 Store the solution in the Values field of the solved node.
935 Also check for integrality. If done here it is inside the
936 parallel loop. */
937 struct BBNode *node;
938 int i;
939 int j;
940 int numintvar=0;
941 double dist;
942
943 node = (struct BBNode *) USRMEM;
944 for ( i=0; i<NUMVAR; i++ )
945 node->values[i] = XVAL[i];
946 for ( i=0; i < NBIN; i++ )
947 {
948 j = binmap[i];
949 if ( node->values[j] < 1.0-node->values[j] )
950 dist = node->values[j];
951 else
952 dist = 1.0-node->values[j];
953 if ( dist <= bintol ) numintvar++;
954 }
955 node->isinteger = (numintvar==NBIN);
956 solcalls++;
957
958 return 0;
959}
960
963int main(int argc, char** argv)
964{
965 coiHandle_t CntVect; /* the global CntVect is overwritten in this model */
966 int maxthread; /* Maximum number of threads */
967 char msg[256];
968
969 int thread;
970 double time0;
971 double time1;
972 double time8S, time16S, time32S;
973 double time8P, time16P, time32P;
974 double stime1;
975 double stime8S, stime16S, stime32S;
976 double stime8P, stime16P, stime32P;
977 int numsolve1;
978 int numsolve8S, numsolve16S, numsolve32S;
979 int numsolve8P, numsolve16P, numsolve32P;
980
981 c_log( "Starting to execute", START );
982 maxthread = omp_get_max_threads();
983 printf("Initial maxthread= %d\n",maxthread);
984 if ( maxthread < 4 ) {
985 maxthread = 4;
986 omp_set_num_threads(maxthread);
987 }
988 printf("Revised maxthread= %d\n",maxthread);
989
990/*
991 Allocate and initialize the Q matrix
992 */
993 defdata();
994/*
995 We cannot use COIDEF_IniC since we need several control vectors.
996 Below we initialize with COIDEF_Ini, COIDEF_Base, and COIDEF_C
997 for the control record for each block.
998*/
999 CntVect1 = (coiHandle_t *) malloc( maxthread*sizeof(coiHandle_t) );
1000 /*
1001 Tell CONOPT about the sizes in the model
1002 */
1003 for ( thread=0; thread<maxthread; thread++ )
1004 {
1005 CntVect1[thread] = NULL;
1007 if (NULL==CntVect) {
1008 printf("Could not create Conopt object: %s\n", msg);
1009 exit(1);
1010 }
1011 CntVect1[thread] = CntVect;
1012 COI_Error += COIDEF_NumVar ( CntVect, 2*NN ); /* 2*NN variables */
1013 COI_Error += COIDEF_NumCon ( CntVect, 4+NN ); /* 3+NN constraints */
1014 COI_Error += COIDEF_NumNz ( CntVect, 6*NN ); /* 5*NN nonzeros in the Jacobian */
1015 COI_Error += COIDEF_NumNlNz ( CntVect, NN ); /* NN of which are nonlinear */
1016 COI_Error += COIDEF_NumHess ( CntVect, NQ ); /* NQ nonzero hessian elements */
1017 COI_Error += COIDEF_OptDir ( CntVect, -1 ); /* Minimize */
1018 COI_Error += COIDEF_ObjCon ( CntVect, 0 ); /* Objective is constraint 0 */
1019 COI_Error += COIDEF_DebugFV ( CntVect, 0 ); /* 0 means no debugging, 1 each iter */
1020 COI_Error += COIDEF_StdOut ( CntVect, 0 ); /* 1 means Allow output to StdOut */
1021 /*
1022 Register the necessary callback routines with CONOPT
1023 */
1024 COI_Error += COIDEF_Message ( CntVect, &BB_Message ); /* Register the callback Message */
1025 COI_Error += COIDEF_ErrMsg ( CntVect, &BB_ErrMsg ); /* Register the callback ErrMsg */
1026 COI_Error += COIDEF_Status ( CntVect, &BB_Status ); /* Register the callback Status */
1027 COI_Error += COIDEF_Solution ( CntVect, &BB_Solution ); /* Register the callback Solution */
1028 COI_Error += COIDEF_ReadMatrix( CntVect, &QP_ReadMatrix); /* Register the callback ReadMatrix */
1029 COI_Error += COIDEF_FDEval ( CntVect, &QP_FDEval); /* Register the callback FDEval */
1030 COI_Error += COIDEF_2DDir ( CntVect, &QP_2DDir ); /* Register the callback 2DDir */
1031 COI_Error += COIDEF_2DLagrStr ( CntVect, &QP_2DLagrStr); /* Register the callback 2DLagrStr */
1032 COI_Error += COIDEF_2DLagrVal ( CntVect, &QP_2DLagrVal); /* Register the callback 2DLagrVal */
1033
1034#if defined(LICENSE_INT_1) && defined(LICENSE_INT_2) && defined(LICENSE_INT_3) && defined(LICENSE_TEXT)
1035 COI_Error += COIDEF_License ( CntVect, LICENSE_INT_1, LICENSE_INT_2, LICENSE_INT_3, LICENSE_TEXT);
1036#endif
1037 }
1038
1039 if ( COI_Error ) {
1040 printf("Skipping COI_Solve due to setup errors. COI_Error = %d\n",COI_Error);
1041 c_log( "Skipping Solve due to setup errors", COI_Error); }
1042/*
1043 Solve the model using sequential processing with 1 node in pool
1044*/
1045 parallel = 0;
1046 maxpool = 1;
1047 time0 = omp_get_wtime();
1048 bandb_solve();
1049 time1 = omp_get_wtime() - time0;
1050 stime1 = stime;
1051 numsolve1 = numsolve;
1052 fprintf(fd,"Finished sequential with maxpool= %d\n",maxpool);
1053/*
1054 Solve the model using sequential processing with 8 nodes in pool
1055*/
1056 parallel = 0;
1057 maxpool = 8;
1058 time0 = omp_get_wtime();
1059 bandb_solve();
1060 time8S = omp_get_wtime() - time0;
1061 stime8S = stime;
1062 numsolve8S = numsolve;
1063 fprintf(fd,"Finished sequential with maxpool= %d\n",maxpool);
1064/*
1065 Solve the model using sequential processing with 16 nodes in pool
1066*/
1067 parallel = 0;
1068 maxpool = 16;
1069 time0 = omp_get_wtime();
1070 bandb_solve();
1071 time16S = omp_get_wtime() - time0;
1072 stime16S = stime;
1073 numsolve16S = numsolve;
1074 fprintf(fd,"Finished sequential with maxpool= %d\n",maxpool);
1075/*
1076 Solve the model using sequential processing with 32 nodes in pool
1077*/
1078 parallel = 0;
1079 maxpool = 32;
1080 time0 = omp_get_wtime();
1081 bandb_solve();
1082 time32S = omp_get_wtime() - time0;
1083 stime32S = stime;
1084 numsolve32S = numsolve;
1085 fprintf(fd,"Finished sequential with maxpool= %d\n",maxpool);
1086/*
1087 Solve the model using sequential processing with 8 nodes in pool
1088*/
1089 parallel = 1;
1090 maxpool = 8;
1091 time0 = omp_get_wtime();
1092 bandb_solve();
1093 time8P = omp_get_wtime() - time0;
1094 stime8P = stime;
1095 numsolve8P = numsolve;
1096 fprintf(fd,"Finished parallel with maxpool= %d\n",maxpool);
1097/*
1098 Solve the model using sequential processing with 16 nodes in pool
1099*/
1100 parallel = 1;
1101 maxpool = 16;
1102 time0 = omp_get_wtime();
1103 bandb_solve();
1104 time16P = omp_get_wtime() - time0;
1105 stime16P = stime;
1106 numsolve16P = numsolve;
1107 fprintf(fd,"Finished parallel with maxpool= %d\n",maxpool);
1108/*
1109 Solve the model using sequential processing with 32 nodes in pool
1110*/
1111 parallel = 1;
1112 maxpool = 32;
1113 time0 = omp_get_wtime();
1114 bandb_solve();
1115 time32P = omp_get_wtime() - time0;
1116 stime32P = stime;
1117 numsolve32P = numsolve;
1118 fprintf(fd,"Finished parallel with maxpool= %d\n",maxpool);
1119
1120 fprintf(fd,"Number of Binary variables in model= %d\n",NN);
1121 fprintf(fd,"Number of threads in parallel experiments= %d\n\n",maxthread);
1122 fprintf(fd,"Loop type MaxPool Total time %% Solve Time %% Number of Solves Parallel Speedup\n\n");
1123 fprintf(fd,"Sequential 1 %9.3f %5.1f %9.3f %5.1f %d\n",
1124 time1 , 100.0, stime1 , 100.0, numsolve1);
1125 fprintf(fd,"Sequential 8 %9.3f %5.1f %9.3f %5.1f %d\n",
1126 time8S, time8S/time1*100.0, stime8S, stime8S/stime1*100.0, numsolve8S);
1127 fprintf(fd,"Sequential 16 %9.3f %5.1f %9.3f %5.1f %d\n",
1128 time16S, time16S/time1*100.0, stime16S, stime16S/stime1*100.0, numsolve16S);
1129 fprintf(fd,"Sequential 32 %9.3f %5.1f %9.3f %5.1f %d\n",
1130 time32S, time32S/time1*100.0, stime32S, stime32S/stime1*100.0, numsolve32S);
1131 fprintf(fd,"Parallel 8 %9.3f %5.1f %9.3f %5.1f %d %10.2f\n",
1132 time8P, time8P/time1*100.0, stime8P, stime8P/stime1*100.0, numsolve8P, time8S/time8P);
1133 fprintf(fd,"Parallel 16 %9.3f %5.1f %9.3f %5.1f %d %10.2f\n",
1134 time16P, time16P/time1*100.0, stime16P, stime16P/stime1*100.0, numsolve16P, time16S/time16P);
1135 fprintf(fd,"Parallel 32 %9.3f %5.1f %9.3f %5.1f %d %10.2f\n",
1136 time32P, time32P/time1*100.0, stime32P, stime32P/stime1*100.0, numsolve32P, time32S/time32P);
1137
1138 if ( COI_Error ) {
1139 c_log( "Errors encountered during first solve", COI_Error); }
1140 else if ( stacalls == 0 || solcalls == 0 ) {
1141 c_log( "Status or Solution routine was not during first solve called",-1 ); }
1142 else if ( numsolve8S != numsolve8P ) {
1143 c_log( "Number of solves with workpool 8 differs between static and dynamic", -1 ); }
1144 else if ( numsolve16S != numsolve16P ) {
1145 c_log( "Number of solves with workpool 16 differs between static and dynamic", -1 ); }
1146 else if ( numsolve32S != numsolve32P ) {
1147 c_log( "Number of solves with workpool 32 differs between static and dynamic", -1 ); }
1148
1149 for ( thread=0; thread<maxthread; thread++ )
1150 {
1151 CntVect = CntVect1[thread];
1152 coiFree(&CntVect);
1153 }
1154 free(CntVect1);
1155 coiFinalize();
1156 c_log( "Successful Solve", OK );
1157}
C language header file for direct linking against the COI library generated by apiwrapper for GAMS Ve...
int stacalls
Definition comdecl.h:4
char pname[MAXLINE]
Definition comdecl.h:10
char fname[MAXLINE]
Definition comdecl.h:11
coiHandle_t CntVect
Definition comdecl.h:14
#define START
Definition comdecl.h:13
#define MAXLINE
Definition comdecl.h:9
FILE * fd
Definition comdecl.h:3
int solcalls
Definition comdecl.h:5
#define OK
Definition comdecl.h:12
int COI_Error
Definition comdecl.h:15
FILE * fs
Definition comdecl.h:2
int COI_CALLCONV COIDEF_ReadMatrix(coiHandle_t cntvect, COI_READMATRIX_t coi_readmatrix)
define callback routine for providing the matrix data to CONOPT.
int COI_CALLCONV COIDEF_Message(coiHandle_t cntvect, COI_MESSAGE_t coi_message)
define callback routine for handling messages returned during the solution process.
int COI_CALLCONV COIDEF_Solution(coiHandle_t cntvect, COI_SOLUTION_t coi_solution)
define callback routine for returning the final solution values.
int COI_CALLCONV COIDEF_Status(coiHandle_t cntvect, COI_STATUS_t coi_status)
define callback routine for returning the completion status.
int COI_CALLCONV COIDEF_ErrMsg(coiHandle_t cntvect, COI_ERRMSG_t coi_errmsg)
define callback routine for returning error messages for row, column or Jacobian elements.
int COI_CALLCONV COIDEF_FDEval(coiHandle_t cntvect, COI_FDEVAL_t coi_fdeval)
define callback routine for performing function and derivative evaluations.
int COI_CALLCONV COIDEF_2DLagrVal(coiHandle_t cntvect, COI_2DLAGRVAL_t coi_2dlagrval)
define callback routine for computing the values of the second derivatives of the Lagrangian.
int COI_CALLCONV COIDEF_UsrMem(coiHandle_t cntvect, void *usrmem)
provides a pointer to user memory that is available in all callback functions. NOTE: this is not a ca...
int COI_CALLCONV COIDEF_2DDir(coiHandle_t cntvect, COI_2DDIR_t coi_2ddir)
define callback routine for computing the second derivative for a constraint in a direction.
int COI_CALLCONV COIDEF_2DLagrStr(coiHandle_t cntvect, COI_2DLAGRSTR_t coi_2dlagrstr)
define callback routine for providing the structure of the second derivatives of the Lagrangian.
int COI_CALLCONV COIDEF_DebugFV(coiHandle_t cntvect, int debugfv)
turn Debugging of FDEval on and off.
int COI_CALLCONV COIDEF_License(coiHandle_t cntvect, int licint1, int licint2, int licint3, const char *licstring)
define the License Information.
int COI_CALLCONV COIDEF_StdOut(coiHandle_t cntvect, int tostdout)
allow output to StdOut.
int COI_CALLCONV COIDEF_NumHess(coiHandle_t cntvect, int numhess)
defines the Number of Hessian Nonzeros.
int COI_CALLCONV COIDEF_ObjCon(coiHandle_t cntvect, int objcon)
defines the Objective Constraint.
int COI_CALLCONV COIDEF_NumVar(coiHandle_t cntvect, int numvar)
defines the number of variables in the model.
int COI_CALLCONV COIDEF_NumNz(coiHandle_t cntvect, int numnz)
defines the number of nonzero elements in the Jacobian.
int COI_CALLCONV COIDEF_NumCon(coiHandle_t cntvect, int numcon)
defines the number of constraints in the model.
int COI_CALLCONV COIDEF_OptDir(coiHandle_t cntvect, int optdir)
defines the Optimization Direction.
int COI_CALLCONV COIDEF_NumNlNz(coiHandle_t cntvect, int numnlnz)
defines the Number of Nonlinear Nonzeros.
void COI_CALLCONV coiFinalize(void)
finializes the solving process for CONOPT. This must be called when using OpenMP. It will terminate t...
int COI_CALLCONV coiCreate(coiHandle_t *cntvect)
initialises and create the control vector.
int COI_CALLCONV coiFree(coiHandle_t *cntvect)
frees the control vector.
int COI_CALLCONV COI_Solve(coiHandle_t cntvect)
method for starting the solving process of CONOPT.
int seed
Definition leastsq.c:15
int maxpool
Definition mp_qpbandb.c:132
int select_var(struct BBNode *node)
Definition mp_qpbandb.c:240
struct BBNode * freenode
Definition mp_qpbandb.c:126
void add_activenode(struct BBNode *node)
Definition mp_qpbandb.c:219
int workpool
Definition mp_qpbandb.c:133
int actnodes
Definition mp_qpbandb.c:110
int main(int argc, char **argv)
Main program. A simple setup and call of CONOPT.
Definition mp_qpbandb.c:963
struct BBNode * work_node[maxmaxpool]
Definition mp_qpbandb.c:134
int COI_CALLCONV QP_FDEval(const double X[], double *G, double JAC[], int ROWNO, const int JCNM[], int MODE, int IGNERR, int *ERRCNT, int NUMVAR, int NUMJAC, int THREAD, void *USRMEM)
Compute nonlinear terms and non-constant Jacobian elements.
Definition mp_qpbandb.c:770
double stime
Definition mp_qpbandb.c:138
void return_freenode(struct BBNode *node)
Definition mp_qpbandb.c:181
int numintfound
Definition mp_qpbandb.c:117
void solve_workpool()
Definition mp_qpbandb.c:360
int numsolve
Definition mp_qpbandb.c:111
#define NOBS
Definition mp_qpbandb.c:40
int COI_CALLCONV BB_Solution(const double XVAL[], const double XMAR[], const int XBAS[], const int XSTA[], const double YVAL[], const double YMAR[], const int YBAS[], const int YSTA[], int NUMVAR, int NUMCON, void *USRMEM)
Definition mp_qpbandb.c:929
#define NBIN
Definition mp_qpbandb.c:38
void bandb_solve()
Definition mp_qpbandb.c:502
int intfound
Definition mp_qpbandb.c:115
double solution[NVAR]
Definition mp_qpbandb.c:120
void add2workpool(struct BBNode *node)
Definition mp_qpbandb.c:232
int totnodes
Definition mp_qpbandb.c:108
struct BBNode * actnode
Definition mp_qpbandb.c:124
coiHandle_t * CntVect1
Definition mp_qpbandb.c:48
int COI_CALLCONV QP_ReadMatrix(double LOWER[], double CURR[], double UPPER[], int VSTA[], int TYPE[], double RHS[], int ESTA[], int COLSTA[], int ROWNO[], double VALUE[], int NLFLAG[], int NUMVAR, int NUMCON, int NUMNZ, void *USRMEM)
Define information about the model.
Definition mp_qpbandb.c:637
int COI_CALLCONV QP_2DLagrStr(int HSRW[], int HSCL[], int *NODRV, int NUMVAR, int NUMCON, int NHESS, void *USRMEM)
Specify the structure of the Lagrangian of the Hessian.
Definition mp_qpbandb.c:866
void defdata()
Definition mp_qpbandb.c:569
double bestint
Definition mp_qpbandb.c:118
int COI_CALLCONV BB_Message(int SMSG, int DMSG, int NMSG, char *MSGV[], void *USRMEM)
Definition mp_qpbandb.c:897
int freenodes
Definition mp_qpbandb.c:109
void create_workpool()
Definition mp_qpbandb.c:266
void c_log(char *msgt, int code)
Definition mp_qpbandb.c:52
#define maxmaxpool
Definition mp_qpbandb.c:131
int COI_CALLCONV BB_ErrMsg(int ROWNO, int COLNO, int POSNO, const char *MSG, void *USRMEM)
Definition mp_qpbandb.c:904
double Mean[NN]
Definition mp_qpbandb.c:43
double bintol
Definition mp_qpbandb.c:107
int COI_CALLCONV QP_2DDir(const double X[], const double DX[], double D2G[], int ROWNO, const int JACNUM[], int *NODRV, int NUMVAR, int NUMJAC, int THREAD, void *USRMEM)
Computes the second derivative of a constraint in a direction.
Definition mp_qpbandb.c:833
#define NVAR
Definition mp_qpbandb.c:37
struct BBNode * get_freenode()
Definition mp_qpbandb.c:191
#define MAXBIN
Definition mp_qpbandb.c:39
void remove_activenode(struct BBNode *node)
Definition mp_qpbandb.c:168
int binmap[NN]
Definition mp_qpbandb.c:45
int COI_CALLCONV QP_2DLagrVal(const double X[], const double U[], const int HSRW[], const int HSCL[], double HSVL[], int *NODRV, int NUMVAR, int NUMCON, int NHESS, void *USRMEM)
Compute the Lagrangian of the Hessian.
Definition mp_qpbandb.c:887
void list_nodes()
Definition mp_qpbandb.c:153
int parallel
Definition mp_qpbandb.c:136
int COI_CALLCONV BB_Status(int MODSTA, int SOLSTA, int ITER, double OBJVAL, void *USRMEM)
Definition mp_qpbandb.c:911
float rndx()
Definition mp_qpbandb.c:561
void list_node(struct BBNode *node)
Definition mp_qpbandb.c:144
#define NN
Definition qp1.c:21
int COI_CALLCONV QP_FDEval(const double X[], double *G, double JAC[], int ROWNO, const int JACNUM[], int MODE, int IGNERR, int *ERRCNT, int NUMVAR, int NUMJAC, int THREAD, void *USRMEM)
Compute nonlinear terms and non-constant Jacobian elements.
Definition qp1.c:99
#define NQ
Definition qp1.c:22
double Q[NQ]
Definition qp1.c:23
int COI_CALLCONV QP_ReadMatrix(double LOWER[], double CURR[], double UPPER[], int VSTA[], int TYPE[], double RHS[], int ESTA[], int COLSTA[], int ROWNO[], double VALUE[], int NLFLAG[], int NUMVAR, int NUMCON, int NUMNZ, void *USRMEM)
Define information about the model.
Definition qp1.c:33
double Target[NN]
Definition qp1.c:24
int COI_CALLCONV QP_2DDir(const double X[], const double DX[], double D2G[], int ROWNO, const int JACNUM[], int *NODRV, int NUMVAR, int NUMJAC, int THREAD, void *USRMEM)
Computes the second derivative of a constraint in a direction.
Definition qp2.c:152
int COI_CALLCONV QP_2DLagrStr(int HSRW[], int HSCL[], int *NODRV, int NUMVAR, int NUMCON, int NHESS, void *USRMEM)
Specify the structure of the Lagrangian of the Hessian.
Definition qp3.c:152
int COI_CALLCONV QP_2DLagrVal(const double X[], const double U[], const int HSRW[], const int HSCL[], double HSVL[], int *NODRV, int NUMVAR, int NUMCON, int NHESS, void *USRMEM)
Compute the Lagrangian of the Hessian.
Definition qp3.c:168
int solstat
Definition mp_qpbandb.c:98
int node_stat
Definition mp_qpbandb.c:95
int * fixed
Definition mp_qpbandb.c:90
double object
Definition mp_qpbandb.c:93
int depth
Definition mp_qpbandb.c:103
int isinteger
Definition mp_qpbandb.c:104
double * values
Definition mp_qpbandb.c:89
int number
Definition mp_qpbandb.c:102
struct BBNode * prvnode
Definition mp_qpbandb.c:91
int modstat
Definition mp_qpbandb.c:100
struct BBNode * nxtnode
Definition mp_qpbandb.c:92