I am writing a C programme in which there will be several arrays which lengths are configured in a data file.
I am trying to read I and J from OFDMA.dat, and create arrays Noise, Bw .etc
The lines I have commented belong to the original programme which works:
//#define I 3;
//#define J 2;
//#define NUMROWS (1+I+2*I*J)
//#define NUMCOLS 3*I*J
//#define NUMNZ 6*I*J
Then I tried to read from OFDMA.dat with following code:
while (fgets(buffer, 80, dat) != NULL) {
if (buffer[0] == '#') continue;
if (counter == 1){
maxIter = atoi(buffer);
printf("maxIter \n");
}
if (counter == 2){
Pwr = atof(buffer);
printf("Pwr \n");
}
if (counter == 3){
I = atoi(buffer);
printf("I \n");
Bw = (double*)malloc(sizeof(double)*I);
Noise = (double*)malloc(sizeof(double)*I);
}
if (counter == 4){
J = atoi(buffer);
printf("J \n");
}
if (counter>4 && counter <= 4 + I){
Noise[counter - 5] = atof(buffer);
printf("Noise[%d]: %lf\n", counter - 5, Noise[counter - 5]);
}
if (counter>4 + I&&counter<4 + 2 * I){
Bw[counter - 5 - I] = atof(buffer);
printf("Bw[%d]: %lf\n", counter - I - 5, Bw[counter - I - 5]);
}
counter++;
}
Then visual studio says:
1>OFDMA.c(96): error C2057: expected constant expression
1>OFDMA.c(96): error C2466: cannot allocate an array of constant size 0
1>OFDMA.c(102): error C2057: expected constant expression
1>OFDMA.c(102): error C2466: cannot allocate an array of constant size 0
1>OFDMA.c(135): error C2057: expected constant expression
1>OFDMA.c(135): error C2466: cannot allocate an array of constant size 0
1>OFDMA.c(135): error C2133: 'x' : unknown size
1>OFDMA.c(136): error C2057: expected constant expression
1>OFDMA.c(136): error C2466: cannot allocate an array of constant size 0
1>OFDMA.c(136): error C2133: 'slack' : unknown size
1>OFDMA.c(352): error C2057: expected constant expression
1>OFDMA.c(352): error C2466: cannot allocate an array of constant size 0
1>OFDMA.c(546): error C2057: expected constant expression
1>OFDMA.c(546): error C2466: cannot allocate an array of constant size 0
In those lines, I and J are used in declaring arrays. For example:
static int
setproblemdata(char **probname_p, int *numcols_p, int *numrows_p, int *objsen_p,
double **obj_p, double **rhs_p, char **sense_p, int **matbeg_p,
int **matcnt_p, int **matind_p, double **matval_p, double **lb_p,
double **ub_p, char **ctype_p, double Noise_p[I]);
The full codes:
/* Bring in the CPLEX function declarations and the C library
header file stdio.h with the include of cplex.h. */
#include <ilcplex/cplex.h>
/* Bring in the declarations for the string functions */
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
/* The problem we are optimizing will have I channels, J users.
* So there will be 1+I+2*I*J rows, 3*I*J columns, and 5*I*J nonzeros. */
//#define I 3;
//#define J 2;
//#define NUMROWS (1+I+2*I*J)
//#define NUMCOLS 3*I*J
//#define NUMNZ 6*I*J
int I, J;
int maxIter;
double Pwr;
double* Bw;
double* Noise;
/* Include declaration for function at end of program */
static int readdata(){
int counter = 1;
FILE * dat;
dat = fopen("OFDMA.dat", "r");
char buffer[80];
if (!dat) // equivalent to saying if ( in_file == NULL )
{
printf("oops, file can't be read\n");
return 1;
}
while (fgets(buffer, 80, dat) != NULL) {
if (buffer[0] == '#') continue;
if (counter == 1){
maxIter = atoi(buffer);
printf("maxIter \n");
}
if (counter == 2){
Pwr = atof(buffer);
printf("Pwr \n");
}
if (counter == 3){
I = atoi(buffer);
printf("I \n");
Bw = (double*)malloc(sizeof(double)*I);
Noise = (double*)malloc(sizeof(double)*I);
NUMROWS=1+I+2*I*J;
NUMCOLS=4*I*J;
NUMNZ=6*I*J;
}
if (counter == 4){
J = atoi(buffer);
printf("J \n");
}
if (counter>4 && counter <= 4 + I){
Noise[counter - 5] = atof(buffer);
printf("Noise[%d]: %lf\n", counter - 5, Noise[counter - 5]);
}
if (counter>4 + I&&counter<4 + 2 * I){
Bw[counter - 5 - I] = atof(buffer);
printf("Bw[%d]: %lf\n", counter - I - 5, Bw[counter - I - 5]);
}
counter++;
}
fclose(dat);
return 0;
}
static int
setproblemdata(char **probname_p, int *numcols_p, int *numrows_p, int *objsen_p,
double **obj_p, double **rhs_p, char **sense_p, int **matbeg_p,
int **matcnt_p, int **matind_p, double **matval_p, double **lb_p,
double **ub_p, char **ctype_p, double Noise_p[I]);
static void
free_and_null(char **ptr);
static int
addcuts(double **matval_p, double **rhs_p, double pbar_p[I*J], const double Bw_[I], double Noise_p[I]);
int main(void) {
/* Declare pointers for the variables and arrays that will contain
the data which define the LP problem. The setproblemdata() routine
allocates space for the problem data. */
char *probname = NULL;
int numcols;
int numrows;
int objsen;
double *obj = NULL;
double *rhs = NULL;
char *sense = NULL;
int *matbeg = NULL;
int *matcnt = NULL;
int *matind = NULL;
double *matval = NULL;
double *lb = NULL;
double *ub = NULL;
char *ctype = NULL;
double *pbar = NULL;
/* Declare and allocate space for the variables and arrays where we will
store the optimization results including the status, objective value,
variable values, and row slacks. */
int solstat;
double objval;
double x[NUMCOLS];
double slack[NUMROWS];
CPXENVptr env = NULL;
CPXLPptr lp = NULL;
int status;
int i, j;
int counter;
int cur_numrows, cur_numcols;
/* Import Data from file OFDMA.dat*/
status = readdata();
if (status){
fprintf(stderr, "Failure to read data from file. \n");
goto TERMINATE;
}
/* Initialize the CPLEX environment */
env = CPXopenCPLEX(&status);
/* If an error occurs, the status value indicates the reason for
failure. A call to CPXgeterrorstring will produce the text of
the error message. Note that CPXopenCPLEX produces no output,
so the only way to see the cause of the error is to use
CPXgeterrorstring. For other CPLEX routines, the errors will
be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */
if (env == NULL) {
char errmsg[CPXMESSAGEBUFSIZE];
fprintf(stderr, "Could not open CPLEX environment.\n");
CPXgeterrorstring(env, status, errmsg);
fprintf(stderr, "%s", errmsg);
goto TERMINATE;
}
/* Turn on output to the screen */
status = CPXsetintparam(env, CPXPARAM_ScreenOutput, CPX_ON);
if (status) {
fprintf(stderr, "Failure to turn on screen indicator, error %d.\n",
status);
goto TERMINATE;
}
/* Fill in the data for the problem. */
status = setproblemdata(&probname, &numcols, &numrows, &objsen, &obj, &rhs,
&sense, &matbeg, &matcnt, &matind, &matval, &lb, &ub, &ctype, Noise);
if (status) {
fprintf(stderr, "Failed to build problem data arrays.\n");
goto TERMINATE;
}
/* Create the problem. */
lp = CPXcreateprob(env, &status, probname);
/* A returned pointer of NULL may mean that not enough memory
was available or there was some other problem. In the case of
failure, an error message will have been written to the error
channel from inside CPLEX. In this example, the setting of
the parameter CPXPARAM_ScreenOutput causes the error message to
appear on stdout. */
if (lp == NULL) {
fprintf(stderr, "Failed to create LP.\n");
goto TERMINATE;
}
/* Main Loop */
for (i = 0; i < maxIter; i++) {
/* Now copy the problem data into the lp */
status = CPXcopylp(env, lp, numcols, numrows, objsen, obj, rhs, sense,
matbeg, matcnt, matind, matval, lb, ub, NULL);
if (status) {
fprintf(stderr, "Failed to copy problem data.\n");
goto TERMINATE;
}
/* Now copy the ctype array */
status = CPXcopyctype(env, lp, ctype);
if (status) {
fprintf(stderr, "Failed to copy ctype\n");
goto TERMINATE;
}
/* Optimize the problem and obtain solution. */
status = CPXmipopt(env, lp);
if (status) {
fprintf(stderr, "Failed to optimize MIP.\n");
goto TERMINATE;
}
solstat = CPXgetstat(env, lp);
/* Write the output to the screen. */
printf("\nSolution status = %d\n", solstat);
status = CPXgetobjval(env, lp, &objval);
if (status) {
fprintf(stderr, "No MIP objective value available. Exiting...\n");
goto TERMINATE;
}
cur_numcols = CPXgetnumcols(env, lp);
status = CPXgetx(env, lp, x, 0, cur_numcols - 1);
if (status) {
fprintf(stderr, "Failed to get optimal integer x.\n");
goto TERMINATE;
}
printf("Solution value = %f\n\n", objval);
/* Add Cuts to the problem */
addcuts(&matval, &rhs, x, Bw, Noise);
}
/* The size of the problem should be obtained by asking CPLEX what
the actual size is, rather than using what was passed to CPXcopylp.
cur_numrows and cur_numcols store the current number of rows and
columns, respectively. */
cur_numrows = CPXgetnumrows(env, lp);
cur_numcols = CPXgetnumcols(env, lp);
status = CPXgetx(env, lp, x, 0, cur_numcols - 1);
if (status) {
fprintf(stderr, "Failed to get optimal integer x.\n");
goto TERMINATE;
}
status = CPXgetslack(env, lp, slack, 0, cur_numrows - 1);
if (status) {
fprintf(stderr, "Failed to get optimal slack values.\n");
goto TERMINATE;
}
for (i = 0; i < cur_numrows; i++) {
printf("Row %d: Slack = %10f\n", i, slack[i]);
}
for (j = 0; j < cur_numcols; j++) {
printf("Column %d: Value = %10f\n", j, x[j]);
}
/* Finally, write a copy of the problem to a file. */
status = CPXwriteprob(env, lp, "OFMDA.lp", NULL);
if (status) {
fprintf(stderr, "Failed to write LP to disk.\n");
goto TERMINATE;
}
TERMINATE:
/* Free up the problem as allocated by CPXcreateprob, if necessary */
if (lp != NULL) {
status = CPXfreeprob(env, &lp);
if (status) {
fprintf(stderr, "CPXfreeprob failed, error code %d.\n", status);
}
}
/* Free up the CPLEX environment, if necessary */
if (env != NULL) {
status = CPXcloseCPLEX(&env);
/* Note that CPXcloseCPLEX produces no output,
so the only way to see the cause of the error is to use
CPXgeterrorstring. For other CPLEX routines, the errors will
be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */
if (status) {
char errmsg[CPXMESSAGEBUFSIZE];
fprintf(stderr, "Could not close CPLEX environment.\n");
CPXgeterrorstring(env, status, errmsg);
fprintf(stderr, "%s", errmsg);
}
}
/* Free up the problem data arrays, if necessary. */
free_and_null((char **)&probname);
free_and_null((char **)&obj);
free_and_null((char **)&rhs);
free_and_null((char **)&sense);
free_and_null((char **)&matbeg);
free_and_null((char **)&matcnt);
free_and_null((char **)&matind);
free_and_null((char **)&matval);
free_and_null((char **)&lb);
free_and_null((char **)&ub);
free_and_null((char **)&ctype);
return (status);
} /* END main */
static int setproblemdata(char **probname_p, int *numcols_p, int *numrows_p,
int *objsen_p, double **obj_p, double **rhs_p, char **sense_p,
int **matbeg_p, int **matcnt_p, int **matind_p, double **matval_p,
double **lb_p, double **ub_p, char **ctype_p, double Noise_p[I]) {
char *zprobname = NULL; /* Problem name <= 16 characters */
double *zobj = NULL;
double *zrhs = NULL;
char *zsense = NULL;
int *zmatbeg = NULL;
int *zmatcnt = NULL;
int *zmatind = NULL;
double *zmatval = NULL;
double *zlb = NULL;
double *zub = NULL;
char *zctype = NULL;
int status = 0;
int i, j; //channel and user
int counter = 0; //counter
zprobname = (char *)malloc(16 * sizeof (char));
zobj = (double *)malloc(NUMCOLS * sizeof (double));
zrhs = (double *)malloc(NUMROWS * sizeof (double));
zsense = (char *)malloc(NUMROWS * sizeof (char));
zmatbeg = (int *)malloc(NUMCOLS * sizeof (int));
zmatcnt = (int *)malloc(NUMCOLS * sizeof (int));
zmatind = (int *)malloc(NUMNZ * sizeof (int));
zmatval = (double *)malloc(NUMNZ * sizeof (double));
zlb = (double *)malloc(NUMCOLS * sizeof (double));
zub = (double *)malloc(NUMCOLS * sizeof (double));
zctype = (char *)malloc(NUMCOLS * sizeof (char));
if (zprobname == NULL || zobj == NULL || zrhs == NULL || zsense == NULL
|| zmatbeg == NULL || zmatcnt == NULL || zmatind == NULL
|| zmatval == NULL || zlb == NULL || zub == NULL || zctype == NULL) {
status = 1;
goto TERMINATE;
}
strcpy(zprobname, "example");
/* The code is formatted to make a visual correspondence
between the mathematical linear program and the specific data
items. */
/* Objective Function*/
/* coefficients of p_ij and x_ij*/
for (i = 0; i < 2 * I * J; i++) {
zobj[i] = 0;
}
/* coefficients of e_ij*/
for (i = 2 * I * J; i < 3 * I * J; i++) {
zobj[i] = 1;
}
/* Constraints */
/*
* Non-zeros
*
* Every p_ij appears twice, at the 0th and (I+i)th constraints.
* Every x_ij appears twice, at the ...........
* Every e_ij appears once, at the (1+I+I*J+i)th constraint.
*/
for (i = 0; i < I * J; i++) {
zmatbeg[i] = 3 * i;
zmatcnt[i] = 3;
}
for (i = 0; i < I * J; i++) {
zmatbeg[I * J + i] = 3 * I * J + 2 * i;
zmatcnt[I * J + i] = 2;
}
for (i = 0; i < I * J; i++) {
zmatbeg[2 * I * J + i] = 5 * I * J + i;
zmatcnt[2 * I * J + i] = 1;
}
/*
* p_ij appears at the 0th and (I+i+1)th constraints, coefficient is 1.
*/
for (i = 0; i < I * J; i++) {
zmatind[3 * i] = 0;
zmatval[3 * i] = 1.0;
zmatind[3 * i + 1] = I + i + 1;
zmatval[3 * i + 1] = 1.0;
zmatind[3 * i + 2] = 1 + I + I * J + i;
zmatval[3 * i + 2] = -1.0;
}
/*
* x_ij
*/
int ztmpind = I + 1;
for (i = 0; i < 2 * I * J; i += 2) {
zmatind[3 * I * J + i] = i / (2 * J) + 1;
zmatval[3 * I * J + i] = 1;
zmatind[3 * I * J + i + 1] = ztmpind;
zmatval[3 * I * J + i + 1] = -1 * Pwr;
ztmpind++;
}
/*
* e_ij appears at the (1+I+I*J+i)th constraint.
*/
for (i = 0; i < I * J; i++) {
zmatind[5 * I * J + i] = 1 + I + I * J + i;
zmatval[5 * I * J + i] = 1;
}
/*
* Domain of variables
*/
for (i = 0; i < I * J; i++) {
zlb[i] = 0.0;
zub[i] = CPX_INFBOUND;
zctype[i] = 'C';
}
for (i = I * J; i < 2 * I * J; i++) {
zlb[i] = 0.0;
zub[i] = 1.0;
zctype[i] = 'I';
}
for (i = 2 * I * J; i < 3 * I * J; i++) {
zlb[i] = 0.0;
zub[i] = CPX_INFBOUND;
zctype[i] = 'C';
}
/* The right-hand-side values don't fit nicely on a line above. So put
them here. */
zsense[0] = 'L';
zrhs[0] = Pwr;
for (i = 0; i < I; i++) {
zsense[i + 1] = 'L';
zrhs[i + 1] = 1;
}
for (i = 0; i < I * J; i++) {
zsense[I + i + 1] = 'L';
zrhs[I + 1 + i] = 0;
}
counter = 0;
for (i = 0; i < I; i++) {
for (j = 0; j < J; j++) {
zsense[1 + I + I * J + counter] = 'L';
zrhs[1 + I + I * J + counter] = log(1 + Pwr / Noise_p[i]);
counter++;
}
}
TERMINATE:
if (status) {
free_and_null((char **)&zprobname);
free_and_null((char **)&zobj);
free_and_null((char **)&zrhs);
free_and_null((char **)&zsense);
free_and_null((char **)&zmatbeg);
free_and_null((char **)&zmatcnt);
free_and_null((char **)&zmatind);
free_and_null((char **)&zmatval);
free_and_null((char **)&zlb);
free_and_null((char **)&zub);
free_and_null((char **)&zctype);
}
else {
*numcols_p = NUMCOLS;
*numrows_p = NUMROWS;
*objsen_p = CPX_MAX; /* The problem is maximization */
*probname_p = zprobname;
*obj_p = zobj;
*rhs_p = zrhs;
*sense_p = zsense;
*matbeg_p = zmatbeg;
*matcnt_p = zmatcnt;
*matind_p = zmatind;
*matval_p = zmatval;
*lb_p = zlb;
*ub_p = zub;
*ctype_p = zctype;
}
return (status);
} /* END setproblemdata */
/* Add Cuts to the problem */
static int addcuts(double **matval_p, double **rhs_p, double pbar_p[I*J], const double Bw_p[I], double Noise_p[I]) {
double *zmatval = NULL;
double *zrhs = NULL;
int status = 0;
int i, j;
int counter;
zrhs = (double *)malloc(NUMROWS * sizeof (double));
zmatval = (double *)malloc(NUMNZ * sizeof (double));
if (zrhs == NULL || zmatval == NULL) {
status = 1;
goto TERMINATE;
}
zrhs = *rhs_p;
zmatval = *matval_p;
for (i = 0; i < I * J; i++) {
printf("pbar_%d is %f\n", i, pbar_p[i]);
}
/*
*/
counter = 0;
for (i = 0; i < I; i++) {
for (j = 0; j < J; j++) {
printf("e_bar: %f\n", Bw_p[i] * log2(1 + pbar_p[counter] / Noise_p[i]));
}
}
for (i = 0; i < I; i++) {
for (j = 0; j < J; j++) {
printf("xx: %f\n", -Bw_p[i] / (log(2)*(Noise_p[i] + pbar_p[i])));
}
}
for (i = 0; i < I; i++) {
for (j = 0; j < J; j++) {
zmatval[3 * i + 2] = -Bw_p[i] / (log(2)*(Noise_p[i] + pbar_p[i]));
}
}
for (i = 0; i < I; i++) {
for (j = 0; j < J; j++) {
zrhs[1 + I + I * J + i] = Bw_p[i] * log2(1 + pbar_p[i] / Noise_p[i]) - Bw_p[i] / (log(2)*(Noise_p[i] + pbar_p[i])) * pbar_p[i];
}
}
TERMINATE:
if (status) {
free_and_null((char **)&zrhs);
}
else {
*rhs_p = zrhs;
}
return (status);
} /* END addcuts */
/* This simple routine frees up the pointer *ptr, and sets *ptr to NULL */
static void free_and_null(char **ptr) {
if (*ptr != NULL) {
free(*ptr);
*ptr = NULL;
}
} /* END free_and_null */
Can anybody give me an example please?