/* Copyright: Copyright (c) MOSEK ApS, Denmark. All rights reserved. File: lo2.cs Purpose: Demonstrates how to solve small linear optimization problem using the MOSEK C# API. */ using System; namespace mosek.example { class msgclass : mosek.Stream { string prefix; public msgclass (string prfx) { prefix = prfx; } public override void streamCB (string msg) { Console.Write ("{0}{1}", prefix, msg); } } public class lo2 { public static void Main () { const int numcon = 3; const int numvar = 4; // Since the value infinity is never used, we define // 'infinity' symbolic purposes only double infinity = 0; double[] c = {3.0, 1.0, 5.0, 1.0}; int[][] asub = { new int[] {0, 1, 2}, new int[] {0, 1, 2, 3}, new int[] {1, 3} }; double[][] aval = { new double[] {3.0, 1.0, 2.0}, new double[] {2.0, 1.0, 3.0, 1.0}, new double[] {2.0, 3.0} }; mosek.boundkey[] bkc = {mosek.boundkey.fx, mosek.boundkey.lo, mosek.boundkey.up }; double[] blc = {30.0, 15.0, -infinity }; double[] buc = {30.0, +infinity, 25.0 }; mosek.boundkey[] bkx = {mosek.boundkey.lo, mosek.boundkey.ra, mosek.boundkey.lo, mosek.boundkey.lo }; double[] blx = {0.0, 0.0, 0.0, 0.0 }; double[] bux = { +infinity, 10.0, +infinity, +infinity }; mosek.Task task = null; mosek.Env env = null; double[] xx = new double[numvar]; try { // Make mosek environment. env = new mosek.Env (); // Create a task object linked with the environment env. task = new mosek.Task (env, 0, 0); // Directs the log task stream to the user specified // method task_msg_obj.streamCB task.set_Stream (mosek.streamtype.log, new msgclass ("")); /* Give MOSEK an estimate of the size of the input data. This is done to increase the speed of inputting data. However, it is optional. */ /* Append 'numcon' empty constraints. The constraints will initially have no bounds. */ task.appendcons(numcon); /* Append 'numvar' variables. The variables will initially be fixed at zero (x=0). */ task.appendvars(numvar); /* Optionally add a constant term to the objective. */ task.putcfix(0.0); for (int j = 0; j < numvar; ++j) { /* Set the linear term c_j in the objective.*/ task.putcj(j, c[j]); /* Set the bounds on variable j. blx[j] <= x_j <= bux[j] */ task.putvarbound(j, bkx[j], blx[j], bux[j]); } /* Set the bounds on constraints. for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */ for (int i = 0; i < numcon; ++i) { task.putconbound(i, bkc[i], blc[i], buc[i]); /* Input row i of A */ task.putarow(i, /* Row index.*/ asub[i], /* Column indexes of non-zeros in row i.*/ aval[i]); /* Non-zero Values of row i. */ } task.putobjsense(mosek.objsense.maximize); task.optimize(); // Print a summary containing information // about the solution for debugging purposes task.solutionsummary(mosek.streamtype.msg); mosek.solsta solsta; /* Get status information about the solution */ task.getsolsta(mosek.soltype.bas, out solsta); task.getxx(mosek.soltype.bas, // Basic solution. xx); switch (solsta) { case mosek.solsta.optimal: Console.WriteLine ("Optimal primal solution\n"); for (int j = 0; j < numvar; ++j) Console.WriteLine ("x[{0}]: {1}", j, xx[j]); break; case mosek.solsta.dual_infeas_cer: case mosek.solsta.prim_infeas_cer: Console.WriteLine("Primal or dual infeasibility.\n"); break; case mosek.solsta.unknown: Console.WriteLine("Unknown solution status.\n"); break; default: Console.WriteLine("Other solution status"); break; } } catch (mosek.Exception e) { Console.WriteLine (e.Code); Console.WriteLine (e); throw; } finally { if (task != null) task.Dispose (); if (env != null) env.Dispose (); } } } }