예제 #1
0
    // Print out the objective function.
    // Note that the quadratic expression in the objective
    // is normalized: i.E., for all i != j, terms
    // c(i,j)*x[i]*x[j] + c(j,i)*x[j]*x[i] is normalized as
    // (c(i,j) + c(j,i)) * x[i]*x[j], or
    // (c(i,j) + c(j,i)) * x[j]*x[i].
    internal static void PrintObjective(IObjective obj)
    {
        System.Console.WriteLine("obj: " + obj);

        // Count the number of linear terms
        // in the objective function.
        int nlinterms = 0;
        ILinearNumExprEnumerator len = ((ILQNumExpr)obj.Expr).GetLinearEnumerator();

        while (len.MoveNext())
        {
            ++nlinterms;
        }

        // Count the number of quadratic terms
        // in the objective function.
        int nquadterms             = 0;
        int nquaddiag              = 0;
        IQuadNumExprEnumerator qen = ((ILQNumExpr)obj.Expr).GetQuadEnumerator();

        while (qen.MoveNext())
        {
            ++nquadterms;
            INumVar var1 = qen.GetNumVar1();
            INumVar var2 = qen.GetNumVar2();
            if (var1.Equals(var2))
            {
                ++nquaddiag;
            }
        }

        System.Console.WriteLine("number of linear terms in the objective             : " + nlinterms);
        System.Console.WriteLine("number of quadratic terms in the objective          : " + nquadterms);
        System.Console.WriteLine("number of diagonal quadratic terms in the objective : " + nquaddiag);
        System.Console.WriteLine();
    }
예제 #2
0
        // This method separates Benders' cuts violated by the current x solution.
        // Violated cuts are found by solving the worker LP
        //
        public IRange Separate(double[][] xSol, IIntVar[][] x)
        {
            int i, j, k;

            IRange cut = null;

            // Update the objective function in the worker LP:
            // minimize sum(k in V0) sum((i,j) in A) x(i,j) * v(k,i,j)
            //          - sum(k in V0) u(k,0) + sum(k in V0) u(k,k)

            ILinearNumExpr objExpr = cplex.LinearNumExpr();

            for (k = 1; k < numNodes; ++k)
            {
                for (i = 0; i < numNodes; ++i)
                {
                    for (j = 0; j < numNodes; ++j)
                    {
                        objExpr.AddTerm(v[k - 1][i][j], xSol[i][j]);
                    }
                }
            }
            for (k = 1; k < numNodes; ++k)
            {
                objExpr.AddTerm(u[k - 1][k], 1.0);
                objExpr.AddTerm(u[k - 1][0], -1.0);
            }
            cplex.GetObjective().Expr = objExpr;

            // Solve the worker LP

            cplex.Solve();

            // A violated cut is available iff the solution status is Unbounded

            if (cplex.GetStatus().Equals(Cplex.Status.Unbounded))
            {
                // Get the violated cut as an unbounded ray of the worker LP

                ILinearNumExpr rayExpr = cplex.Ray;

                // Compute the cut from the unbounded ray. The cut is:
                // sum((i,j) in A) (sum(k in V0) v(k,i,j)) * x(i,j) >=
                // sum(k in V0) u(k,0) - u(k,k)

                ILinearNumExpr           cutLhs  = cplex.LinearNumExpr();
                double                   cutRhs  = 0.0;
                ILinearNumExprEnumerator rayEnum = rayExpr.GetLinearEnumerator();

                while (rayEnum.MoveNext())
                {
                    INumVar var      = rayEnum.NumVar;
                    bool    varFound = false;
                    for (k = 1; k < numNodes && !varFound; ++k)
                    {
                        for (i = 0; i < numNodes && !varFound; ++i)
                        {
                            for (j = 0; j < numNodes && !varFound; ++j)
                            {
                                if (var.Equals(v[k - 1][i][j]))
                                {
                                    cutLhs.AddTerm(x[i][j], rayEnum.Value);
                                    varFound = true;
                                }
                            }
                        }
                    }
                    for (k = 1; k < numNodes && !varFound; ++k)
                    {
                        for (i = 0; i < numNodes && !varFound; ++i)
                        {
                            if (var.Equals(u[k - 1][i]))
                            {
                                if (i == 0)
                                {
                                    cutRhs += rayEnum.Value;
                                }
                                else if (i == k)
                                {
                                    cutRhs -= rayEnum.Value;
                                }
                                varFound = true;
                            }
                        }
                    }
                }

                cut = cplex.Ge(cutLhs, cutRhs);
            }

            return(cut);
        } // END Separate