Untitled

 avatar
unknown
plain_text
10 months ago
8.8 kB
14
Indexable
from datetime import datetime as dt
import pulp as pl 

start = dt.now()
print("Optimising. Start:", start)

# Create the problem instance
# LpProblem is the main class for defining an optimization problem.
# "Wrench_Production_Planning" is an informative name for the problem.
# pl.LpMinimize specifies that we want to minimize the objective function.
# This can be changed to pl.LpMaximize if the goal was maximization.
prob2 = pl.LpProblem("days an sh", pl.LpMinimize)
wt=1500
def solvefor(day):
    global wt
    prob = pl.LpProblem("pipes an sh", pl.LpMinimize,) # Can be replaced with LpMinimize for minimization

    # Data
    W_water = {
        1: 1474,
        2: 1315,
        3: 1655,
        4: 1399,
        5: 1380,
        6: 1655,
        7: 1840,
        8: 2005,
        9: 2300,
        10: 2630,
        11: 2915,
        12: 2200,
        13: 1830,
        14: 1460
    }
    S_water = {
        1: 0,
        2: 0,
        3: 0,
        4: 235,
        5: 0,
        6: 347,
        7: 0,
        8: 531,
        9: 823,
        10: 665,
        11: 1658,
        12: 1430,
        13: 1053,
        14: 294
    }

    ### Decision Variables
    p_13 = pl.LpVariable(
        "p1,p3",
        lowBound=0,
        upBound=None,
        cat="Continous",
    )
    p_14 = pl.LpVariable(
        "p1,p4",
        lowBound=0,
        upBound=None,
        cat="Continous",
    )
    p_8 = pl.LpVariable(
        "p8",
        lowBound=0,
        upBound=None,
        cat="Continous",
    )
    p_26 = pl.LpVariable(
        "p2,p6",
        lowBound=0,
        upBound=None,
        cat="Continous",
    )

    p_15 = pl.LpVariable(
        "p1,p5",
        lowBound=0,
        upBound=None,
        cat="Continous",
    )
    p_27 = pl.LpVariable(
        "p2,p7",
        lowBound=0,
        upBound=None,
        cat="Continous"
    )

    # We can add decision variables by using the pulp.LpVariable.dicts() function


    ### Add the objective function
    # The objective function is what we are trying to minimize or maximize.
    # In this case, we want to maximize the profit.

    # Objective Function: min cost

        
    prob.setObjective((p_13*0.6)+(p_14*0.56)+(p_15*0.7)+(p_26*1.2)+(p_27*0.05))

    ### Constraint
    # Constraints are limitations or requirements that the solution must satisfy.

    prob += pl.LpConstraint(p_13 + p_14 + p_15, sense=pl.LpConstraintLE, rhs=2000, name="n1")
    prob += pl.LpConstraint(p_26 + p_27, sense=pl.LpConstraintLE, rhs=2000, name="n2")
    prob += pl.LpConstraint(p_13, sense=pl.LpConstraintLE, rhs=1700, name="p13")
    prob += pl.LpConstraint(p_14, sense=pl.LpConstraintLE, rhs=1500, name="p14")
    prob += pl.LpConstraint(p_15, sense=pl.LpConstraintLE, rhs=1000, name="p15")
    prob += pl.LpConstraint(p_26, sense=pl.LpConstraintLE, rhs=1000, name="p26")
    prob += pl.LpConstraint(p_27, sense=pl.LpConstraintLE, rhs=1500, name="p27")
    prob += pl.LpConstraint(p_8, sense=pl.LpConstraintLE, rhs=1500, name="p8")

    prob += pl.LpConstraint(p_13, sense=pl.LpConstraintGE, rhs=0, name="p13m")
    prob += pl.LpConstraint(p_14, sense=pl.LpConstraintGE, rhs=0, name="p14m")
    prob += pl.LpConstraint(p_15, sense=pl.LpConstraintGE, rhs=0, name="p15m")
    prob += pl.LpConstraint(p_26, sense=pl.LpConstraintGE, rhs=0, name="p26m")
    prob += pl.LpConstraint(p_27, sense=pl.LpConstraintGE, rhs=0, name="p27m")
    prob += pl.LpConstraint(p_8, sense=pl.LpConstraintGE, rhs=0, name="p8m")

    prob += pl.LpConstraint((p_8*0.94)+(p_14*0.85)+(p_26*0.85), sense=pl.LpConstraintEQ, rhs=W_water[day], name="W water")
    prob += pl.LpConstraint((p_15*0.90)+(p_27*0.95), sense=pl.LpConstraintEQ, rhs=S_water[day], name="S water")
    prob += pl.LpConstraint(wt, sense=pl.LpConstraintGE, rhs=0, name="wt min")
    prob += pl.LpConstraint(wt, sense=pl.LpConstraintLE, rhs=3000, name="wt max")
    prob += pl.LpConstraint(p_13+wt-p_8, sense=pl.LpConstraintLE, rhs=3000)
    prob += pl.LpConstraint(p_8, sense=pl.LpConstraintLE, rhs=wt, name="wt out")




    # Solve the problem using Gurobi solver
    # If you do not have the Gurobi licence, you can find instructions to get it on 
    # wattle. Gurobi will be necessary to solve quadratic problems later, for now 
    # you may run "prob.solve()" instead
    # solver = pl.GUROBI()
    # prob.solve(solver)
    prob.solve()
    end = dt.now()
    print("Optimisation took:", end - start)

    print("Solver Status:", pl.LpStatus[prob.status])

    print("\nOptimal Solution")
    print("===========================")
    print(f"""
        DAY NUMBER {day}
    p_8: {pl.value(p_8)}
    p_13: {pl.value(p_13)}
    p_14: {pl.value(p_14)}
    p_15: {pl.value(p_15)}
    p_26: {pl.value(p_26)}
    p_27: {pl.value(p_27)}

    Water Req:
    W: {pl.value(W_water[day])}
    S: {pl.value(S_water[day])}

    Total Cost:
        $ {pl.value(prob.objective):.2f}
    """) # pl.value() retrieves the numerical value of the objective function
    wt += pl.value(p_13)
    cost = pl.value(prob.objective)
    print(wt)
    return cost


