19#pragma warning (disable : 3280)
41#define NQ (NN*(NN+1)/2)
52void c_log(
char *msgt,
int code )
63 while ( (c = getchar()) != EOF && i <
MAXLINE )
pname[i++] = (char)c;
71 fc = fopen(
fname,
"w");
72 fprintf(fc,
"%s: %s.\n",
pname, msgt );
148 printf(
"list_node: number= %d node_stat= %d.\n", node->
number,node->
node_stat);
150 printf(
"list_node: node is NULL.\n");
161 printf(
"list_nodes: node number= %d node_stat= %d object= %f\n", node->
number, node->
node_stat, node->
object);
165 printf(
"list_nodes: Total= %d.\n", n);
205 node = (
struct BBNode *)malloc(
sizeof(
struct BBNode) );
208 node->
values = (
double *)malloc(
NVAR*
sizeof(
double) );
209 node->
fixed = (
int *)malloc(
NBIN*
sizeof(
int) );
248 double dist, maxdist = 0;
250 for ( i=0; i<
NBIN; i++ )
256 dist = 1.0-node->
values[j];
257 if ( dist > maxdist )
272 struct BBNode *node, *curr, *next;
293 if ( curr->
object < cutoff )
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);
323 for ( i=0; i<
NVAR; i++ )
325 for ( i=0; i<
NBIN; i++ )
370 struct BBNode *node, *curr, *next;
374 time0 = omp_get_wtime();
386 c_log(
"**** Fatal Error while loading CONOPT Callback routines.", -1 );
389 c_log(
"**** Fatal Error while solving.", -1);
396#pragma omp parallel for default(shared) private(CntVect,thread,node) schedule(dynamic) reduction(+:COI_Error)
399 thread = omp_get_thread_num();
401 printf(
"Solving node %d with thread %d.\n", node->
number, thread);
408 c_log(
"**** Fatal Error inside parallel loop.", -1);
423 printf(
"Node= %d Solstat= %d Modstat= %d Object= %f Isinteger = %d\n",
428 printf(
"Not optimal -- fathom.\n");
436 printf(
"Worse than optimal -- fathom.\n");
443 printf(
"A: Integer solution stored.\n");
447 for ( i = 0; i <
NVAR; i++ )
453 printf(
"Non-integer. kept.\n");
465 printf(
"B: Integer solution stored.\n");
470 for ( i = 0; i <
NVAR; i++ )
476 printf(
"Non-integer. kept.\n");
493 printf(
"Node %d with object= %f fathomed by new objective.\n", curr->
number, curr->
object);
521 for ( i = 0; i <
NVAR; i++ )
523 for ( i = 0; i <
NBIN; i++ )
530 printf(
"Creating WorkPool. Active nodes= %d\n",
actnodes);
532 printf(
"WorkPool with %d nodes selected. Remaining Active nodes= %d.\n",
workpool,
actnodes);
536 c_log(
"No nodes found but actnodes is positive", -1);
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]);
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);
566 return ((
float)
seed)/((float)1048576);
578 Xobs = (
double *)malloc(
NN*
NOBS*
sizeof(
double));
580 for (i=0; i<
NN; i++)
586 for (i=0; i<
NQ; i++)
589 for (i=0; i<
NN; i++)
593 for (k=0; k <
NOBS; k++)
595 Xobs[j] = 100.0*
rndx();
601 for (k=0; k <
NOBS; k++)
603 Xobs[j] = Xobs[j] - Sum;
616 for (i=0; i<
NN; i++)
618 for (j=i; j <
NN; j++)
621 for (k=0; k <
NOBS; k++)
622 Sum = Sum + Xobs[i*
NN+k] * Xobs[j*
NN+k];
623 Q[l] = Sum / (
NOBS-1);
628 for ( i=0; i<
NN; i++ )
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 )
643 node = (
struct BBNode *) USRMEM;
651 for ( i=0; i<
NN; i++ )
659 for ( i=0; i<
NVAR; i++ )
661 CURR[i] = node->
values[i];
663 for ( i=0; i<
NBIN; i++ )
666 if ( node->
fixed[i] == 0 )
671 else if ( node->
fixed[i] == 1 )
714 for ( i=0; i<
NN; i++ )
732 for ( i=0; i<
NN; i++ ) {
750 for ( i=0; i<
NN; i++ ) {
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 )
784 if ( MODE == 1 || MODE == 3 )
788 for (i=0; i<
NN; i++)
790 sum += X[i]*
Q[k]*X[i];
792 for (j=i+1; j <
NN; j++)
794 sum += 2*X[i]*
Q[k]*X[j];
803 if ( MODE == 2 || MODE == 3 )
805 for ( i=0; i<
NN; i++ )
808 for (i=0; i <
NN; i++)
812 for (j=i+1; j <
NN; j++)
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 )
843 for ( i=0; i<
NN; i++ )
846 for (i=0; i<
NN; i++)
848 D2G[i] +=
Q[k]*DX[i];
850 for (j=i+1; j <
NN; j++)
852 D2G[i] +=
Q[k]*DX[j];
853 D2G[j] +=
Q[k]*DX[i];
867 int NUMVAR,
int NUMCON,
int NHESS,
void* USRMEM )
872 for (i=0; i<
NN; i++)
873 for (j=i; j <
NN; j++)
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 )
892 for ( k=0; k<
NQ; k++ )
897int COI_CALLCONV
BB_Message(
int SMSG,
int DMSG,
int NMSG,
char* MSGV[],
void* USRMEM )
904int COI_CALLCONV
BB_ErrMsg(
int ROWNO,
int COLNO,
int POSNO,
const char* MSG,
void* USRMEM )
911int COI_CALLCONV
BB_Status(
int MODSTA,
int SOLSTA,
int ITER,
double OBJVAL,
void* USRMEM )
919 node = (
struct BBNode *) USRMEM;
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 )
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++ )
952 dist = 1.0-node->
values[j];
953 if ( dist <=
bintol ) numintvar++;
972 double time8S, time16S, time32S;
973 double time8P, time16P, time32P;
975 double stime8S, stime16S, stime32S;
976 double stime8P, stime16P, stime32P;
978 int numsolve8S, numsolve16S, numsolve32S;
979 int numsolve8P, numsolve16P, numsolve32P;
982 maxthread = omp_get_max_threads();
983 printf(
"Initial maxthread= %d\n",maxthread);
984 if ( maxthread < 4 ) {
986 omp_set_num_threads(maxthread);
988 printf(
"Revised maxthread= %d\n",maxthread);
999 CntVect1 = (coiHandle_t *) malloc( maxthread*
sizeof(coiHandle_t) );
1003 for ( thread=0; thread<maxthread; thread++ )
1008 printf(
"Could not create Conopt object: %s\n", msg);
1034#if defined(LICENSE_INT_1) && defined(LICENSE_INT_2) && defined(LICENSE_INT_3) && defined(LICENSE_TEXT)
1040 printf(
"Skipping COI_Solve due to setup errors. COI_Error = %d\n",
COI_Error);
1047 time0 = omp_get_wtime();
1049 time1 = omp_get_wtime() - time0;
1052 fprintf(
fd,
"Finished sequential with maxpool= %d\n",
maxpool);
1058 time0 = omp_get_wtime();
1060 time8S = omp_get_wtime() - time0;
1063 fprintf(
fd,
"Finished sequential with maxpool= %d\n",
maxpool);
1069 time0 = omp_get_wtime();
1071 time16S = omp_get_wtime() - time0;
1074 fprintf(
fd,
"Finished sequential with maxpool= %d\n",
maxpool);
1080 time0 = omp_get_wtime();
1082 time32S = omp_get_wtime() - time0;
1085 fprintf(
fd,
"Finished sequential with maxpool= %d\n",
maxpool);
1091 time0 = omp_get_wtime();
1093 time8P = omp_get_wtime() - time0;
1096 fprintf(
fd,
"Finished parallel with maxpool= %d\n",
maxpool);
1102 time0 = omp_get_wtime();
1104 time16P = omp_get_wtime() - time0;
1107 fprintf(
fd,
"Finished parallel with maxpool= %d\n",
maxpool);
1113 time0 = omp_get_wtime();
1115 time32P = omp_get_wtime() - time0;
1118 fprintf(
fd,
"Finished parallel with maxpool= %d\n",
maxpool);
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);
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 ); }
1149 for ( thread=0; thread<maxthread; thread++ )
1156 c_log(
"Successful Solve",
OK );
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 select_var(struct BBNode *node)
void add_activenode(struct BBNode *node)
int main(int argc, char **argv)
Main program. A simple setup and call of CONOPT.
struct BBNode * work_node[maxmaxpool]
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.
void return_freenode(struct BBNode *node)
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)
void add2workpool(struct BBNode *node)
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.
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.
int COI_CALLCONV BB_Message(int SMSG, int DMSG, int NMSG, char *MSGV[], void *USRMEM)
void c_log(char *msgt, int code)
int COI_CALLCONV BB_ErrMsg(int ROWNO, int COLNO, int POSNO, const char *MSG, void *USRMEM)
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.
struct BBNode * get_freenode()
void remove_activenode(struct BBNode *node)
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.
int COI_CALLCONV BB_Status(int MODSTA, int SOLSTA, int ITER, double OBJVAL, void *USRMEM)
void list_node(struct BBNode *node)
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.
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.
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.
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.
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.