int CPLEXPrintFromSolver() {
	int Status = 0;
	if (CPLEXenv == NULL) {
		FErrorFile() << "Cannot print problem to file because CPLEX environment is not open." << endl;
		FlushErrorFile();
		return FAIL;
	}

	if (CPLEXModel == NULL) {
		FErrorFile() << "Cannot print problem to file because no CPLEX model exists." << endl;
		FlushErrorFile();
		return FAIL;
	}
	
	string Filename = CheckFilename(FOutputFilepath()+GetParameter("LP filename"));
	Status = CPXwriteprob (CPLEXenv, CPLEXModel,Filename.data(), "LP");

	if (Status) {
		FErrorFile() << "Cannot print problem to file for unknown reason." << endl;
		FlushErrorFile();
		return FAIL;
	}

	return SUCCESS;
}
Exemple #2
0
int CPLEXDelConstraint(LinEquation* InEquation) {
	int Status = 0;
	int rowIndex = InEquation->Index;
	int* indexPtr;
	string ConstraintName = GetConstraintName(InEquation);

	Status = CPXgetrowindex(CPLEXenv, CPLEXModel, ConstraintName.data(), indexPtr);

	if (Status) {
		FErrorFile() << "Failed to get constraint index for deletion." << endl;
		FlushErrorFile();
		return FAIL;
	}

	Status = CPXdelrows(CPLEXenv, CPLEXModel, rowIndex, rowIndex);

	if (Status) {
		FErrorFile() << "Failed to delete constraint " << ConstraintName << endl;
		FlushErrorFile();
		return FAIL;
	} else {
		return SUCCESS;
	}
	
}
int GLPKPrintFromSolver(int lpcount) {
	if (GLPKModel == NULL) {
		FErrorFile() << "Cannot print problem because problem does not exist." << endl;
		FlushErrorFile();
		return FAIL;
	}

	string Filename = CheckFilename(FOutputFilepath()+GetParameter("LP filename"));
	int Status = glp_write_lp(GLPKModel,NULL,ConvertStringToCString(Filename));

	if (Status) {
		FErrorFile() << "Unable to write problem to file due to error in writing function." << endl;
		FlushErrorFile();
		return FAIL;
	}

	Filename = CheckFilename(FOutputFilepath()+GetParameter("LP filename")+itoa(lpcount));
	Status = glp_write_lp(GLPKModel,NULL,ConvertStringToCString(Filename));

	if (Status) {
		FErrorFile() << "Unable to write problem to file due to error in writing function." << endl;
		FlushErrorFile();
		return FAIL;
	}

	return SUCCESS;
}
int GLPKAddConstraint(LinEquation* InEquation) {
	if (InEquation->QuadCoeff.size() > 0) {
		FErrorFile() << "GLPK solver cannot accept quadratic constraints." << endl;
		FlushErrorFile();
		return FAIL;
	}

	if (GLPKModel == NULL) {
		FErrorFile() << "Could not add constraint because GLPK object does not exist." << endl;
		FlushErrorFile();
		return FAIL;
	}

	int NumRows = glp_get_num_rows(GLPKModel);

	if (InEquation->Index >= NumRows) {
		glp_add_rows(GLPKModel, 1);
	}

	if (InEquation->EqualityType == EQUAL) {
		glp_set_row_bnds(GLPKModel, InEquation->Index+1, GLP_FX, InEquation->RightHandSide, InEquation->RightHandSide);
	} else if (InEquation->EqualityType == GREATER) {
		glp_set_row_bnds(GLPKModel, InEquation->Index+1, GLP_LO, InEquation->RightHandSide, InEquation->RightHandSide);
	} else if (InEquation->EqualityType == LESS) {
		glp_set_row_bnds(GLPKModel, InEquation->Index+1, GLP_UP, InEquation->RightHandSide, InEquation->RightHandSide);
	} else {
		FErrorFile() << "Could not add constraint because the constraint type was not recognized." << endl;
		FlushErrorFile();
		return FAIL;
	}

	int NumColumns = glp_get_num_cols(GLPKModel);

	int* Indecies = new int[int(InEquation->Variables.size())+1];
	double* Coeff = new double[int(InEquation->Variables.size())+1];
	for (int i=0; i < int(InEquation->Variables.size()); i++) {
		if (InEquation->Variables[i]->Index < NumColumns) {
			if (InEquation->Variables[i]->Exclude) {
				Coeff[i+1] = 0;
			} else {
				Coeff[i+1] = InEquation->Coefficient[i];
			}
			Indecies[i+1] = InEquation->Variables[i]->Index+1;
		} else {
			FErrorFile() << "Variable index found in constraint is out of the range found in GLPK problem" << endl;
			FlushErrorFile();
			return FAIL;
		}
	}

	glp_set_mat_row(GLPKModel, InEquation->Index+1, int(InEquation->Variables.size()), Indecies, Coeff);

	delete [] Indecies;
	delete [] Coeff;

	return SUCCESS;
}
Exemple #5
0
int CPLEXClearSolver() {
	int Status = 0;
	if (CPLEXModel != NULL) {
		Status = CPXfreeprob(CPLEXenv, &CPLEXModel);
	}

	if (Status || CPLEXModel != NULL) {
		FErrorFile() << "Failed to delete old CPLEX model." << endl;\
		FlushErrorFile();
		return FAIL;
	}

	return SUCCESS;
}
int GLPKLoadObjective(LinEquation* InEquation, bool Max) {
	if (InEquation->QuadCoeff.size() > 0) {
		FErrorFile() << "GLPK solver cannot accept quadratic objectives." << endl;
		FlushErrorFile();
		return FAIL;
	}

	if (GLPKModel == NULL) {
		FErrorFile() << "Could not add objective because GLPK object does not exist." << endl;
		FlushErrorFile();
		return FAIL;
	}

	if (!Max) {
		glp_set_obj_dir(GLPKModel, GLP_MIN);
	} else {
		glp_set_obj_dir(GLPKModel, GLP_MAX);
	}
	
	int NumColumns = glp_get_num_cols(GLPKModel);

	for (int i=0; i < NumColumns; i++) {
		glp_set_obj_coef(GLPKModel, i+1, 0);
	}
	for (int i=0; i < int(InEquation->Variables.size()); i++) {
		if (NumColumns > InEquation->Variables[i]->Index) {
			glp_set_obj_coef(GLPKModel, InEquation->Variables[i]->Index+1, InEquation->Coefficient[i]);
		} else {
			FErrorFile() << "Variable index specified in objective was out of the range of variables added to the GLPK problem object." << endl;
			FlushErrorFile();
			return FAIL;
		}
	}

	return SUCCESS;
}
Exemple #7
0
int CPLEXCleanup() {
	int Status = 0;
	if (CPLEXModel != NULL) {
		if (CPLEXClearSolver() != SUCCESS) {
			return FAIL;		
		}
	}
	
	if (CPLEXenv != NULL) {
		Status = CPXcloseCPLEX (&CPLEXenv);
		if (Status) {
			FErrorFile() << "Could not close CPLEX environment." << endl;
			FlushErrorFile();
			return FAIL;
		}
	}

	return SUCCESS;
}
int GLPKLoadVariables(MFAVariable* InVariable, bool RelaxIntegerVariables,bool UseTightBounds) {
	if (GLPKModel == NULL) {
		FErrorFile() << "Could not add variable because GLPK object does not exist." << endl;
		FlushErrorFile();
		return FAIL;
	}

	int NumColumns = glp_get_num_cols(GLPKModel);

	if (InVariable->Index >= NumColumns) {
		glp_add_cols(GLPKModel, 1);
		string Name = GetMFAVariableName(InVariable);
		char* Temp = new char[Name.length()+1];
		strcpy(Temp,Name.data());
		glp_set_col_name(GLPKModel,InVariable->Index+1,Temp);
	}


	double LowerBound = InVariable->LowerBound;
	double UpperBound = InVariable->UpperBound;
	if (UseTightBounds) {
		LowerBound = InVariable->Min;
		UpperBound = InVariable->Max;
	}
	if (LowerBound != UpperBound) {
		glp_set_col_bnds(GLPKModel, InVariable->Index+1, GLP_DB, InVariable->LowerBound, InVariable->UpperBound);
	} else {
		glp_set_col_bnds(GLPKModel, InVariable->Index+1, GLP_FX, InVariable->LowerBound, InVariable->UpperBound);
	}

	if (InVariable->Binary && !RelaxIntegerVariables) {
		//glp_set_class(GLPKModel, GLP_MIP); There is no equivalent in the new API
		glp_set_col_kind(GLPKModel, InVariable->Index+1,GLP_IV);
	}

	return SUCCESS;
}
Exemple #9
0
int CPLEXAddConstraint(LinEquation* InEquation) {
	int Status = 0;
	
	if (InEquation->ConstraintType != QUADRATIC && InEquation->ConstraintType != LINEAR) {
		FErrorFile() << "This constraint type is not supported in CPLEX: " << InEquation->ConstraintType << endl;
		FlushErrorFile();
		return FAIL;
	}

	//First I check the number of rows. If it's larger than the index, then this constraint already exists and is only being changed
	int NumberRows = CPXgetnumrows (CPLEXenv, CPLEXModel);
	if (NumberRows <= InEquation->Index) {
		char* Sense = new char[1];
		if (InEquation->EqualityType == EQUAL) {
			if (InEquation->QuadOne.size() > 0) {
				delete [] Sense;
				FErrorFile() << "Quadratic constraints cannot be equivalent constraints in CPLEX." << endl;
				FlushErrorFile();
				return FAIL;
			} else {
				Sense[0] = 'E';
			}
		} else if (InEquation->EqualityType == LESS) {
			Sense[0] = 'L';
		} else if (InEquation->EqualityType == GREATER) {
			Sense[0] = 'G';
		} else {
			delete [] Sense;
			FErrorFile() << "Unrecognized constraint type: " << InEquation->ConstraintType << endl;
			FlushErrorFile();
			return FAIL;
		}

		double* Rhs = new double[1];
		Rhs[0] = InEquation->RightHandSide;
		
		int* ColInd = NULL;
		int* RowInd = NULL;
		double* Coeff = NULL;
		if (InEquation->Variables.size() > 0) {
			ColInd = new int[int(InEquation->Variables.size())];
			RowInd = new int[int(InEquation->Variables.size())];
			Coeff = new double[int(InEquation->Variables.size())];
			for (int i=0; i < int(InEquation->Variables.size()); i++) {
				Coeff[i] = InEquation->Coefficient[i];
				RowInd[i] = 0;
				ColInd[i] = InEquation->Variables[i]->Index;
			}
		}
		
		if (InEquation->QuadOne.size() > 0) {
			if (CPXgetprobtype(CPLEXenv, CPLEXModel) == CPXPROB_LP) {
				Status = CPXchgprobtype(CPLEXenv, CPLEXModel, CPXPROB_QP);
			}
			else if (CPXgetprobtype(CPLEXenv, CPLEXModel) == CPXPROB_MILP) {
				Status = CPXchgprobtype(CPLEXenv, CPLEXModel, CPXPROB_MIQP);
			}
	
			int *QuadCol = new int[int(InEquation->QuadOne.size())];
			int *QuadRow = new int[int(InEquation->QuadTwo.size())];
			double *QuadCoeff = new double[int(InEquation->QuadCoeff.size())];
			for (int i=0; i < int(InEquation->QuadOne.size()); i++) {
				QuadCol[i] = InEquation->QuadOne[i]->Index;
				QuadRow[i] = InEquation->QuadTwo[i]->Index;
				QuadCoeff[i] = InEquation->QuadCoeff[i];
			}

			Status = CPXaddqconstr(CPLEXenv, CPLEXModel, int(InEquation->Variables.size()), int(InEquation->QuadOne.size()), Rhs[0], int(Sense[0]), ColInd, Coeff, QuadRow, QuadCol, QuadCoeff, NULL);

			delete [] QuadCol;
			delete [] QuadRow;
			delete [] QuadCoeff;
		} else if (InEquation->Variables.size() > 0) {	
			string StrName = GetConstraintName(InEquation);
			char** Name = new char*;
			Name[0] = new char[StrName.length()+1];
			strcpy(Name[0],StrName.data());

			if ((InEquation->ConstraintMeaning.compare("chemical potential constraint") == 0) && (InEquation->Loaded == false) && (GetParameter("Check potential constraints feasibility").compare("1") == 0)) {
				Rhs[0] = InEquation->LoadedRightHandSide;
				Sense[0] = 'L';
			} else if ((InEquation->ConstraintMeaning.compare("chemical potential constraint") == 0) && (InEquation->Loaded == false) && (InEquation->RightHandSide > 0.9*FLAG)){
				Rhs[0] = FLAG;
				Sense[0] = 'L';
			}

			Status = CPXaddrows(CPLEXenv, CPLEXModel, 0, 1, int(InEquation->Variables.size()), Rhs, Sense, RowInd, ColInd, Coeff, NULL, Name);
			delete [] Name[0];
			delete [] Name;
			delete [] ColInd;
			delete [] RowInd;
			delete [] Coeff;	
		}
		delete [] Rhs;
		delete [] Sense;

		if (Status) {
			FErrorFile() << "Failed to add constraint: " << InEquation->Index << endl;
			FlushErrorFile();
			return FAIL;
		}
	} else {
		if (InEquation->QuadOne.size() > 0) {
			FErrorFile() << "Cannot change a quadratic constraint." << endl;
			FlushErrorFile();
			return FAIL;
		} else {
			int NumberOfColumns = CPXgetnumcols(CPLEXenv, CPLEXModel);
			//First I reset all of the coefficients to zero
			for (int i=0; i < NumberOfColumns; i++) {
				Status = CPXchgcoef (CPLEXenv, CPLEXModel, InEquation->Index, i, 0);
				if (Status) {
					FErrorFile() << "Failed to change constraint: " << InEquation->Index << endl;
					FlushErrorFile();
					return FAIL;
				}
			}
			//Next I set all of the nonzero coefficients according to the input equation
			for (int i=0; i < int(InEquation->Variables.size()); i++) {
				Status = CPXchgcoef (CPLEXenv, CPLEXModel, InEquation->Index, InEquation->Variables[i]->Index, InEquation->Coefficient[i]);
				if (Status) {
					FErrorFile() << "Failed to change constraint: " << InEquation->Index << endl;
					FlushErrorFile();
					return FAIL;
				}
			}
			
			char* Sense = new char[1];
			
			if (InEquation->ConstraintMeaning.compare("chemical potential constraint") == 0 && InEquation->Loaded == false) {
				Sense[0] = 'L';
				
				Status = CPXchgcoef (CPLEXenv, CPLEXModel, InEquation->Index, -1, InEquation->LoadedRightHandSide);
				Status = CPXchgsense (CPLEXenv, CPLEXModel, 1, &(InEquation->Index), Sense);
				
			} else {
			
				//Now I change the RHS of the constraint
				Status = CPXchgcoef (CPLEXenv, CPLEXModel, InEquation->Index, -1, InEquation->RightHandSide);
	
				//Also change the sense of the constraint if nec
				
				if (InEquation->EqualityType == EQUAL) {
					if (InEquation->QuadOne.size() > 0) {
						delete [] Sense;
						FErrorFile() << "Quadratic constraints cannot be equivalent constraints in CPLEX." << endl;
						FlushErrorFile();
						return FAIL;
					} else {
						Sense[0] = 'E';
					}
				} else if (InEquation->EqualityType == LESS) {
					Sense[0] = 'L';
				} else if (InEquation->EqualityType == GREATER) {
					Sense[0] = 'G';
				} else {
					delete [] Sense;
					FErrorFile() << "Unrecognized constraint type: " << InEquation->ConstraintType << endl;
					FlushErrorFile();
					return FAIL;
				}
	
				Status = CPXchgsense (CPLEXenv, CPLEXModel, 1, &(InEquation->Index), Sense);
				if (Status) {
					FErrorFile() << "Failed to change constraint: " << InEquation->Index << endl;
					FlushErrorFile();
					return FAIL;
				}
			}
		}
	}
	return SUCCESS;
}
Exemple #10
0
int CPLEXLoadObjective(LinEquation* InEquation, bool Max) {
	int NumCols = CPXgetnumcols(CPLEXenv, CPLEXModel);
	int Status = 0;

	if (Max) {
		CPXchgobjsen (CPLEXenv, CPLEXModel, CPX_MAX);
	} else {
		CPXchgobjsen (CPLEXenv, CPLEXModel, CPX_MIN);
	}
	
	int* Indeces = new int[NumCols];
	double* Coeffs = new double[NumCols];

	for (int i=0; i < NumCols; i++) {
		Indeces[i] = i;
		Coeffs[i] = 0;
	}
	for (int i=0; i < int(InEquation->Variables.size()); i++) {
		Coeffs[InEquation->Variables[i]->Index] = InEquation->Coefficient[i];
	}
	
	Status = CPXchgobj(CPLEXenv, CPLEXModel, NumCols, Indeces, Coeffs);
	delete [] Indeces;
	delete [] Coeffs;
	if (Status) {
		cout << "Failed to set objective coefficients. " << endl;
		return FAIL;
	}
	if (InEquation->QuadOne.size() > 0) {
		if (CPXgetprobtype(CPLEXenv, CPLEXModel) == CPXPROB_LP) {
			Status = CPXchgprobtype(CPLEXenv, CPLEXModel, CPXPROB_QP);
		} else if (CPXgetprobtype(CPLEXenv, CPLEXModel) == CPXPROB_MILP) {
			Status = CPXchgprobtype(CPLEXenv, CPLEXModel, CPXPROB_MIQP);
		}
		if (Status) {
			FErrorFile() << "Failed to change problem type." << endl;
			FlushErrorFile();
			return FAIL;
		}
		
		for (int i=0; i < NumCols; i++) {
			for (int j=0; j < NumCols; j++) {
				Status = CPXchgqpcoef(CPLEXenv, CPLEXModel, i, j, 0);
				if (Status) {
					FErrorFile() << "Failed to change quadratic coefficient." << endl;
					FlushErrorFile();
					return FAIL;
				}
			}
		}
		for (int i=0; i < int(InEquation->QuadOne.size()); i++) {
			Status = CPXchgqpcoef(CPLEXenv, CPLEXModel, InEquation->QuadOne[i]->Index, InEquation->QuadTwo[i]->Index, InEquation->QuadCoeff[i]);
			if (Status) {
				FErrorFile() << "Failed to change quadratic coefficient." << endl;
				FlushErrorFile();
				return FAIL;
			}
		}
	}	
	
	return SUCCESS;
}
Exemple #11
0
int CPLEXInitialize() {
	int Status = 0;
	
	//First I open the CPLEX environment if it is not already open
	if (CPLEXenv == NULL) {
		CPLEXenv = CPXopenCPLEX (&Status);
	}
	if (CPLEXenv == NULL || Status) {
		FErrorFile() << "Failed to initialize CPLEX environment. Check license server on aterneus." << endl;
		FlushErrorFile();
		return FAIL;
	}

	//Now I set any environment variables
	Status = CPXsetintparam(CPLEXenv, CPX_PARAM_SCRIND, CPX_ON);
	Status = CPXsetdblparam(CPLEXenv, CPX_PARAM_WORKMEM, 50);
	Status = CPXsetstrparam(CPLEXenv, CPX_PARAM_WORKDIR, FOutputFilepath().data());
	Status = CPXsetintparam(CPLEXenv, CPX_PARAM_NODEFILEIND, 2);
	Status = CPXsetdblparam(CPLEXenv, CPX_PARAM_TRELIM, 50);

	if (Status) {
		FErrorFile() << "Failed to set screen indicators to on." << endl;
		FlushErrorFile();
		return FAIL;
	}

	if (GetParameter("CPLEX solver time limit").length() > 0 && GetParameter("CPLEX solver time limit").compare("none") != 0) { 
		Status = CPXsetdblparam (CPLEXenv, CPX_PARAM_TILIM, atof(GetParameter("CPLEX solver time limit").data()));
		if (Status) {
			FErrorFile() << "Failed to set CPLEX time limit." << endl;
			FlushErrorFile();
			return FAIL;
		}
	}

	//I set the number of processors to run on if allowed to
	
	// SYSTEM_INFO sysinfo;
	// GetSystemInfo( &sysinfo );

	// int numCPU = sysinfo.dwNumberOfProcessors;

	Status = CPXsetintparam(CPLEXenv, CPX_PARAM_THREADS, 1);
	Status = CPXsetintparam(CPLEXenv, CPX_PARAM_PARALLELMODE, 0);
	Status = CPXsetintparam (CPLEXenv, CPX_PARAM_MIPDISPLAY, 0);

	//Next I clear out any models that currently exist
	if (CPLEXClearSolver() != SUCCESS) {
		return FAIL; //error message already printed	
	}

	//Now I create a new CPLEX model
	CPLEXModel = CPXcreateprob (CPLEXenv, &Status, "LPProb");
	Status = CPXchgprobtype(CPLEXenv, CPLEXModel, CPXPROB_LP);
	if (Status || CPLEXModel == NULL) {
		FErrorFile() << "Failed to create new CPLEX model." << endl;
		FlushErrorFile();
		return FAIL;
	}

	return SUCCESS;
}
Exemple #12
0
int CPLEXLoadVariables(MFAVariable* InVariable, bool RelaxIntegerVariables,bool UseTightBounds) {
	int Status = 0;
	
	//First I check the number of columns. If it's larger than the index, then this variable already exists and is only being changed
	int NumberColumns = CPXgetnumcols (CPLEXenv, CPLEXModel);
	if (NumberColumns <= InVariable->Index) {
		string StrName = GetMFAVariableName(InVariable);
		
		double* LB = new double;
		LB[0] = InVariable->LowerBound;
		double* UB = new double;
		UB[0] = InVariable->UpperBound;
		if (UseTightBounds) {
			LB[0] = InVariable->Min;
			UB[0] = InVariable->Max;
		}
		double* Obj = new double;
		Obj[0] = 0;
		char* Temp = new char;
		char** Name = new char*;
		Name[0] = new char[StrName.length()+1];
		strcpy(Name[0],StrName.data());
		
		if (InVariable->Binary && !RelaxIntegerVariables) {
			Temp[0] = CPX_BINARY;
			Status = CPXnewcols (CPLEXenv, CPLEXModel, 1, Obj, LB, UB, Temp, Name);
		} else if (InVariable->Integer && !RelaxIntegerVariables) {
			Temp[0] = CPX_INTEGER;
			Status = CPXnewcols (CPLEXenv, CPLEXModel, 1, Obj, LB, UB, Temp, Name);
		} else {
			Temp[0] = CPX_CONTINUOUS;
			Status = CPXnewcols (CPLEXenv, CPLEXModel, 1, Obj, LB, UB, Temp, Name);
		}

		delete LB;
		delete UB;
		delete Obj;
		delete Temp;
		delete [] Name[0];
		delete Name;

		if (Status ) {
			FErrorFile() << "Could not add variable " << InVariable->Index << endl;
			FlushErrorFile();
			return FAIL;
		}
	} else {
		double* Bounds = new double[2];
		Bounds[0] = InVariable->LowerBound;
		Bounds[1] = InVariable->UpperBound;
		
		int* Indices = new int[2];
		Indices[0] = InVariable->Index;
		Indices[1] = InVariable->Index;

		Status = CPXchgbds (CPLEXenv, CPLEXModel, 2, Indices, "LU", Bounds);
		
		delete [] Bounds;
		delete [] Indices;

		if (Status) {
			FErrorFile() << "Could not change bounds on variable " << InVariable->Index << endl;
			FlushErrorFile();
			return FAIL;
		}
	}

	return SUCCESS;
}
Exemple #13
0
OptSolutionData* CPLEXRunSolver(int ProbType) {
	OptSolutionData* NewSolution = NULL;
	int Status = 0;
	if (ProbType == LP) {
		Status = CPXsetintparam (CPLEXenv, CPX_PARAM_LPMETHOD, CPX_ALG_AUTOMATIC);
		if (Status) {
			FErrorFile() << "Failed to set the optimization method." << endl;
			FlushErrorFile();
			return NULL;
		}
		Status = CPXsetintparam (CPLEXenv, CPX_PARAM_SIMDISPLAY, 0);
		if (Status) {
			FErrorFile() << "Failed to set the optimization method." << endl;
			FlushErrorFile();
			return NULL;
		}
		Status = CPXchgprobtype(CPLEXenv, CPLEXModel, CPXPROB_LP);
		Status = CPXlpopt(CPLEXenv, CPLEXModel);
	} else if(ProbType == MILP || ProbType == MIQP) {
		//Setting the bound tightening on high
		Status = CPXsetintparam (CPLEXenv, CPX_PARAM_BNDSTRENIND, 1);
		if (Status) {
			FErrorFile() << "Failed to set the optimization method." << endl;
			FlushErrorFile();
			return NULL;
		}
		//Setting tolerance to 1e-9 instead of 1e-6
		double tolerance = atof(GetParameter("Solver tolerance").data());
		Status = CPXsetdblparam(CPLEXenv,CPX_PARAM_EPRHS, tolerance);
		if (Status) {
			FErrorFile() << "Failed to set the optimization method." << endl;
			FlushErrorFile();
			return NULL;
		}
		Status = CPXsetdblparam(CPLEXenv,CPX_PARAM_EPINT, tolerance);
		if (Status) {
			FErrorFile() << "Failed to set the optimization method." << endl;
			FlushErrorFile();
			return NULL;
		}
		//Deactivates all messages from MIP solver
		Status = CPXchgprobtype(CPLEXenv, CPLEXModel, CPXPROB_MILP);
		Status = CPXmipopt (CPLEXenv, CPLEXModel);
	} else if(ProbType == QP) {
		Status = CPXqpopt (CPLEXenv, CPLEXModel);
	}
	if (Status ) {
		cout << "Failed to optimize LP." << endl;
		return NULL;
	}
	int Temp = CPXgetstat (CPLEXenv, CPLEXModel);
	NewSolution = new OptSolutionData;
	if (Temp == CPX_STAT_UNBOUNDED) {
		cout << "Model is unbounded" << endl;
		FErrorFile() << "Model is unbounded" << endl;
		FlushErrorFile();
		NewSolution->Status = UNBOUNDED;
		return NewSolution;
	} else if (Temp == CPX_STAT_INFEASIBLE) {
		cout << "Model is infeasible" << endl;
		FErrorFile() << "Model is infeasible" << endl;
		FlushErrorFile();
		NewSolution->Status = INFEASIBLE;
		return NewSolution;
	} else if (Temp == CPX_STAT_INForUNBD ) {
		cout << "Model is infeasible or unbounded" << endl;
		FErrorFile() << "Model is infeasible or unbounded" << endl;
		FlushErrorFile();
		NewSolution->Status = INFEASIBLE;
		return NewSolution;
	} else {
		NewSolution->Status = SUCCESS;
	}

	int NumberColumns = CPXgetnumcols (CPLEXenv, CPLEXModel);
	int NumberRows = CPXgetnumrows (CPLEXenv, CPLEXModel);
	NewSolution->NumVariables = NumberColumns;
	NewSolution->SolutionData.resize(NumberColumns);

	double* x = new double[NumberColumns];
	
	if (ProbType == MILP || ProbType == MIQP) {
		Status = CPXgetmipobjval (CPLEXenv, CPLEXModel, &(NewSolution->Objective));
		Status = CPXgetmipx (CPLEXenv, CPLEXModel, x, 0, NumberColumns-1);
	} else {
		Status = CPXsolution(CPLEXenv,CPLEXModel,NULL,&(NewSolution->Objective),x,NULL,NULL,NULL);
	}
	
	if ( Status ) {
		cout << "Failed to obtain objective value." << endl;
		delete [] x;
		NewSolution->Status = INFEASIBLE;
		return NewSolution;
	}

	cout << "Objective value: " << NewSolution->Objective << endl;
	/*
	string* StrNames = new string[NumberColumns];
	char** Names = new char*[NumberColumns];
	char* NameStore = new char[7*NumberColumns];
	int Surplus = 0;

	Status = CPXgetcolname(CPLEXenv, CPLEXModel, Names, NameStore, 7*NumberColumns, &Surplus, 0, NumberColumns-1);
	if (Status) {
		FErrorFile() << "Failed to get column names." << endl;
		FlushErrorFile();
		delete [] StrNames;
		delete [] Names;
		delete [] NameStore;
		delete [] x;
		delete NewSolution;
		return NULL;
	}
	*/
	for (int i=0; i < NumberColumns; i++) {
		//StrNames[i].assign(Names[i]);
		//StrNames[i] = StrNames[i].substr(1, StrNames[i].length()-1);
		//NewSolution->SolutionData[atoi(StrNames[i].data())-1] = x[i];
		NewSolution->SolutionData[i] = x[i];
	}
	/*
	delete [] StrNames;
	delete [] Names;
	delete [] NameStore;
	*/
	delete [] x;

	return NewSolution;
}
OptSolutionData* GLPKRunSolver(int ProbType) {
	OptSolutionData* NewSolution = NULL;

	int NumVariables = glp_get_num_cols(GLPKModel);

	int Status = 0;
	if (ProbType == MILP) {
		Status = glp_simplex(GLPKModel, NULL); // Use default settings
		if (Status != 0) {
			FErrorFile() << "Failed to optimize problem." << endl;
			FlushErrorFile();
			return NULL;
		}
		Status = glp_intopt(GLPKModel, NULL); // Use default settings
		if (Status != 0) {
			FErrorFile() << "Failed to optimize problem." << endl;
			FlushErrorFile();
			return NULL;
		}
		NewSolution = new OptSolutionData;

		Status = glp_mip_status(GLPKModel);
		if (Status == GLP_UNDEF || Status == GLP_NOFEAS) {
			NewSolution->Status = INFEASIBLE;
			return NewSolution;
		} else if (Status == GLP_FEAS) {
			NewSolution->Status = UNBOUNDED;
			return NewSolution;
		} else if (Status == GLP_OPT) {
			NewSolution->Status = SUCCESS;
		} else {
			delete NewSolution;
			FErrorFile() << "Problem status unrecognized." << endl;
			FlushErrorFile();
			return NULL;
		}

		NewSolution->Objective = glp_mip_obj_val(GLPKModel);
	
		NewSolution->SolutionData.resize(NumVariables);
		for (int i=0; i < NumVariables; i++) {
			NewSolution->SolutionData[i] = glp_mip_col_val(GLPKModel, i+1);
		}
	} else if (ProbType == LP) {
		//First we check the basis matrix to ensure it is not singular
		if (glp_warm_up(GLPKModel) != 0) {
			glp_adv_basis(GLPKModel, 0);
		}
		Status = glp_simplex(GLPKModel, NULL); // Use default settings
		if (Status == GLP_EBADB) {  /* the basis is invalid; build some valid basis */
			glp_adv_basis(GLPKModel, 0);
			Status = glp_simplex(GLPKModel, NULL); // Use default settings
		}
		if (Status != 0) {
			FErrorFile() << "Failed to optimize problem." << endl;
			FlushErrorFile();
			return NULL;
		}
		NewSolution = new OptSolutionData;

		Status = glp_get_status(GLPKModel);
		if (Status == GLP_INFEAS || Status == GLP_NOFEAS || Status == GLP_UNDEF) {
			cout << "Model is infeasible" << endl;
			FErrorFile() << "Model is infeasible" << endl;
			FlushErrorFile();
			NewSolution->Status = INFEASIBLE;
			return NewSolution;
		} else if (Status == GLP_FEAS || Status == GLP_UNBND) {
			cout << "Model is unbounded" << endl;
			FErrorFile() << "Model is unbounded" << endl;
			FlushErrorFile();
			NewSolution->Status = UNBOUNDED;
			return NewSolution;
		} else if (Status == GLP_OPT) {
			NewSolution->Status = SUCCESS;
		} else {
			delete NewSolution;
			FErrorFile() << "Problem status unrecognized." << endl;
			FlushErrorFile();
			return NULL;
		}

		NewSolution->Objective = glp_get_obj_val(GLPKModel);
	
		NewSolution->SolutionData.resize(NumVariables);
		for (int i=0; i < NumVariables; i++) {
			NewSolution->SolutionData[i] = glp_get_col_prim(GLPKModel, i+1);
		}
	} else {
		FErrorFile() << "Optimization problem type cannot be handled by GLPK solver." << endl;
		FlushErrorFile();
		return NULL;
	}

	return NewSolution;
}
void CommandlineInterface(vector<string> Arguments) {
	bool InputArgument = false;	
	vector<string> ParameterFiles;
	for (int i=0; i < int(Arguments.size()); i++) {
		if (Arguments[i].compare("inputfilelist") == 0) {
			if (int(Arguments.size()) >= i+2) {
				InputArgument = true;
				SetInputParametersFile(Arguments[i+1].data());
			}
		} if (Arguments[i].compare("parameterfile") == 0) {
			if (int(Arguments.size()) >= i+2) {
				ParameterFiles.push_back(Arguments[i+1].data());
				i++;
			}
		} 
	}
	if (!InputArgument) {
		SetInputParametersFile(COMMANDLINE_INPUT_FILE);
	}
	LoadParameters();
	for(int i=0; i < int(ParameterFiles.size()); i++) {
		LoadParameterFile(ParameterFiles[i]);
	}
	for (int i=0; i < int(Arguments.size()); i++) {
		if (Arguments[i].compare("resetparameter") == 0) {
			if (int(Arguments.size()) >= i+3) {
				string ParameterName = Arguments[i+1];
				findandreplace(ParameterName,"_"," ");
				SetParameter(ParameterName.data(),Arguments[i+2].data());		
			}
		} 
	}
	ClearParameterDependance("CLEAR ALL PARAMETER DEPENDANCE");
	if (Initialize() != SUCCESS) {
		return;
	}
	LoadFIGMODELParameters();
	ClearParameterDependance("CLEAR ALL PARAMETER DEPENDANCE");
	for (int i=0; i < int(Arguments.size()); i++) {
		if (Arguments[i].compare("stringcode") == 0) {
			if (int(Arguments.size()) < i+3) {
				cout << "Insufficient arguments" << endl;
				FErrorFile() << "Insufficient arguments" << endl;
				FlushErrorFile();
			} else {
				CreateStringCode(Arguments[i+1],Arguments[i+2]);
				i += 2;
			}
		} else if (Arguments[i].compare("LoadCentralSystem") == 0 || Arguments[i].compare("LoadDecentralSystem") == 0) {
			if (int(Arguments.size()) < i+2) {
				cout << "Insufficient arguments" << endl;
				FErrorFile() << "Insufficient arguments" << endl;
				FlushErrorFile();
			} else {
				LoadDatabaseFile(Arguments[i+1].data());		
			}
		} else if (Arguments[i].compare("ProcessDatabase") == 0) {
			ProcessDatabase();
		} else if (Arguments[i].compare("metabolites") == 0) {
			if (int(Arguments.size()) < i+2) {
				cout << "Insufficient arguments" << endl;
				FErrorFile() << "Insufficient arguments" << endl;
				FlushErrorFile();
			} else {
				SetParameter("metabolites to optimize",Arguments[i+1].data());		
			}
		} else if (Arguments[i].compare("WebGCM") == 0) {
			if (int(Arguments.size()) < i+3) {
				cout << "Insufficient arguments" << endl;
				FErrorFile() << "Insufficient arguments" << endl;
				FlushErrorFile();
			} else {
				RunWebGCM(Arguments[i+1].data(),Arguments[i+2].data());		
			}
		} else if (Arguments[i].compare("ProcessMolfiles") == 0) {
			if (int(Arguments.size()) < i+3) {
				cout << "Insufficient arguments" << endl;
				FErrorFile() << "Insufficient arguments" << endl;
				FlushErrorFile();
			} else {
				ProcessMolfileDirectory(Arguments[i+1].data(),Arguments[i+2].data());		
			}
		} else if (Arguments[i].compare("ProcessMolfileList") == 0) {
			ProcessMolfiles();
		}
	}
}
void LoadDatabaseFile(const char* DatabaseFilename) {
	if (GetParameter("Network output location").compare("none") != 0 && GetParameter("Network output location").length() > 0) {
		if (GetParameter("os").compare("windows") == 0) {
			system(("move "+GetDatabaseDirectory(GetParameter("database"),"output directory")+GetParameter("output folder")+" "+GetParameter("Network output location")).data());
		} else {
			system(("cp -r "+GetDatabaseDirectory(GetParameter("database"),"output directory")+GetParameter("output folder")+" "+GetParameter("Network output location")).data());
		}
	}
	
	//Getting filename that all compound and reaction data will be saved into
	string Filename(DatabaseFilename);	
	if (Filename.length() == 0) {
		Filename = AskString("Input filename for database: ");
	}
	
	//Creating datastructure for all program data
	Data* NewData = new Data(0);
	NewData->ClearData("NAME",STRING);
	NewData->AddData("NAME",RemoveExtension(RemovePath(Filename)).data(),STRING);

	//Loading data from file
	if (NewData->LoadSystem(Filename) == FAIL) {
		delete NewData;
		return;
	}
	//Performing a variety of tasks according to the parameters in the parameters files including KEGG lookup, reaction and compound printing etc.
	NewData->PerformAllRequestedTasks();
	// Test for Adjustment of DeltaGs for PH for COMPOUNDS
	bool TestCpds = 0;

	if (TestCpds){

		double IonicS = 0.25;
		FErrorFile() << "Std Transformed Gibbs Energy of Formation vs pH" << endl;
		
		for (int i=0; i < NewData->FNumSpecies(); i++){
			
			string CompoundID = NewData->GetSpecies(i)->GetData("DATABASE",STRING); // gets the cpdID
			string Name = NewData->GetSpecies(i)->GetData("NAME",STRING); // gets the name of the cpd

			Species* Temp = NewData->FindSpecies("DATABASE",CompoundID.data());
			
			//if (CompoundID.compare("cpd00003") == 0 || CompoundID.compare("cpd00004") == 0 || CompoundID.compare("cpd00002") == 0) {
			double AdjDeltaG5 = Temp->AdjustedDeltaG(IonicS,5,298.15);
			double AdjDeltaG5_kJ = 4.184*AdjDeltaG5;

			double AdjDeltaG6 = Temp->AdjustedDeltaG(IonicS,6,298.15);
			double AdjDeltaG6_kJ = 4.184*AdjDeltaG6;

			double AdjDeltaG7 = Temp->AdjustedDeltaG(IonicS,7,298.15);
			double AdjDeltaG7_kJ = 4.184*AdjDeltaG7;

			double AdjDeltaG8 = Temp->AdjustedDeltaG(IonicS,8,298.15);
			double AdjDeltaG8_kJ = 4.184*AdjDeltaG8;

			double AdjDeltaG9 = Temp->AdjustedDeltaG(IonicS,9,298.15);
			double AdjDeltaG9_kJ = 4.184*AdjDeltaG9;

			FErrorFile() << CompoundID << "\t" << AdjDeltaG5_kJ << "\t" << AdjDeltaG6_kJ << "\t" << AdjDeltaG7_kJ << "\t" << AdjDeltaG8_kJ << "\t" << AdjDeltaG9_kJ << endl;
			//}
		}

		FlushErrorFile();
	}
	// Test for Adjustment of DeltaGs for IONIC STRENGTH for COMPOUNDS
	bool TestCpdsIS = 0;

	if (TestCpdsIS){
	
		FErrorFile() << "Std Transformed Gibbs Energy of Formation vs Ionic Strength" << endl;

		for (int i=0; i < NewData->FNumSpecies(); i++){

			string CompoundID = NewData->GetSpecies(i)->GetData("DATABASE",STRING); // gets the cpdID
			string Name = NewData->GetSpecies(i)->GetData("NAME",STRING); // gets the name of the cpd

			Species* Temp = NewData->FindSpecies("DATABASE",CompoundID.data());

			double AdjDeltaG_IS0 = Temp->AdjustedDeltaG(0,7,298.15);
			double AdjDeltaG_IS0_kJ = 4.184*AdjDeltaG_IS0;

			double AdjDeltaG_IS10 = Temp->AdjustedDeltaG(0.1,7,298.15);
			double AdjDeltaG_IS10_kJ = 4.184*AdjDeltaG_IS10;

			double AdjDeltaG_IS25 = Temp->AdjustedDeltaG(0.25,7,298.15);
			double AdjDeltaG_IS25_kJ = 4.184*AdjDeltaG_IS25;

			FErrorFile() << CompoundID << "\t" << AdjDeltaG_IS0_kJ << "\t" << AdjDeltaG_IS10_kJ << "\t" << AdjDeltaG_IS25_kJ << endl;
		
		}

		FlushErrorFile();
	}
	// Test for Adjustment of DeltaGs for pH for REACTIONS
	bool TestRxns = 0;

	if (TestRxns){
		
		double IonicS = 0.25;
		//double pH = 7;
		FErrorFile() << "Std Transformed Gibbs Energy of Reaction (kJmol-1) vs pH" << endl;

		for (int i=0; i < NewData->FNumReactions(); i++){
			Reaction* Rxn = NewData->GetReaction(i);
			string RxnID = Rxn->GetData("DATABASE",STRING);
			string Name = Rxn->GetData("NAME",STRING);
		
			double DG5 = Rxn->FEstDeltaG(5,IonicS)*4.184;
			double DG6 = Rxn->FEstDeltaG(6,IonicS)*4.184;
			double DG7 = Rxn->FEstDeltaG(7,IonicS)*4.184;
			double DG8 = Rxn->FEstDeltaG(8,IonicS)*4.184;
			double DG9 = Rxn->FEstDeltaG(9,IonicS)*4.184;
			
			FErrorFile() << RxnID << "\t" << DG5 << "\t" << DG6 << "\t" << DG7 << "\t" << DG8 << "\t" << DG9 << endl;
		}
		FlushErrorFile();
	}
	// Test for Adjustment of DeltaGs for IONIC STRENGTH for REACTIONS
	bool TestRxnsIS = 0;

	if (TestRxnsIS){
		
		FErrorFile() << "Std Transformed Gibbs Energy of Reaction (kJmol-1) vs Ionic Strength" << endl;
		
		for (int i=0; i < NewData->FNumReactions(); i++){
			Reaction* Rxn = NewData->GetReaction(i);
			string RxnID = Rxn->GetData("DATABASE",STRING);
			string Name = Rxn->GetData("NAME",STRING);
			
			double DG_IS0 = Rxn->FEstDeltaG(7,0.25)*4.184;
			double DG_IS10 = Rxn->FEstDeltaG(7,0.15)*4.184;
			double DG_IS25 = Rxn->FEstDeltaG(7,0.25)*4.184;
			
			FErrorFile() << RxnID << "\t" << DG_IS0 << "\t" << DG_IS10 << "\t" << DG_IS25 << endl;

		}
		// FlushErrorFile();
	}
	delete NewData;
};