Skip to main content

tupledict.prod() with partial dictionary key

Answered

Comments

6 comments

  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    You are getting a \(0\) result, because the tuple key for your variables are of 3 while the ones for coeff are of length 2.

    You can do

    # My trial:
    x = m.addVars([(1,2,0), (1,3,0), (2,3,0)]) # The indices are generated from tuplelist, in which the last index can span to T.
    m.update()
    coeff = dict([((1,2,0), 2.0), ((1,3,0), 2.1), ((2,3,0), 3.3)])
    expr = x.prod(coeff,'*',3,'*')

    print(expr)

    > 2.1 C1 + 3.3 C2

    The pattern states to use only the entries with \(3\) in the second place.

    0
  • Panggah Prabawa
    Conversationalist
    First Question

    Thank you for your response.

    I know that is a way to do that.
    Let's say that the index is a tuple (i,j,t), where t < T.
    I maintain parameter coeff to have 2 key lengths to avoid iterating coeff over T.
    This is a simple reproducible code, where the actual simulation has more than 100 (i,j) pairs and T > 100.

    So, is it still impossible to use variable x and coeff with different key lengths?
    Is there any other workaround? Or is it okay to just copy the coeff T times?

    0
  • Jaromił Najman
    Gurobi Staff Gurobi Staff

    So, is it still impossible to use variable x and coeff with different key lengths?

    No, this is not possible.

    Is there any other workaround? Or is it okay to just copy the coeff T times?

    There may be a workaround but I am not aware of one. Copying coeff T times should work well enough.

    1
  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Panggah,

    Jarek has given me the green light to post some creative solutions if you want to keep your data in its current format, which does have it's advantages - not sure if speed is one of them though.

    # import gurobipy as gp

    gp.quicksum(coeff[k1,k2]*v for (k1,k2,_),v in x.items())

    gp.quicksum(coeff*x.sum(*k,"*") for k,coeff in coeff.items())

    gp.quicksum(coeff*x.sum(k1,k2,"*") for (k1,k2),coeff in coeff.items())

    gp.tupledict({k:x.sum(*k,"*") for k in coeff.keys()}).prod(coeff)

    - Riley

    1
  • Panggah Prabawa
    Conversationalist
    First Question

    Thank you for your answers, Jaromil and Riley.
    I will test the creation speeds of those options. Very interesting.

     

    0
  • Riley Clement
    Gurobi Staff Gurobi Staff

    No problem, my advice for comparison is to use the following approach as an example:

    import numpy as np
    import timeit


    setup = """
    import gurobipy as gp
    m = gp.Model()
    x = m.addVar()
    y = m.addVar()
    """


    statement1= """
    m.addConstr(x <= 2)
    """

    statement2= """
    m.addLConstr(x,"<=",2)
    """

    factor = np.divide(
        np.min(timeit.repeat(stmt=statement1, setup=setup, number=1, repeat=1000)),
        np.min(timeit.repeat(stmt=statement2, setup=setup, number=1, repeat=1000)),
    )

    It runs the code many times, then takes the minimum for comparison, to reduce the effect of noise on your machine.

    - Riley

    1

Please sign in to leave a comment.