day1 = abs(solvefor(1)) == pl.LpVariable("day1", lowBound=0, upBound=None, cat="Continous")
day2 = abs(solvefor(2)) == pl.LpVariable("day2", lowBound=0, upBound=None, cat="Continous")
day3 = abs(solvefor(3)) == pl.LpVariable("day3", lowBound=0, upBound=None, cat="Continous")
day4 = abs(solvefor(4)) == pl.LpVariable("day4", lowBound=0, upBound=None, cat="Continous")
day5 = abs(solvefor(5)) == pl.LpVariable("day5", lowBound=0, upBound=None, cat="Continous")
day6 = abs(solvefor(6)) == pl.LpVariable("day6", lowBound=0, upBound=None, cat="Continous")
day7 = abs(solvefor(7)) == pl.LpVariable("day7", lowBound=0, upBound=None, cat="Continous")
day8 = abs(solvefor(8)) == pl.LpVariable("day8", lowBound=0, upBound=None, cat="Continous")
day9 = abs(solvefor(9)) == pl.LpVariable("day9", lowBound=0, upBound=None, cat="Continous")
day10 = abs(solvefor(10)) == pl.LpVariable("day10", lowBound=0, upBound=None, cat="Continous")
day11 = abs(solvefor(11)) == pl.LpVariable("day11", lowBound=0, upBound=None, cat="Continous")
day12 = abs(solvefor(12)) == pl.LpVariable("day12", lowBound=0, upBound=None, cat="Continous")
day13 = abs(solvefor(13)) == pl.LpVariable("day13", lowBound=0, upBound=None, cat="Continous")
day14 = abs(solvefor(14)) == pl.LpVariable("day14", lowBound=0, upBound=None, cat="Continous")
    


prob2.setObjective(day1+day2+day3+day4+day5+day6+day7+day8+day9+day10+day11+day12+day13+day14)

# prob2 += pl.LpConstraint(day1, sense=pl.LpConstraintGE, rhs=0)
# prob2 += pl.LpConstraint(day2, sense=pl.LpConstraintGE, rhs=0)
# prob2 += pl.LpConstraint(day3, sense=pl.LpConstraintGE, rhs=0)
# prob2 += pl.LpConstraint(day4, sense=pl.LpConstraintGE, rhs=0)
# prob2 += pl.LpConstraint(day5, sense=pl.LpConstraintGE, rhs=0)
# prob2 += pl.LpConstraint(day6, sense=pl.LpConstraintGE, rhs=0)
# prob2 += pl.LpConstraint(day7, sense=pl.LpConstraintGE, rhs=0)
# prob2 += pl.LpConstraint(day8, sense=pl.LpConstraintGE, rhs=0)
# prob2 += pl.LpConstraint(day9, sense=pl.LpConstraintGE, rhs=0)
# prob2 += pl.LpConstraint(day10, sense=pl.LpConstraintGE, rhs=0)
# prob2 += pl.LpConstraint(day11, sense=pl.LpConstraintGE, rhs=0)
# prob2 += pl.LpConstraint(day12, sense=pl.LpConstraintGE, rhs=0)
# prob2 += pl.LpConstraint(day13, sense=pl.LpConstraintGE, rhs=0)
# prob2 += pl.LpConstraint(day14, sense=pl.LpConstraintGE, rhs=0)

prob2 += pl.LpConstraint(wt, sense=pl.LpConstraintEQ, name="wt end", rhs=1500)

prob2.solve()
    



def buffer_string(obj, n=8):
    """ Adds white space to the end of a string to pad to a specified length, n"""
    if isinstance(obj, float):
        obj = int(round(obj))  # Round to nearest integer for display
    obj = str(obj) # convert to string
    assert len(obj) <= n
    obj += " " * max(0, (4 - len(obj))) # add white space to end of string
    return obj

# Including f at the start allows us to insert values with {}
# this is called an f-string 
print(f"""
Water Tower Final: {wt}

COSTS per day:
1: {abs(pl.value(day1)):.2f},
2: {abs(pl.value(day2)):.2f},
3: {abs(pl.value(day3)):.2f},
4: {abs(pl.value(day4)):.2f},
5: {abs(pl.value(day5)):.2f},
6: {abs(pl.value(day6)):.2f},
7: {abs(pl.value(day7)):.2f},
8: {abs(pl.value(day8)):.2f},
9: {abs(pl.value(day9)):.2f},
10: {abs(pl.value(day10)):.2f},
11: {abs(pl.value(day11)):.2f},
12: {abs(pl.value(day12)):.2f},
13: {abs(pl.value(day13)):.2f},
14: {abs(pl.value(day14)):.2f}
    TOTAL = $ {abs(pl.value(prob2.objective)):.2f}
    """) # pl.value() retrieves the numerical value of the objective function


Editor is loading...
Leave a Comment