メインコンテンツへスキップ

Copy constraints and variables from base model to extended model

回答済み

コメント

5件のコメント

  • Riley Clement
    • Gurobi Staff

    Hi Tim,

    In the MixedSequencing function you are creating a model, then passing it to your BaseModel function, which adds variables and constraints to this model (not a copy), and then you are iterating through the constraints and adding them again, creating duplicates on the model.  You are then doing something similar with variables.

    There is no copying occurring here, and I'd recommend reading up on Passing by Reference in Python to understand what is going on when you pass objects to functions.

    That aside, this misunderstanding is not what is the core of your problem.  One issue is that the MixedSequencing code does not know what "x" is, since it was defined in a different place.  You can see that your editor is highlighting this for you by underlining the "x" in the screenshots.  There maybe more issues but it is hard to tell using screenshots.

    If you would like to paste code here (not screenshots), then I can demonstrate how to fix this.

    Cheers,
    Riley

    0
  • Tim Sanwald
    • Gurobi-versary
    • First Comment
    • First Question

    Dear Riley,

    thank you very much for your quick and detailled answer. I'll take a look into the "passing by reference in python" link you provided later today but thank you for that already in advance.

    Since I could not upload the python (and a mathematical problem definition in a pdf file in case my code is totally messy) file, please find a .zip package under this link: https://drive.google.com/file/d/1bFoqyIREwHwenZAKUk351bYMKK8BDpJA/view?usp=sharing

    Let me know, if this works!

    Kind regards,
    Tim

    0
  • Riley Clement
    • Gurobi Staff

    Hi Tim,

    Please see changes I've made below to the relevant sections of code.  I've made comments where changes have been made.  Let me know if you need any clarification?

    def BaseModel(M, T, demand, model):
        """
        M: constant, number of models
        T: constant, number of production cycles
        demand: list, demand for copies of model m.
        model: object, gurobi optimization model
        """

        # Define decision variables for the given model
        x = model.addVars(M, T, vtype = gp.GRB.BINARY, name = "x")

        # Add constraints (1a) and (1b)
        ct_1a = model.addConstrs(gp.quicksum(x[m, t] for m in range(0, M)) == 1 for t in range(0, T))
        ct_1b = model.addConstrs(gp.quicksum(x[m, t] for t in range(0, T)) == demand[m] for m in range(0, M))

        # Write the optimization model in txt file
        model.write('BaseModel.lp')

        # fix:  no need to return model, you have made changes to the original model being passed in
        return x


    def MixedSequencing(T, C, demand, processTimes, length):
        # Create the optimization model
        model = gp.Model("Mixed Sequencing")

        # Set parameters
        model.setParam('OutputFlag', True)

        M, K = len(demand), len(processTimes[0])  # number of models, number of stations
        
        # Define decision variables
        # fix: missing vtype keyword parameter.  Without it addVars assumes gp.GRB.CONTINUOUS is another index
        #      and hence w and s would have 3-element indices.
        w = model.addVars(K, T, vtype=gp.GRB.CONTINUOUS, lb = 0, name = "work_overload")
        s = model.addVars(K, T, vtype=gp.GRB.CONTINUOUS, lb = 0, name = "start_position_of_worker")

        # fix: returning x and assigning so that we can use it in constraints.
        #      Another option is to set 
        #         model._x = x
        #      in BaseModel function then in this function use
        #         x = model._x
        #      after calling BaseModel so that you have a reference to x.
        x = BaseModel(M, T, demand, model)

        # Add constraints (2c) - (2f)
        # fix: cannot use processTimes[m, k] with nested lists.  You could convert processTimes to numpy array and use this indexing though.
      # fix: cannot have t+1 index and t in range(T)
    ct_2c = model.addConstrs(s[k, t+1] >= s[k, t] + gp.quicksum(processTimes[m][k] * x[m, t] - w[k, t] - C
                                                                    for m in range(M)) for k in range(K) for t in range(T-1))
        ct_2d = model.addConstrs(length[k] >= s[k, t] + gp.quicksum(processTimes[m][k] * x[m, t] - w[k, t]
                                                                    for m in range(M)) for k in range(K) for t in range(T))

        # Set objective
        obj = model.setObjective(gp.quicksum(w[k, t] for k in range(0, K) for t in range(0, T)), sense = gp.GRB.MINIMIZE)

        # Optimize the model
        model.optimize()

        # Write the optimization model in txt file
        model.write('MixedModel.lp')

        Output(model)


    Note that you may benefit a lot from prototyping your models interactively either with Jupyter notebooks, or equivalently pypercent format offered by editors such as VS Code.

    - Riley

    0
  • Tim Sanwald
    • Gurobi-versary
    • First Comment
    • First Question

    Hi Riley,

    Thanks you very much for the code suggestion and the hints to things that don't work! I'm still trying to fix those so just one quick direct follow-up question: with your suggestion I can easly take the x variables from the BaseModel into the extended MixedSequencing, that's already awesome! How can I access the 2 constraints ct_1a and ct_1b as well? 

    Kind regards, Tim

    0
  • Riley Clement
    • Gurobi Staff

    Hi Tim,

    You can either use

    return x, ct_1a, ct_1b

    and then

    x, ct_1a, ct_1b = BaseModel(M, T, demand, model)

    or you can use the other approach where you store them on the model object, i.e.

    model._ct_1a = ct_1a


    - Riley

    0

サインインしてコメントを残してください。