Apply a primal heuristic to a knapsack problem
|
|
Type: | Knapsack problem |
Rating: | 3 |
Description: | The program demonstrates the use of the global log callback. We take the knapsack problem stored in burglar.mat and instigate a global search. At each node, so long as the current solution is both LP optimal and integer infeasible, we truncate the solution values to create a feasible integer solution. We then update the cutoff, if the new objective value has improved it, and continue the search. |
File(s): | Knapsack.cs |
Data file(s): | burglar.mat |
|
Knapsack.cs |
using System; using Optimizer; namespace XPRSExamples { class Knapsack { public static void Main(string[] args) { Knapsack example = new Knapsack(); example.Run(); } private void Run() { string sLogFile = "knapsack.log"; string sProblem = @"..\..\..\Data\burglar"; try { // initialise optimizer XPRS.Init(""); Console.WriteLine(XPRS.GetBanner()); prob = new XPRSprob(); // define log file 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(prob.Version); //Turn off presolve and disallow cuts - to slow solution and allow the // effect of the heuristic to be seen prob.Presolve = 0; prob.CutStrategy = 0; // Read the problem file prob.MPSFormat = -1; prob.ReadProb(sProblem,""); // Prepare to apply the heuristic // Get the number of columns gnCol = prob.Cols; // Allocate memory to the coefficient and solution arrays gpObjCoef = new double[gnCol]; x = new double[gnCol]; // Get the objective function coefficients prob.GetObj(gpObjCoef, 0,gnCol-1); // Get integer feasibility tolerance gdIntTol = prob.MIPTol; // Tell Optimizer to print global information to the log file at each node prob.MIPLog = 3; // Tell Optimizer to call truncsol at each node and apply the heuristic prob.GloballogCallbacks += new GloballogCallback(this.TruncSol); // Perform the global search - in the course of which the heuristic will // be applied Console.WriteLine("Applying a primal heuristic to problem {0}",sProblem); prob.MipOptimize(); } 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) { Console.WriteLine ("{0}" + message, data); } public int TruncSol(XPRSprob prob, object data) { int nNodeNum; // Number of nodes solved double dObjVal; // Objective value double dCutoff; // Cutoff value LPStatus nLPStatus; // LP solution status int nIntInf; // Number of integer infeasibilities int i; // Loop counter double dHeurObj; // Objective value after the solution values have been truncated string [] sLPStatus = { "Optimal","Infeasible","Objective worse than cutoff", "Unfinished","Unbounded","Cutoff in dual" }; // Get the current node number nNodeNum = prob.Nodes; // Get objective value at the current node dObjVal = prob.LPObjVal; // Get the current cutoff value dCutoff = prob.MIPAbsCutoff; // Get LP solution status and the number of integer infeasibilities nLPStatus = prob.LPStatus; nIntInf = prob.MIPInfeas; // Apply heuristic if nodal solution is LP optimal and integer infeasible if (nLPStatus == LPStatus.Optimal && nIntInf>0) { // Get LP solution prob.GetSol(x,null,null,null); // Truncate each solution value - making allowance for the integer // tolerance - and calculate the new "heuristic" objective value for (dHeurObj=0, i=0; i |