Exemple #1
0
void binmap(int *rule, // 1 or 2, just like for approx()
    double *beamAngle, double *pitch, double *roll, // all of length 1
    int *n, // length of distance, z1-z4, and y1-y4
    double *distance, // like "x"
    double *y1, double *y2, double *y3, double *y4,  // like a set of "y" values
    // below are storage
    double *buffer, // do not allocate locally, for speed
    double *z1, double *z2, double *z3, double *z4,  // calculated here; just supply space
    double *Y1, double *Y2, double *Y3, double *Y4)  // calculated here; just supply space
{
  int i;
  // distance, y, y1-y4 are of length *n
  // beamAngle, pitch, and roll are of length 1
  const double RPD = atan2(1.0, 1.0) / 45.0; // radians/degree
#if 0
  Rprintf("n %d\n", *n);
  Rprintf("beamAngle %f pitch %f roll %f\n", *beamAngle, *pitch, *roll);
#endif
  double cr = cos((*roll) * RPD);
  double sr = sin((*roll) * RPD);
  double cp = cos((*pitch) * RPD);
  double sp = sin((*pitch) * RPD);
  double tt = tan((*beamAngle) * RPD);
#if 0
  Rprintf("C : r %.6f p %.6f cr %.6f sr %.6f cp %.6f sp %.6f tt %.6f\n", *roll, *pitch, cr, sr, cp, sp, tt);
#endif
  for (i=0; i < *n; i++) {
    z1[i] = distance[i] * (cr - tt * sr) * cp;
    z2[i] = distance[i] * (cr + tt * sr) * cp;
    z3[i] = distance[i] * (cp + tt * sp) * cr;
    z4[i] = distance[i] * (cp - tt * sp) * cr;
  }
#if 0
  Rprintf("C : z1       ");
  for (i = 0; i < 8; i++)
    Rprintf("%11.6f ", i, z1[i]);
  Rprintf("\n");
#endif

  // y <- .C(C_R_approx, as.double(x), as.double(y), as.integer(nx), 
  //  xout = as.double(xout), as.integer(length(xout)), as.integer(method), 
  //  as.double(yleft), as.double(yright), as.double(f), NAOK = TRUE, 
  //  PACKAGE = "stats")$xout
  double f = 0.0; // unused, since we set method=1; see docs on approx()
  double left, right;
  // void R_approx(double *x, double *y, int *nxy, double *xout, int *nout,
  //               int *method, double *yleft, double *yright, double *f)
  // NOTE: replaces xout with the interpolated value!
  int method = 1; // "linear" for approx()

  if (*rule == 1) { left = NA_REAL; right = NA_REAL; } else { left = y1[0]; right = y1[*n]; }
  for (i = 0; i < *n; i++) {
    buffer[i] = distance[i];
  }
  R_approx(z1, y1, n, buffer, n, &method, &left, &right, &f);
  for (i = 0; i < *n; i++) {
    Y1[i] = buffer[i];
    buffer[i] = distance[i];
  }

  if (*rule == 1) { left = NA_REAL; right = NA_REAL; } else { left = y2[0]; right = y2[*n]; }
  R_approx(z2, y2, n, buffer, n, &method, &left, &right, &f);
  for (i = 0; i < *n; i++) {
    Y2[i] = buffer[i];
    buffer[i] = distance[i];
  }

  if (*rule == 1) { left = NA_REAL; right = NA_REAL; } else { left = y3[0]; right = y3[*n]; }
  R_approx(z3, y3, n, buffer, n, &method, &left, &right, &f);
  for (i = 0; i < *n; i++) {
    Y3[i] = buffer[i];
    buffer[i] = distance[i];
  }

  if (*rule == 1) { left = NA_REAL; right = NA_REAL; } else { left = y4[0]; right = y4[*n]; }
  R_approx(z4, y4, n, buffer, n, &method, &left, &right, &f);
  for (i = 0; i < *n; i++) {
    Y4[i] = buffer[i];
  }
}
int main(int argc, char **argv) {
	clock_t t1, t2;
	t1 = clock();

	IloEnv env;
	IloModel model(env);
	IloCplex cplex(model);

	/************************** Defining the parameters ************************************/
	IloInt N;							//No. of nodes
	IloInt M;							//No. of calls
	Num2DMatrix links(env);				//Defines the topology of the network
	IloNumArray call_demand(env);		//link bandwidth requirement of each call
	IloNumArray call_revenue(env);		//revenue generated from the call
	IloNumArray call_origin(env);		//origin node index of each call
	IloNumArray call_destination(env);	//destination node index of each call
	Num2DMatrix Q(env);					//Bandwidth capacity of each link
	Num2DMatrix sigma(env);				//Standard deviation of service times on link (i,j)
	Num2DMatrix cv(env);				//coefficient of variation of service times on the link (i,j)
	IloNum C;							//Unit queueing delay cost per unit time
	IloNumArray R_approx_init(env);

	ifstream fin;
	const char* filename = "BPP_data_sample - Copy.txt";
	if (argc > 1)
		filename = argv[1];
		
	fin.open(filename);
	//fin.open("BPP_10node_navneet.txt");
	fin >> links >> call_origin >> call_destination >> call_demand >>
		call_revenue >> Q >> cv >> R_approx_init >> C ;
	cout << "Reading Data from the file - "<<filename<<endl;

	N = links.getSize();
	M = call_origin.getSize();

	IloInt H = R_approx_init.getSize();
	Num3DMatrix R_approx(env, N);			//The tangential linear function approximation to R.
	for (IloInt i=0; i<N; i++) {
		R_approx[i] = Num2DMatrix(env, N);
		for (IloInt j=0; j<N; j++) {
			R_approx[i][j] = IloNumArray(env, H);
			for (IloInt h=0; h<H; h++)
				R_approx[i][j][h] = R_approx_init[h];
		}
	}

	/************************** Defining the parameters ENDS ************************************/

	/************* Defining the variables defined in the model formulation **********************/
	IloNumVarArray Y(env, M, 0, 1, ILOINT); //Variable to define whether a call m is routed or not
	IloNumArray Y_sol(env, M); //Solution values

	NumVar3DMatrix X(env, N); //Variable to define whether a call m is routed along path i-j
	Num3DMatrix X_sol(env, N);
	for (IloInt i=0; i<N; i++) {
		X[i] = NumVar2DMatrix(env, N);
		X_sol[i] = Num2DMatrix(env, N);
		for (IloInt j=0; j<N; j++) {
			X[i][j] = IloNumVarArray(env, M, 0, 1, ILOINT);
			X_sol[i][j] = IloNumArray(env, M);
		}
	}

	NumVar3DMatrix W(env, N); //Variable to define whether a call m is routed along path i-j
	for (IloInt i=0; i<N; i++) {
		W[i] = NumVar2DMatrix(env, N);
		for (IloInt j=0; j<N; j++)
			W[i][j] = IloNumVarArray(env, M, 0, 1, ILOINT);
	}

	NumVar2DMatrix R(env, (IloInt)N); //The linearization Variable
	for (IloInt i=0; i<N; i++)
		R[i] = IloNumVarArray(env, (IloInt)N, 0, IloInfinity, ILOFLOAT);
	
	/************* Defining the variables defined in the model formulation ENDS *****************/

	/**************************** Defining the Constraints *******************************/
	// Constraint #1 : Flow Conservation Constraint
	for (IloInt m=0; m<M; m++) {
		for (IloInt i=0; i<N; i++) {
			IloExpr constraint1(env);
			for (IloInt j=0; j<N; j++) {
				if (links[i][j] == 1)
					constraint1 += W[i][j][m];
			}
			for (IloInt j=0; j<N; j++) {
				if (links[j][i] == 1)
					constraint1 += -W[j][i][m];
			}
			
			if (i == call_origin[m])
				model.add(constraint1 == Y[m]);
			else if (i == call_destination[m])
				model.add(constraint1 == -Y[m]);
			else 
				model.add(constraint1 == 0);

			constraint1.end();
		}
	}

	// Constraint #2 :
	for (IloInt m=0; m<M; m++) {
		for (IloInt i=0; i<N; i++) {			
			for (IloInt j=0; j<N; j++) {
				if (links[i][j] == 1)
					model.add(W[i][j][m] + W[j][i][m] <= X[i][j][m]);					
			}			
		}
	}

	// Constraint #3 : Link Capacity Constraint
	for (IloInt i=0; i<N; i++) {
		for (IloInt j=i+1; j<N; j++) {
			if (links[i][j] == 1) {
				IloExpr constraint3(env);
				for (IloInt m=0; m<M; m++)
					constraint3 += call_demand[m]*X[i][j][m];
				model.add(constraint3 <= Q[i][j]);
				constraint3.end();
			}
		}
	}
	
	// Constraint #4 : Defining the constraint for initial values of R_approx, 
	//				   Cuts must be added during the iterations whenever the values are updated
	for (IloInt i=0; i<N; i++) {
		for (IloInt j=i+1; j<N; j++) {	
			if (links[i][j] == 1) {
				for (IloInt h=0; h<H; h++) {
					IloExpr constraint4_lhs(env);
					IloNum constraint4_rhs = 0;
					for (IloInt m=0; m<M; m++)
						constraint4_lhs += call_demand[m]*X[i][j][m];

					constraint4_lhs -= (Q[i][j]/((1+R_approx[i][j][h])*(1+R_approx[i][j][h])))*R[i][j];
					constraint4_rhs = Q[i][j]*((R_approx[i][j][h]/(1+R_approx[i][j][h])) *
											(R_approx[i][j][h]/(1+R_approx[i][j][h])));
					model.add(constraint4_lhs <= constraint4_rhs);
					constraint4_lhs.end();
				}
			}
		}
	}

	/************************** Defining the Constraints ENDS ****************************/

	/************************ Defining the Objective Function ****************************/
	IloExpr Objective(env);
	IloExpr Obj_expr1(env);
	IloExpr Obj_expr2(env);
	
	for (IloInt m=0; m<M; m++)
		Obj_expr1 += call_revenue[m]*Y[m];

	for (IloInt i=0; i<N; i++) {
		for (IloInt j=i+1; j<N; j++) {
			if (links[i][j] == 1) {
				Obj_expr2 += (1+cv[i][j] * cv[i][j])*R[i][j];
				for (IloInt m=0; m<M; m++) 
					Obj_expr2 += ((1-cv[i][j] * cv[i][j])/Q[i][j])*call_demand[m]*X[i][j][m];
			}
		}
	}
	Objective += Obj_expr1 - 0.5*C*Obj_expr2;
	model.add(IloMaximize(env, Objective));
	//model.add(IloMinimize(env, -Objective));

	Objective.end();
	Obj_expr1.end();
	Obj_expr2.end();

	/********************** Defining the Objective Function ENDS **************************/

	IloNum eps = cplex.getParam(IloCplex::EpInt);

	IloNum UB = IloInfinity;
	IloNum LB = -IloInfinity;

	/***************** Solve ***********************/
	do {
		cplex.setParam(IloCplex::MIPInterval, 5);
		cplex.setParam(IloCplex::NodeFileInd ,2);
		cplex.setOut(env.getNullStream());

		cplex.exportModel("BPP_model.lp");

		if(!cplex.solve()) {
			cout << "Infeasible"<<endl;
			system("pause");
		}
		else {
			for (IloInt m=0; m<M; m++) {
				if (cplex.getValue(Y[m]) > eps) {
					cout << "Call(m) = "<<m+1<<" : "<<call_origin[m]+1<<" --> "<<call_destination[m]+1
						<<"; demand = "<<call_demand[m]<<endl;
					cout << "Path : ";
					for (IloInt i=0; i<N; i++) {
						for (IloInt j=i+1; j<N; j++) {
							if (links[i][j] == 1) {
								if (cplex.getValue(X[i][j][m]) > eps) {
									X_sol[i][j][m] = 1;
									cout <<i+1<<"-"<<j+1<<"; ";
								}
							}
						}
					}
					cout << endl << endl;
				}				
			}		

			//system("pause");
		}

		UB = min(UB, cplex.getObjValue());

		IloNum lbound = 0;
		for (IloInt m=0; m<M; m++) 
			if(cplex.getValue(Y[m]) > eps)
				lbound += call_revenue[m];

		for (IloInt i=0; i<N; i++) {
			for (IloInt j=i+1; j<N; j++) {
				if (links[i][j] == 1) {
					IloNum lbound_temp1 = 0;
					IloNum lbound_temp2 = 0;
					for (IloInt m=0; m<M; m++)
						lbound_temp1 += call_demand[m]*X_sol[i][j][m];
					lbound_temp2 = 0.5*(1+cv[i][j]*cv[i][j]) * (lbound_temp1*lbound_temp1) / (Q[i][j]*(Q[i][j]-lbound_temp1));
					lbound_temp2 += lbound_temp1 / Q[i][j];

					lbound -= C*lbound_temp2;
				}
			}
		}

		LB = max(LB, lbound);
		
		Num2DMatrix R_approx_new(env, N);
		for (IloInt i=0; i<N; i++)
			R_approx_new[i] = IloNumArray(env, N);

		for (IloInt i=0; i<N; i++) {			
			for (IloInt j=i+1; j<N; j++) {	
				if (links[i][j] == 1) {
					IloExpr cut_lhs(env);
					IloNum cut_rhs = 0;		

					IloNum cut_temp = 0;
					for (IloInt m=0; m<M; m++) {
						cut_temp += call_demand[m]*X_sol[i][j][m];
					}

					R_approx_new[i][j] = cut_temp / (Q[i][j] - cut_temp);
					//cout << "R_approx_new = "<<R_approx_new<<endl;
										
					for (IloInt m=0; m<M; m++)
						cut_lhs += call_demand[m]*X[i][j][m];					

					cut_lhs -= (Q[i][j]/((1+R_approx_new[i][j])*(1+R_approx_new[i][j])))*R[i][j];
					cut_rhs = Q[i][j]*((R_approx_new[i][j]/(1+R_approx_new[i][j])) *
												(R_approx_new[i][j]/(1+R_approx_new[i][j])));

					model.add(cut_lhs <= cut_rhs);
					cut_lhs.end();
				}				
			}
		}

		cout << "UB = "<<UB<<endl;
		cout << "LB = "<<LB<<endl;
		cout << "Gap (%) = "<<(UB-LB)*100/LB<<endl;
		//system("pause");

	}while ((UB-LB)/UB > eps);
	t2 = clock();
	float secs = (float)t2 - (float)t1;
	secs = secs / CLOCKS_PER_SEC;
	cout << "CPUTIME = "<<secs <<endl<<endl;
}