Filter Content By
Version

### fixanddive_cs.cs

/* Copyright 2016, Gurobi Optimization, Inc. */

/* Implement a simple MIP heuristic.  Relax the model,
sort variables based on fractionality, and fix the 25% of
the fractional variables that are closest to integer variables.
Repeat until either the relaxation is integer feasible or
linearly infeasible. */

using System;
using System.Collections.Generic;
using Gurobi;

class fixanddive_cs
{
// Comparison class used to sort variable list based on relaxation
// fractionality

class FractionalCompare : IComparer<GRBVar>
{
public int Compare(GRBVar v1, GRBVar v2)
{
try {
double sol1 = Math.Abs(v1.X);
double sol2 = Math.Abs(v2.X);
double frac1 = Math.Abs(sol1 - Math.Floor(sol1 + 0.5));
double frac2 = Math.Abs(sol2 - Math.Floor(sol2 + 0.5));
if (frac1 < frac2) {
return -1;
} else if (frac1 > frac2) {
return 1;
} else {
return 0;
}
} catch (GRBException e) {
Console.WriteLine("Error code: " + e.ErrorCode + ". " +
e.Message);
}
return 0;
}
}

static void Main(string[] args)
{
if (args.Length < 1) {
Console.Out.WriteLine("Usage: fixanddive_cs filename");
return;
}

try {
GRBEnv env = new GRBEnv();
GRBModel model = new GRBModel(env, args[0]);

// Collect integer variables and relax them
List<GRBVar> intvars = new List<GRBVar>();
foreach (GRBVar v in model.GetVars()) {
if (v.VType != GRB.CONTINUOUS) {
v.VType = GRB.CONTINUOUS;
}
}

model.Parameters.OutputFlag = 0;
model.Optimize();

// Perform multiple iterations. In each iteration, identify the first
// quartile of integer variables that are closest to an integer value
// in the relaxation, fix them to the nearest integer, and repeat.

for (int iter = 0; iter < 1000; ++iter) {

// create a list of fractional variables, sorted in order of
// increasing distance from the relaxation solution to the nearest
// integer value

List<GRBVar> fractional = new List<GRBVar>();
foreach (GRBVar v in intvars) {
double sol = Math.Abs(v.X);
if (Math.Abs(sol - Math.Floor(sol + 0.5)) > 1e-5) {
}
}

Console.WriteLine("Iteration " + iter + ", obj " +
model.ObjVal + ", fractional " + fractional.Count);

if (fractional.Count == 0) {
Console.WriteLine("Found feasible solution - objective " +
model.ObjVal);
break;
}

// Fix the first quartile to the nearest integer value

fractional.Sort(new FractionalCompare());
int nfix = Math.Max(fractional.Count / 4, 1);
for (int i = 0; i < nfix; ++i) {
GRBVar v = fractional[i];
double fixval = Math.Floor(v.X + 0.5);
v.LB = fixval;
v.UB = fixval;
Console.WriteLine("  Fix " + v.VarName +
" to " + fixval + " ( rel " + v.X + " )");
}

model.Optimize();

// Check optimization result

if (model.Status != GRB.Status.OPTIMAL) {
Console.WriteLine("Relaxation is infeasible");
break;
}
}

// Dispose of model and env
model.Dispose();
env.Dispose();

} catch (GRBException e) {
Console.WriteLine("Error code: " + e.ErrorCode + ". " +
e.Message);
}
}
}