Пример #1
0
def getsocpconstrmultipliers(cplex, dslack=None):
    socppi = dict()

    # Compute full dual slack (sum of dual multipliers for bound constraints
    # and per-constraint dual slacks)
    dense = dict(
        zip(cplex.variables.get_names(), cplex.solution.get_reduced_costs()))
    for n in cplex.quadratic_constraints.get_names():
        v = cplex.solution.get_quadratic_dualslack(n)
        for (var, val) in zip(v.ind, v.val):
            dense[cplex.variables.get_names(var)] += val

    # Find the cone head variables and pick up the dual slacks for them.
    for n in cplex.quadratic_constraints.get_names():
        q = cplex.quadratic_constraints.get_quadratic_components(n)
        for (i1, i2, v) in zip(q.ind1, q.ind2, q.val):
            if v < 0:
                name = cplex.variables.get_names(i1)
                socppi[n] = dense[name]
                break

    if dslack is not None:
        dslack.clear()
        for key, value in six.iteritems(dense):
            dslack[key] = value

    return socppi
Пример #2
0
def getsocpconstrmultipliers(cplex,dslack = None):
    socppi = dict()

    # Compute full dual slack (sum of dual multipliers for bound constraints
    # and per-constraint dual slacks)
    dense = dict(zip(cplex.variables.get_names(),
                     cplex.solution.get_reduced_costs()))
    for n in cplex.quadratic_constraints.get_names():
        v = cplex.solution.get_quadratic_dualslack(n)
        for (var,val) in zip(v.ind, v.val):
            dense[cplex.variables.get_names(var)] += val

    # Find the cone head variables and pick up the dual slacks for them.
    for n in cplex.quadratic_constraints.get_names():
        q = cplex.quadratic_constraints.get_quadratic_components(n)
        for (i1,i2,v) in zip(q.ind1, q.ind2, q.val):
            if v < 0:
                name = cplex.variables.get_names(i1)
                socppi[n] = dense[name]
                break

    if dslack != None:
        dslack.clear()
        for key, value in six.iteritems(dense):
            dslack[key] = value
            
    return socppi
