/* Copyright 2025, Gurobi Optimization, LLC *//* This example reads a MIP model from a file, adds artificial variables to each constraint, and then minimizes the sum of the artificial variables. A solution with objective zero corresponds to a feasible solution to the input model. We can also use FeasRelax feature to do it. In this example, we use minrelax=1, i.e. optimizing the returned model finds a solution that minimizes the original objective, but only from among those solutions that minimize the sum of the artificial variables. */#include<stdlib.h>#include<stdio.h>#include<math.h>#include<string.h>#include"gurobi_c.h"intmain(intargc,char*argv[]){GRBenv*env=NULL;GRBmodel*model=NULL;GRBmodel*feasmodel=NULL;double*rhspen=NULL;interror=0;inti,j;intnumvars,numconstrs;charsense;intvind[1];doublevval[1];doublefeasobj;char*cname,*vname;if(argc<2){fprintf(stderr,"Usage: feasopt_c filename\n");exit(1);}error=GRBloadenv(&env,"feasopt.log");if(error)gotoQUIT;error=GRBreadmodel(env,argv[1],&model);if(error)gotoQUIT;/* Create a copy to use FeasRelax feature later */feasmodel=GRBcopymodel(model);if(error)gotoQUIT;/* clear objective */error=GRBgetintattr(model,"NumVars",&numvars);if(error)gotoQUIT;for(j=0;j<numvars;++j){error=GRBsetdblattrelement(model,"Obj",j,0.0);if(error)gotoQUIT;}/* add slack variables */error=GRBgetintattr(model,"NumConstrs",&numconstrs);if(error)gotoQUIT;for(i=0;i<numconstrs;++i){error=GRBgetcharattrelement(model,"Sense",i,&sense);if(error)gotoQUIT;if(sense!='>'){error=GRBgetstrattrelement(model,"ConstrName",i,&cname);if(error)gotoQUIT;vname=malloc(sizeof(char)*(6+strlen(cname)));if(!vname)gotoQUIT;strcpy(vname,"ArtN_");strcat(vname,cname);vind[0]=i;vval[0]=-1.0;error=GRBaddvar(model,1,vind,vval,1.0,0.0,GRB_INFINITY,GRB_CONTINUOUS,vname);if(error)gotoQUIT;free(vname);}if(sense!='<'){error=GRBgetstrattrelement(model,"ConstrName",i,&cname);if(error)gotoQUIT;vname=malloc(sizeof(char)*(6+strlen(cname)));if(!vname)gotoQUIT;strcpy(vname,"ArtP_");strcat(vname,cname);vind[0]=i;vval[0]=1.0;error=GRBaddvar(model,1,vind,vval,1.0,0.0,GRB_INFINITY,GRB_CONTINUOUS,vname);if(error)gotoQUIT;free(vname);}}/* Optimize modified model */error=GRBoptimize(model);if(error)gotoQUIT;error=GRBwrite(model,"feasopt.lp");if(error)gotoQUIT;/* Use FeasRelax feature */rhspen=(double*)malloc(numconstrs*sizeof(double));if(rhspen==NULL){printf("ERROR: out of memory\n");gotoQUIT;}/* set penalties for artificial variables */for(i=0;i<numconstrs;i++)rhspen[i]=1;/* create a FeasRelax model with the original objective recovered and enforcement on minimum of aretificial variables */error=GRBfeasrelax(feasmodel,GRB_FEASRELAX_LINEAR,1,NULL,NULL,rhspen,&feasobj);if(error)gotoQUIT;/* optimize FeasRelax model */error=GRBwrite(feasmodel,"feasopt1.lp");if(error)gotoQUIT;error=GRBoptimize(feasmodel);if(error)gotoQUIT;QUIT:/* Error reporting */if(error){printf("ERROR: %s\n",GRBgeterrormsg(env));exit(1);}/* Free models, env and etc. */if(rhspen)free(rhspen);GRBfreemodel(model);GRBfreemodel(feasmodel);GRBfreeenv(env);return0;}