Apply a binary fixing heuristic to an unpresolved MIP problem
|  | |
| Type: | Programming | 
| Rating: | 4 (medium-difficult) | 
| Description: | We take a production plan model and solve its LP relaxation. This heuristic will speed up solution - though may fail to optimse the problem. The results are displayed on screen and the problem statistics stored in a log file. | 
| File(s): | FixBV.cs | 
|  | |
| FixBV.cs | 
| using System;
using System.IO;
using Optimizer;
namespace XPRSExamples
{
	class FixBV
	{
		public static void Main(string[] args)
		{
			FixBV example = new FixBV();
			example.Run();
		}
		private const double TOL=0.0005;            // Tolerance on binary variables
		private void Run()
		{	
			try
			{
				string sProblem=@"..\..\..\Data\coco";      // Problem name
				string sLogFile="fixbv.log"; // Log file name
				int nCol;                    // Number of columns
				// Global problem information
				int nGlEnt;                  // Number of global entities: binary, integer, semi-continuous and partial integer variables
				int nSet;                    // Number of S1 and S2 sets
				int[] pGlInd;                 // Column indices of the global entities
				char[] pGlType;               // Global entity types
				// Bound changes
				int[] pBndInd;                // Column indices of the bounds to be changed
				char[] pBndType;              // New bound type
				double[] pBndVal;             // New bound values
				int nBnd;                    // Bound counter
				int i;                       // Loop counter
				int j;                       // Holder for the bound indices
				// Solution information
				double[] x;                  // LP solution values
				int nGlStatus;               // Global status
				int nNodes;                  // Number of nodes solved so far in the global search
				double dObjVal;              // Objective value of the best integer solution
				// Initialise Optimizer
				XPRS.Init("");
				Console.Write(XPRS.GetBanner());
				prob = new XPRSprob();
				// Delete and define log file
				// Delete the file if it exists.
				if (File.Exists(sLogFile)) 
				{
					File.Delete(sLogFile);
				}
				prob.SetLogFile(sLogFile);
				// Tell Optimizer to call optimizermsg whenever a message is output 
				prob.MessageCallbacks += new MessageCallback(this.OptimizerMsg);
				// Get and display the Optimizer version number
				Console.WriteLine("\nXpress Optimiser Subroutine Library Release {0}\n\n", prob.Version/100);
				// Turn off presolve and permit no cuts - to slow down solution and allow
				// the effect of the heuristic to be be seen
				prob.Presolve = 0;
				prob.CutStrategy = 0;
				// Read the problem file
        prob.MPSFormat = -1;
				prob.ReadProb(sProblem,"");
				// Solve the LP relaxation
				// Get the number of columns
				nCol = prob.Cols;
				// Allocate memory for solution array and check for memory shortage
				x= new double[nCol];
				
				// Solve the LP
				prob.Maxim("");
		
				// Get LP solution values
				prob.GetSol(x,null,null,null);
				// Fix the binary variables that are at their bounds
				// Allocate memory for global entity arrays
				pGlInd = new int[nCol];
				pGlType = new char[nCol];
				// Get global entity information
				prob.GetGlobal(out nGlEnt, out nSet, pGlType, pGlInd, null, null, (int[])null, null, null);
				// Allocate memory for bound arrays 
				pBndInd = new int[nGlEnt];
				pBndVal = new double[nGlEnt];
				pBndType = new char[nGlEnt];
				// Initialise bound counter
				nBnd=0;
				// Go through the global entities
				for(i=0; i<nGlEnt; i++) 
				{
					// Test whether each is a binary variable
					if (pGlType[i] == 'B') 
					{
						// Hold the index of the BV
						j=pGlInd[i];
						// If the value of the BV is within TOL of zero, store its index,
						//   set its upper bound to 0, and increment the bound counter
						if (x[j]<=TOL) 
						{
							pBndInd[nBnd]=j;
							pBndType[nBnd]='U';
							pBndVal[nBnd]=0.0;
							nBnd++;
							// If the value of the BV is within TOL of one,store its index,
							//   set its lower bound to 1, and increment the bound counter
						} 
						else if ((1-x[j])<=TOL) 
						{
							pBndInd[nBnd]=j;
							pBndType[nBnd]='L';
							pBndVal[nBnd]=1.0;
							nBnd++;
						}
					}
				}
				// Instruct Optimizer to change the bounds of the appropriate BVs,
				//   and tell the user how many have been fixed
				prob.ChgBounds(nBnd,pBndInd,pBndType,pBndVal);
				Console.WriteLine("Solving problem {0} with a binary fixing heuristic:\n\n",sProblem);
				Console.WriteLine("   After the LP optimisation {0} binary variables were fixed\n\n",nBnd);
				// Solve the modified problem as a MIP 
				// Search for an integer solution
				prob.Global();
				// Get the number of nodes solved in the global search
				nNodes = prob.Nodes;
				// Get the objective value of the best integer solution
				dObjVal = prob.MIPObjVal;
				// Check the global status and display the results of the global search
				nGlStatus = (int)prob.MIPStatus;
				switch (nGlStatus) 
				{
					case 0:
						Console.WriteLine("   Problem has not been loaded");
						break;
					case 1:
						Console.WriteLine("   Search has not begun - LP has not been optimised");
						break;
					case 2:
						Console.WriteLine("   Search has not begun - LP has been optimised");
						break;
					case 3:
						Console.WriteLine("   Search interrupted - No integer solution was found");
						break;
					case 4:
						Console.WriteLine("   Search interrupted - Integer solution found: %g",dObjVal);
						break;
					case 5:
						Console.WriteLine("   No integer solution was found");
						break;
					case 6:
						Console.WriteLine("   Integer solution found: {0}",dObjVal);
						break;
				}
				Console.WriteLine("\n\n   The MIP optimisation took {0} nodes\n\n",nNodes);
			}
			catch (XPRSException e)
			{
				Console.WriteLine(e.ToString());
        throw e;
			}
			finally
			{
				prob.Destroy();
				XPRS.Free();
			}
		}
		public void OptimizerMsg (XPRSprob prob, object data, string message, int len, int msglvl)
		{
			switch(msglvl)
			{
				case 3:
				case 4:
					Console.WriteLine ("{0}" + message, data);
					break;
			}
		}
		private XPRSprob prob;
	}
}
 | 
 