Пример #3
0
def checkkkt(c, cone, tol):
    # Read primal and dual solution information.
    x = dict(zip(c.variables.get_names(), c.solution.get_values()))
    s = dict(
        zip(c.linear_constraints.get_names(), c.solution.get_linear_slacks()))
    pi = dict(
        zip(c.linear_constraints.get_names(), c.solution.get_dual_values()))
    dslack = dict()
    for key, value in six.iteritems(getsocpconstrmultipliers(c, dslack)):
        pi[key] = value
    for (q, v) in zip(
            c.quadratic_constraints.get_names(),
            c.solution.get_quadratic_slacks(
                c.quadratic_constraints.get_names())):
        s[q] = v

    # Print out the data just fetched.
    print("x      = [", end=' ')
    for n in c.variables.get_names():
        print(" %7.3f" % x[n], end=' ')
    print(" ]")
    print("dslack = [", end=' ')
    for n in c.variables.get_names():
        print(" %7.3f" % dslack[n], end=' ')
    print(" ]")
    print("pi     = [", end=' ')
    for n in c.linear_constraints.get_names():
        print(" %7.3f" % pi[n], end=' ')
    for n in c.quadratic_constraints.get_names():
        print(" %7.3f" % pi[n], end=' ')
    print(" ]")
    print("slack  = [", end=' ')
    for n in c.linear_constraints.get_names():
        print(" %7.3f" % s[n], end=' ')
    for n in c.quadratic_constraints.get_names():
        print(" %7.3f" % s[n], end=' ')
    print(" ]")

    # Test primal feasibility.
    # This example illustrates the use of dual vectors returned by CPLEX
    # to verify dual feasibility, so we do not test primal feasibility
    # here.

    # Test dual feasibility.
    # We must have
    # - for all <= constraints the respective pi value is non-negative,
    # - for all >= constraints the respective pi value is non-positive,
    # - the dslack value for all non-cone variables must be non-negative.
    # Note that we do not support ranged constraints here.
    for n in c.linear_constraints.get_names():
        if c.linear_constraints.get_senses(n) == 'L' and pi[n] < -tol:
            print("Dual multiplier ",
                  pi[n],
                  " for <= constraint ",
                  n,
                  " not feasible.",
                  file=sys.stderr)
            return False
        elif c.linear_constraints.get_senses(n) == 'G' and pi[n] > tol:
            print("Dual multiplier ",
                  pi[n],
                  " for >= constraint ",
                  n,
                  " not feasible.",
                  file=sys.stderr)
            return False
    for n in c.quadratic_constraints.get_names():
        if c.quadratic_constraints.get_senses(n) == 'L' and pi[n] < -tol:
            print("Dual multiplier ",
                  pi[n],
                  " for <= constraint ",
                  n,
                  " not feasible.",
                  file=sys.stderr)
            return False
        elif c.quadratic_constraints.get_senses(n) == 'G' and pi[n] > tol:
            print("Dual multiplier ",
                  pi[n],
                  " for >= constraint ",
                  n,
                  " not feasible.",
                  file=sys.stderr)
            return False
    for n in c.variables.get_names():
        if cone[n] == NOT_IN_CONE and dslack[n] < -tol:
            print("Dual multiplier for ",
                  n,
                  " is not feasible: ",
                  dslack[n],
                  file=sys.stderr)
            return False

    # Test complementary slackness.
    # For each constraint either the constraint must have zero slack or
    # the dual multiplier for the constraint must be 0. We must also
    # consider the special case in which a variable is not explicitly
    # contained in a second order cone constraint.
    for n in c.linear_constraints.get_names():
        if fabs(s[n]) > tol and fabs(pi[n]) > tol:
            print("Invalid complementary slackness for ",
                  n,
                  ": ",
                  s[n],
                  " and ",
                  pi[n],
                  file=sys.stderr)
            return False
    for n in c.quadratic_constraints.get_names():
        if fabs(s[n]) > tol and fabs(pi[n]) > tol:
            print("Invalid complementary slackness for ",
                  n,
                  ": ",
                  s[n],
                  " and ",
                  pi[n],
                  file=sys.stderr)
            return False
    for n in c.variables.get_names():
        if cone[n] == NOT_IN_CONE:
            if fabs(x[n]) > tol and fabs(dslack[n]) > tol:
                print("Invalid complementary slackness for ",
                      n,
                      ": ",
                      x[n],
                      " and ",
                      dslack[n],
                      file=sys.stderr)
                return False

    # Test stationarity.
    # We must have
    #  c - g[i]'(X)*pi[i] = 0
    # where c is the objective function, g[i] is the i-th constraint of the
    # problem, g[i]'(x) is the derivate of g[i] with respect to x and X is the
    # optimal solution.
    # We need to distinguish the following cases:
    # - linear constraints g(x) = ax - b. The derivative of such a
    #   constraint is g'(x) = a.
    # - second order constraints g(x[1],...,x[n]) = -x[1] + |(x[2],...,x[n])|
    #   the derivative of such a constraint is
    #     g'(x) = (-1, x[2]/|(x[2],...,x[n])|, ..., x[n]/|(x[2],...,x[n])|
    #   (here |.| denotes the Euclidean norm).
    # - bound constraints g(x) = -x for variables that are not explicitly
    #   contained in any second order cone constraint. The derivative for
    #   such a constraint is g'(x) = -1.
    # Note that it may happen that the derivative of a second order cone
    # constraint is not defined at the optimal solution X (this happens if
    # X=0). In this case we just skip the stationarity test.
    val = dict(zip(c.variables.get_names(), c.objective.get_linear()))

    for n in c.variables.get_names():
        if cone[n] == NOT_IN_CONE:
            val[n] -= dslack[n]

    for n in c.linear_constraints.get_names():
        r = c.linear_constraints.get_rows(n)
        for j in range(0, len(r.ind)):
            nj = c.variables.get_names(r.ind[j])
            val[nj] -= r.val[j] * pi[n]

    for n in c.quadratic_constraints.get_names():
        r = c.quadratic_constraints.get_quadratic_components(n)
        norm = 0
        for j in range(0, len(r.ind1)):
            nj = c.variables.get_names(r.ind1[j])
            if r.val[j] > 0:
                norm += x[nj] * x[nj]
        norm = sqrt(norm)
        if fabs(norm) <= tol:
            # Derivative is not defined. Skip test.
            print("Cannot test stationarity at non-differentiable point.",
                  file=sys.stderr)
            return True
        for j in range(0, len(r.ind1)):
            nj = c.variables.get_names(r.ind1[j])
            if r.val[j] < 0:
                val[nj] -= pi[n]
            else:
                val[nj] += pi[n] * x[nj] / norm

    # Now test that all elements in val[] are 0.
    for n in c.variables.get_names():
        if fabs(val[n]) > tol:
            print("Invalid stationarity ", val[n], " for ", n, file=sys.stderr)
            return False

    return True
Пример #4
0
def checkkkt(c, cone, tol):
    # Read primal and dual solution information.
    x = dict(zip(c.variables.get_names(), c.solution.get_values()))
    s = dict(zip(c.linear_constraints.get_names(), c.solution.get_linear_slacks()))
    pi = dict(zip(c.linear_constraints.get_names(), c.solution.get_dual_values()))
    dslack = dict()
    for key,value in six.iteritems(getsocpconstrmultipliers(c, dslack)):
        pi[key] = value
    for (q,v) in zip(c.quadratic_constraints.get_names(),
                     c.solution.get_quadratic_slacks(c.quadratic_constraints.get_names())):
        s[q] = v
    
    # Print out the data just fetched.
    print("x      = [", end=' ')
    for n in c.variables.get_names():
        print(" %7.3f" % x[n], end=' ')
    print(" ]")
    print("dslack = [", end=' ')
    for n in c.variables.get_names():
        print(" %7.3f" % dslack[n], end=' ')
    print(" ]")
    print("pi     = [", end=' ')
    for n in c.linear_constraints.get_names():
        print(" %7.3f" % pi[n], end=' ')
    for n in c.quadratic_constraints.get_names():
        print(" %7.3f" % pi[n], end=' ')
    print(" ]")
    print("slack  = [", end=' ')
    for n in c.linear_constraints.get_names():
        print(" %7.3f" % s[n], end=' ')
    for n in c.quadratic_constraints.get_names():
        print(" %7.3f" % s[n], end=' ')
    print(" ]")

    # Test primal feasibility.
    # This example illustrates the use of dual vectors returned by CPLEX
    # to verify dual feasibility, so we do not test primal feasibility
    # here.

    # Test dual feasibility.
    # We must have
    # - for all <= constraints the respective pi value is non-negative,
    # - for all >= constraints the respective pi value is non-positive,
    # - the dslack value for all non-cone variables must be non-negative.
    # Note that we do not support ranged constraints here.
    for n in c.linear_constraints.get_names():
        if c.linear_constraints.get_senses(n) == 'L' and pi[n] < -tol:
            print("Dual multiplier ", pi[n], " for <= constraint ", n, " not feasible.", file=sys.stderr)
            return False
        elif c.linear_constraints.get_senses(n) == 'G' and pi[n] > tol:
            print("Dual multiplier ", pi[n], " for >= constraint ", n, " not feasible.", file=sys.stderr)
            return False
    for n in c.quadratic_constraints.get_names():
        if c.quadratic_constraints.get_senses(n) == 'L' and pi[n] < -tol:
            print("Dual multiplier ", pi[n], " for <= constraint ", n, " not feasible.", file=sys.stderr)
            return False
        elif c.quadratic_constraints.get_senses(n) == 'G' and pi[n] > tol:
            print("Dual multiplier ", pi[n], " for >= constraint ", n, " not feasible.", file=sys.stderr)
            return False
    for n in c.variables.get_names():
        if cone[n] == NOT_IN_CONE and dslack[n] < -tol:
            print("Dual multiplier for ", n, " is not feasible: ", dslack[n], file=sys.stderr)
            return False

    # Test complementary slackness.
    # For each constraint either the constraint must have zero slack or
    # the dual multiplier for the constraint must be 0. We must also
    # consider the special case in which a variable is not explicitly
    # contained in a second order cone constraint.
    for n in c.linear_constraints.get_names():
        if fabs(s[n]) > tol and fabs(pi[n]) > tol:
            print("Invalid complementary slackness for ", n, ": ", s[n], " and ", pi[n], file=sys.stderr)
            return False
    for n in c.quadratic_constraints.get_names():
        if fabs(s[n]) > tol and fabs(pi[n]) > tol:
            print("Invalid complementary slackness for ", n, ": ", s[n], " and ", pi[n], file=sys.stderr)
            return False
    for n in c.variables.get_names():
        if cone[n] == NOT_IN_CONE:
            if fabs(x[n]) > tol and fabs(dslack[n]) > tol:
                print("Invalid complementary slackness for ", n, ": ", x[n], " and ", dslack[n], file=sys.stderr)
                return False

    # Test stationarity.
    # We must have
    #  c - g[i]'(X)*pi[i] = 0
    # where c is the objective function, g[i] is the i-th constraint of the
    # problem, g[i]'(x) is the derivate of g[i] with respect to x and X is the
    # optimal solution.
    # We need to distinguish the following cases:
    # - linear constraints g(x) = ax - b. The derivative of such a
    #   constraint is g'(x) = a.
    # - second order constraints g(x[1],...,x[n]) = -x[1] + |(x[2],...,x[n])|
    #   the derivative of such a constraint is
    #     g'(x) = (-1, x[2]/|(x[2],...,x[n])|, ..., x[n]/|(x[2],...,x[n])|
    #   (here |.| denotes the Euclidean norm).
    # - bound constraints g(x) = -x for variables that are not explicitly
    #   contained in any second order cone constraint. The derivative for
    #   such a constraint is g'(x) = -1.
    # Note that it may happen that the derivative of a second order cone
    # constraint is not defined at the optimal solution X (this happens if
    # X=0). In this case we just skip the stationarity test.
    val = dict(zip(c.variables.get_names(), c.objective.get_linear()))

    for n in c.variables.get_names():
        if cone[n] == NOT_IN_CONE:
            val[n] -= dslack[n]

    for n in c.linear_constraints.get_names():
        r = c.linear_constraints.get_rows(n)
        for j in range(0, len(r.ind)):
            nj = c.variables.get_names(r.ind[j])
            val[nj] -= r.val[j] * pi[n]

    for n in c.quadratic_constraints.get_names():
        r = c.quadratic_constraints.get_quadratic_components(n)
        norm = 0
        for j in range(0, len(r.ind1)):
            nj = c.variables.get_names(r.ind1[j])
            if r.val[j] > 0:
                norm += x[nj] * x[nj]
        norm = sqrt(norm)
        if fabs(norm) <= tol:
            # Derivative is not defined. Skip test.
            print("Cannot test stationarity at non-differentiable point.", file=sys.stderr)
            return True
        for j in range(0, len(r.ind1)):
            nj = c.variables.get_names(r.ind1[j])
            if r.val[j] < 0:
                val[nj] -= pi[n]
            else:
                val[nj] += pi[n] * x[nj] / norm

    # Now test that all elements in val[] are 0.
    for n in c.variables.get_names():
        if fabs(val[n]) > tol:
            print("Invalid stationarity ", val[n], " for ", n, file=sys.stderr)
            return False

    return True