Seattle to Topeka (Multi-location SC)#

This is a rather famous multi-location supply chain.

There are a two sources and three sinks. The goal is to procure a commodity (\(r\)) in any of the source, transport it and dispatch it in (or from) the sink locations.

The data is as shown:

Plants

New York

Chicago

Topeka

Supply

Seattle

2.5

1.7

1.8

350

San Diego

2.5

1.8

1.4

600

Demand

325

300

275

Initialize the Model#

The locations can be conveniently generated using .declare(). The US Dollar will be used as currency (a measure of economic impact)

from energia import *
from itertools import product

m = Model()
m.declare(Location, ['seattle', 'sandiego', 'newyork', 'chicago', 'topeka'])
m.usd = Currency()

Resources#

There are three resources we consider.

  • \(r\_consume\) - resource pre-procurement

  • \(r\) - The insitu resource being transported

  • \(r\_release\) - resource post-dispatch

Consumption Upper Bounds#

Set the maximum consumption allowed at source locations

m.r_consume = Resource()
m.r_consume.consume(m.seattle) <= 350
m.r_consume.consume(m.sandiego) <= 600
⚖  Initiated r_consume balance in (seattle, t0)                             ⏱ 0.0001 s
🔗  Bound [≤] r_consume consume in (seattle, t0)                             ⏱ 0.0008 s
⚖  Initiated r_consume balance in (sandiego, t0)                            ⏱ 0.0001 s
🔗  Bound [≤] r_consume consume in (sandiego, t0)                            ⏱ 0.0006 s

Release Lower Bounds#

Set the minimum release allowed at sink locations

m.r_release = Resource()
m.r_release.release(m.newyork) >= 325
m.r_release.release(m.chicago) >= 300
m.r_release.release(m.topeka) >= 275
⚖  Initiated r_release balance in (newyork, t0)                             ⏱ 0.0001 s
🔗  Bound [≥] r_release release in (newyork, t0)                             ⏱ 0.0011 s
⚖  Initiated r_release balance in (chicago, t0)                             ⏱ 0.0001 s
🔗  Bound [≥] r_release release in (chicago, t0)                             ⏱ 0.0006 s
⚖  Initiated r_release balance in (topeka, t0)                              ⏱ 0.0001 s
🔗  Bound [≥] r_release release in (topeka, t0)                              ⏱ 0.0006 s

Insitu Resource#

This is the primary resource being transported. The other two resources are dummy resources created for convenience

m.r = Resource()

Processes#

We create two dummy processes:

  1. Purchase - which expends \(r\_consume\) to produce \(r\)

  2. Dispatch - which expends \(r\) to produce \(r\_release\)

These are located at the sources and sinks respectively

m.purchase = Process()
m.purchase(m.r) == -m.r_consume
m.purchase.operate == True

m.dispatch = Process()
m.dispatch(-m.r) == m.r_release
m.dispatch.operate == True

m.purchase.locate(m.seattle, m.sandiego)
m.dispatch.locate(m.newyork, m.chicago, m.topeka)
💡  Assumed purchase capacity unbounded in (seattle, t0)                     ⏱ 0.0001 s
🧭  Mapped space for operate (purchase, seattle, t0) ⟺ (purchase, ntw, t0)   ⏱ 0.0004 s
🔗  Bound [≤] purchase operate in (seattle, t0)                              ⏱ 0.0011 s
💡  Assumed purchase operate bounded by capacity in (seattle, t0)            ⏱ 0.0015 s
💡  Assumed purchase capacity unbounded in (sandiego, t0)                    ⏱ 0.0001 s
🧭  Mapped space for operate (purchase, sandiego, t0) ⟺ (purchase, ntw, t0)  ⏱ 0.0001 s
🔗  Bound [≤] purchase operate in (sandiego, t0)                             ⏱ 0.0007 s
💡  Assumed purchase operate bounded by capacity in (sandiego, t0)           ⏱ 0.0013 s
⚖  Initiated r balance in (seattle, t0)                                     ⏱ 0.0001 s
🔗  Bound [=] r produce in (seattle, t0)                                     ⏱ 0.0006 s
⚖  Updated r_consume balance with expend(r_consume, seattle, t0, operate, purchase) ⏱ 0.0001 s
🔗  Bound [=] r_consume expend in (seattle, t0)                              ⏱ 0.0005 s
⚖  Initiated r balance in (sandiego, t0)                                    ⏱ 0.0001 s
🔗  Bound [=] r produce in (sandiego, t0)                                    ⏱ 0.0007 s
⚖  Updated r_consume balance with expend(r_consume, sandiego, t0, operate, purchase) ⏱ 0.0001 s
🔗  Bound [=] r_consume expend in (sandiego, t0)                             ⏱ 0.0006 s
🏭  Operating streams introduced for purchase in seattle, sandiego           ⏱ 0.0040 s
🏗  Construction streams introduced for purchase in seattle, sandiego        ⏱ 0.0000 s
🌍  Located purchase in seattle, sandiego                                    ⏱ 0.0091 s
💡  Assumed dispatch capacity unbounded in (newyork, t0)                     ⏱ 0.0002 s
🧭  Mapped space for operate (dispatch, newyork, t0) ⟺ (dispatch, ntw, t0)   ⏱ 0.0001 s
🔗  Bound [≤] dispatch operate in (newyork, t0)                              ⏱ 0.0007 s
💡  Assumed dispatch operate bounded by capacity in (newyork, t0)            ⏱ 0.0011 s
💡  Assumed dispatch capacity unbounded in (chicago, t0)                     ⏱ 0.0001 s
🧭  Mapped space for operate (dispatch, chicago, t0) ⟺ (dispatch, ntw, t0)   ⏱ 0.0015 s
🔗  Bound [≤] dispatch operate in (chicago, t0)                              ⏱ 0.0021 s
💡  Assumed dispatch operate bounded by capacity in (chicago, t0)            ⏱ 0.0024 s
💡  Assumed dispatch capacity unbounded in (topeka, t0)                      ⏱ 0.0002 s
🧭  Mapped space for operate (dispatch, topeka, t0) ⟺ (dispatch, ntw, t0)    ⏱ 0.0002 s
🔗  Bound [≤] dispatch operate in (topeka, t0)                               ⏱ 0.0007 s
💡  Assumed dispatch operate bounded by capacity in (topeka, t0)             ⏱ 0.0010 s
⚖  Initiated r balance in (newyork, t0)                                     ⏱ 0.0002 s
🔗  Bound [=] r expend in (newyork, t0)                                      ⏱ 0.0009 s
⚖  Updated r_release balance with produce(r_release, newyork, t0, operate, dispatch) ⏱ 0.0001 s
🔗  Bound [=] r_release produce in (newyork, t0)                             ⏱ 0.0010 s
⚖  Initiated r balance in (chicago, t0)                                     ⏱ 0.0002 s
🔗  Bound [=] r expend in (chicago, t0)                                      ⏱ 0.0011 s
⚖  Updated r_release balance with produce(r_release, chicago, t0, operate, dispatch) ⏱ 0.0002 s
🔗  Bound [=] r_release produce in (chicago, t0)                             ⏱ 0.0012 s
⚖  Initiated r balance in (topeka, t0)                                      ⏱ 0.0001 s
🔗  Bound [=] r expend in (topeka, t0)                                       ⏱ 0.0008 s
⚖  Updated r_release balance with produce(r_release, topeka, t0, operate, dispatch) ⏱ 0.0001 s
🔗  Bound [=] r_release produce in (topeka, t0)                              ⏱ 0.0012 s
🏭  Operating streams introduced for dispatch in newyork, chicago, topeka    ⏱ 0.0103 s
🏗  Construction streams introduced for dispatch in newyork, chicago, topeka ⏱ 0.0000 s
🌍  Located dispatch in newyork, chicago, topeka                             ⏱ 0.0183 s

Linking Locations#

Since the linkages between sources and sinks are unique. We can use the .Link() method. A unique linkage between two locations can simply be accessed using: source - sink

For multiple linkages between two given locations. Named Linkage objects are needed.

dist_dict = {
    m.seattle: {m.newyork: 2.5, m.chicago: 1.7, m.topeka: 1.8},
    m.sandiego: {m.newyork: 2.5, m.chicago: 1.8, m.topeka: 1.4},
}


for i, j in product([m.seattle, m.sandiego], [m.newyork, m.chicago, m.topeka]):
    m.Link(i, j, dist=dist_dict[i][j])

You can always check the linking

m.seattle.links(m.newyork)  # Link from Seattle to New York
seattle is source and newyork is sink in seattle-newyork
[seattle-newyork]
m.sandiego.connected(m.newyork)
True

Transportation#

In this mickey-mouse problem there are no dependent resources (produced and expended) besides the primary resource being transported.

A constant cost of 90 \(\frac{\$}{\text{unit distance}}\) is considered

m.channel = Transport()
m.channel(m.r) == 1.0  # 100% efficient

for i in dist_dict:
    for j in dist_dict[i]:
        m.usd.spend(m.channel.operate, i - j) == 90
        m.channel.locate(i - j)
🔗  Bound [=] usd spend in (seattle-newyork, t0)                             ⏱ 0.0005 s
💡  Assumed channel capacity unbounded in (seattle-newyork, t0)              ⏱ 0.0002 s
🔗  Bound [≤] channel operate in (seattle-newyork, t0)                       ⏱ 0.0001 s
💡  Assumed channel operate bounded by capacity in (seattle-newyork, t0)     ⏱ 0.0005 s
⚖  Updated r balance with ship_in(r, seattle-newyork, t0, operate, channel) ⏱ 0.0004 s
🔗  Bound [=] r ship_in in (seattle-newyork, t0)                             ⏱ 0.0014 s
⚖  Updated r balance with ship_out(r, seattle-newyork, t0, operate, channel) ⏱ 0.0001 s
🔗  Bound [=] r ship_out in (seattle-newyork, t0)                            ⏱ 0.0008 s
🏭  Operating streams introduced for channel in seattle-newyork              ⏱ 0.0035 s
🏗  Construction streams introduced for channel in seattle-newyork           ⏱ 0.0000 s
🌍  Located channel in seattle-newyork                                       ⏱ 0.0056 s
🔗  Bound [=] usd spend in (seattle-chicago, t0)                             ⏱ 0.0003 s
💡  Assumed channel capacity unbounded in (seattle-chicago, t0)              ⏱ 0.0002 s
🔗  Bound [≤] channel operate in (seattle-chicago, t0)                       ⏱ 0.0001 s
💡  Assumed channel operate bounded by capacity in (seattle-chicago, t0)     ⏱ 0.0005 s
⚖  Updated r balance with ship_in(r, seattle-chicago, t0, operate, channel) ⏱ 0.0001 s
🔗  Bound [=] r ship_in in (seattle-chicago, t0)                             ⏱ 0.0009 s
⚖  Updated r balance with ship_out(r, seattle-chicago, t0, operate, channel) ⏱ 0.0001 s
🔗  Bound [=] r ship_out in (seattle-chicago, t0)                            ⏱ 0.0006 s
🏭  Operating streams introduced for channel in seattle-newyork, seattle-chicago ⏱ 0.0022 s
🏗  Construction streams introduced for channel in seattle-newyork, seattle-chicago ⏱ 0.0000 s
🌍  Located channel in seattle-chicago                                       ⏱ 0.0037 s
🔗  Bound [=] usd spend in (seattle-topeka, t0)                              ⏱ 0.0002 s
💡  Assumed channel capacity unbounded in (seattle-topeka, t0)               ⏱ 0.0002 s
🔗  Bound [≤] channel operate in (seattle-topeka, t0)                        ⏱ 0.0001 s
💡  Assumed channel operate bounded by capacity in (seattle-topeka, t0)      ⏱ 0.0005 s
⚖  Updated r balance with ship_in(r, seattle-topeka, t0, operate, channel)  ⏱ 0.0001 s
🔗  Bound [=] r ship_in in (seattle-topeka, t0)                              ⏱ 0.0007 s
⚖  Updated r balance with ship_out(r, seattle-topeka, t0, operate, channel) ⏱ 0.0001 s
🔗  Bound [=] r ship_out in (seattle-topeka, t0)                             ⏱ 0.0007 s
🏭  Operating streams introduced for channel in seattle-newyork, seattle-chicago, seattle-topeka ⏱ 0.0022 s
🏗  Construction streams introduced for channel in seattle-newyork, seattle-chicago, seattle-topeka ⏱ 0.0000 s
🌍  Located channel in seattle-topeka                                        ⏱ 0.0037 s
🔗  Bound [=] usd spend in (sandiego-newyork, t0)                            ⏱ 0.0005 s
💡  Assumed channel capacity unbounded in (sandiego-newyork, t0)             ⏱ 0.0002 s
🔗  Bound [≤] channel operate in (sandiego-newyork, t0)                      ⏱ 0.0001 s
💡  Assumed channel operate bounded by capacity in (sandiego-newyork, t0)    ⏱ 0.0004 s
⚖  Updated r balance with ship_in(r, sandiego-newyork, t0, operate, channel) ⏱ 0.0001 s
🔗  Bound [=] r ship_in in (sandiego-newyork, t0)                            ⏱ 0.0007 s
⚖  Updated r balance with ship_out(r, sandiego-newyork, t0, operate, channel) ⏱ 0.0001 s
🔗  Bound [=] r ship_out in (sandiego-newyork, t0)                           ⏱ 0.0008 s
🏭  Operating streams introduced for channel in seattle-newyork, seattle-chicago, seattle-topeka, sandiego-newyork ⏱ 0.0022 s
🏗  Construction streams introduced for channel in seattle-newyork, seattle-chicago, seattle-topeka, sandiego-newyork ⏱ 0.0000 s
🌍  Located channel in sandiego-newyork                                      ⏱ 0.0037 s
🔗  Bound [=] usd spend in (sandiego-chicago, t0)                            ⏱ 0.0003 s
💡  Assumed channel capacity unbounded in (sandiego-chicago, t0)             ⏱ 0.0002 s
🔗  Bound [≤] channel operate in (sandiego-chicago, t0)                      ⏱ 0.0001 s
💡  Assumed channel operate bounded by capacity in (sandiego-chicago, t0)    ⏱ 0.0004 s
⚖  Updated r balance with ship_in(r, sandiego-chicago, t0, operate, channel) ⏱ 0.0001 s
🔗  Bound [=] r ship_in in (sandiego-chicago, t0)                            ⏱ 0.0008 s
⚖  Updated r balance with ship_out(r, sandiego-chicago, t0, operate, channel) ⏱ 0.0001 s
🔗  Bound [=] r ship_out in (sandiego-chicago, t0)                           ⏱ 0.0008 s
🏭  Operating streams introduced for channel in seattle-newyork, seattle-chicago, seattle-topeka, sandiego-newyork, sandiego-chicago ⏱ 0.0023 s
🏗  Construction streams introduced for channel in seattle-newyork, seattle-chicago, seattle-topeka, sandiego-newyork, sandiego-chicago ⏱ 0.0000 s
🌍  Located channel in sandiego-chicago                                      ⏱ 0.0039 s
🔗  Bound [=] usd spend in (sandiego-topeka, t0)                             ⏱ 0.0003 s
💡  Assumed channel capacity unbounded in (sandiego-topeka, t0)              ⏱ 0.0002 s
🔗  Bound [≤] channel operate in (sandiego-topeka, t0)                       ⏱ 0.0001 s
💡  Assumed channel operate bounded by capacity in (sandiego-topeka, t0)     ⏱ 0.0004 s
⚖  Updated r balance with ship_in(r, sandiego-topeka, t0, operate, channel) ⏱ 0.0001 s
🔗  Bound [=] r ship_in in (sandiego-topeka, t0)                             ⏱ 0.0008 s
⚖  Updated r balance with ship_out(r, sandiego-topeka, t0, operate, channel) ⏱ 0.0001 s
🔗  Bound [=] r ship_out in (sandiego-topeka, t0)                            ⏱ 0.0007 s
🏭  Operating streams introduced for channel in seattle-newyork, seattle-chicago, seattle-topeka, sandiego-newyork, sandiego-chicago, sandiego-topeka ⏱ 0.0021 s
🏗  Construction streams introduced for channel in seattle-newyork, seattle-chicago, seattle-topeka, sandiego-newyork, sandiego-chicago, sandiego-topeka ⏱ 0.0000 s
🌍  Located channel in sandiego-topeka                                       ⏱ 0.0037 s

The Formulation#

m.show(True)

Mathematical Program for Program(m)



Index Sets

\[\displaystyle {locations} = \{ {{seattle}, \dots ,{ntw}} \}\]
\[\displaystyle {currencies} = \{ {{usd}} \}\]
\[\displaystyle {resources} = \{ {{r\_consume}, {r\_release}, {r}} \}\]
\[\displaystyle {t0} = \{ {{{{t0}_{0}}}} \}\]
\[\displaystyle {processes} = \{ {{purchase}, {dispatch}} \}\]
\[\displaystyle {linkages} = \{ {{seattle-newyork}, \dots ,{sandiego-topeka}} \}\]



s.t.

Balance Constraints

\[\displaystyle [0]\text{ }{\mathbf{{cons}}}_{{r\_consume},{seattle},{{{t0}_{0}}}} - {\mathbf{{expd}}}_{{r\_consume},{seattle},{{{t0}_{0}}},{\mathbf{{opr}}},{purchase}} = 0\]
\[\displaystyle [2]\text{ }{\mathbf{{cons}}}_{{r\_consume},{sandiego},{{{t0}_{0}}}} - {\mathbf{{expd}}}_{{r\_consume},{sandiego},{{{t0}_{0}}},{\mathbf{{opr}}},{purchase}} = 0\]
\[\displaystyle [4]\text{ }-{\mathbf{{rlse}}}_{{r\_release},{newyork},{{{t0}_{0}}}} + {\mathbf{prod}}_{{r\_release},{newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{dispatch}} = 0\]
\[\displaystyle [6]\text{ }-{\mathbf{{rlse}}}_{{r\_release},{chicago},{{{t0}_{0}}}} + {\mathbf{prod}}_{{r\_release},{chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{dispatch}} = 0\]
\[\displaystyle [8]\text{ }-{\mathbf{{rlse}}}_{{r\_release},{topeka},{{{t0}_{0}}}} + {\mathbf{prod}}_{{r\_release},{topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{dispatch}} = 0\]
\[\displaystyle [13]\text{ }{\mathbf{prod}}_{{r},{seattle},{{{t0}_{0}}},{\mathbf{{opr}}},{purchase}} - {\mathbf{{expt}}}_{{r},{seattle-newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - {\mathbf{{expt}}}_{{r},{seattle-chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - {\mathbf{{expt}}}_{{r},{seattle-topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} = 0\]
\[\displaystyle [16]\text{ }{\mathbf{prod}}_{{r},{sandiego},{{{t0}_{0}}},{\mathbf{{opr}}},{purchase}} - {\mathbf{{expt}}}_{{r},{sandiego-newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - {\mathbf{{expt}}}_{{r},{sandiego-chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - {\mathbf{{expt}}}_{{r},{sandiego-topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} = 0\]
\[\displaystyle [23]\text{ }-{\mathbf{{expd}}}_{{r},{newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{dispatch}} + {\mathbf{{impt}}}_{{r},{seattle-newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} + {\mathbf{{impt}}}_{{r},{sandiego-newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} = 0\]
\[\displaystyle [26]\text{ }-{\mathbf{{expd}}}_{{r},{chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{dispatch}} + {\mathbf{{impt}}}_{{r},{seattle-chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} + {\mathbf{{impt}}}_{{r},{sandiego-chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} = 0\]
\[\displaystyle [29]\text{ }-{\mathbf{{expd}}}_{{r},{topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{dispatch}} + {\mathbf{{impt}}}_{{r},{seattle-topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} + {\mathbf{{impt}}}_{{r},{sandiego-topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} = 0\]

Binds Constraints

\[\displaystyle [1]\text{ }{\mathbf{{cons}}}_{{r\_consume},{seattle},{{{t0}_{0}}}} - 350.0 \leq 0\]
\[\displaystyle [3]\text{ }{\mathbf{{cons}}}_{{r\_consume},{sandiego},{{{t0}_{0}}}} - 600.0 \leq 0\]
\[\displaystyle [5]\text{ }-{\mathbf{{rlse}}}_{{r\_release},{newyork},{{{t0}_{0}}}} + 325.0 \leq 0\]
\[\displaystyle [7]\text{ }-{\mathbf{{rlse}}}_{{r\_release},{chicago},{{{t0}_{0}}}} + 300.0 \leq 0\]
\[\displaystyle [9]\text{ }-{\mathbf{{rlse}}}_{{r\_release},{topeka},{{{t0}_{0}}}} + 275.0 \leq 0\]
\[\displaystyle [11]\text{ }{\mathbf{{opr}}}_{{purchase},{seattle},{{{t0}_{0}}}} - {\mathbf{{cap}}}_{{purchase},{seattle},{{{t0}_{0}}}} \leq 0\]
\[\displaystyle [12]\text{ }{\mathbf{{opr}}}_{{purchase},{sandiego},{{{t0}_{0}}}} - {\mathbf{{cap}}}_{{purchase},{sandiego},{{{t0}_{0}}}} \leq 0\]
\[\displaystyle [20]\text{ }{\mathbf{{opr}}}_{{dispatch},{newyork},{{{t0}_{0}}}} - {\mathbf{{cap}}}_{{dispatch},{newyork},{{{t0}_{0}}}} \leq 0\]
\[\displaystyle [21]\text{ }{\mathbf{{opr}}}_{{dispatch},{chicago},{{{t0}_{0}}}} - {\mathbf{{cap}}}_{{dispatch},{chicago},{{{t0}_{0}}}} \leq 0\]
\[\displaystyle [22]\text{ }{\mathbf{{opr}}}_{{dispatch},{topeka},{{{t0}_{0}}}} - {\mathbf{{cap}}}_{{dispatch},{topeka},{{{t0}_{0}}}} \leq 0\]
\[\displaystyle [33]\text{ }{\mathbf{{opr}}}_{{channel},{seattle-newyork},{{{t0}_{0}}}} - {\mathbf{{cap}}}_{{channel},{seattle-newyork},{{{t0}_{0}}}} \leq 0\]
\[\displaystyle [37]\text{ }{\mathbf{{opr}}}_{{channel},{seattle-chicago},{{{t0}_{0}}}} - {\mathbf{{cap}}}_{{channel},{seattle-chicago},{{{t0}_{0}}}} \leq 0\]
\[\displaystyle [41]\text{ }{\mathbf{{opr}}}_{{channel},{seattle-topeka},{{{t0}_{0}}}} - {\mathbf{{cap}}}_{{channel},{seattle-topeka},{{{t0}_{0}}}} \leq 0\]
\[\displaystyle [45]\text{ }{\mathbf{{opr}}}_{{channel},{sandiego-newyork},{{{t0}_{0}}}} - {\mathbf{{cap}}}_{{channel},{sandiego-newyork},{{{t0}_{0}}}} \leq 0\]
\[\displaystyle [49]\text{ }{\mathbf{{opr}}}_{{channel},{sandiego-chicago},{{{t0}_{0}}}} - {\mathbf{{cap}}}_{{channel},{sandiego-chicago},{{{t0}_{0}}}} \leq 0\]
\[\displaystyle [53]\text{ }{\mathbf{{opr}}}_{{channel},{sandiego-topeka},{{{t0}_{0}}}} - {\mathbf{{cap}}}_{{channel},{sandiego-topeka},{{{t0}_{0}}}} \leq 0\]

Calculations Constraints

\[\displaystyle [14]\text{ }{\mathbf{prod}}_{{r},{seattle},{{{t0}_{0}}},{\mathbf{{opr}}},{purchase}} - 1.0 \cdot {\mathbf{{opr}}}_{{purchase},{seattle},{{{t0}_{0}}}} = 0\]
\[\displaystyle [15]\text{ }{\mathbf{{expd}}}_{{r\_consume},{seattle},{{{t0}_{0}}},{\mathbf{{opr}}},{purchase}} - 1.0 \cdot {\mathbf{{opr}}}_{{purchase},{seattle},{{{t0}_{0}}}} = 0\]
\[\displaystyle [17]\text{ }{\mathbf{prod}}_{{r},{sandiego},{{{t0}_{0}}},{\mathbf{{opr}}},{purchase}} - 1.0 \cdot {\mathbf{{opr}}}_{{purchase},{sandiego},{{{t0}_{0}}}} = 0\]
\[\displaystyle [18]\text{ }{\mathbf{{expd}}}_{{r\_consume},{sandiego},{{{t0}_{0}}},{\mathbf{{opr}}},{purchase}} - 1.0 \cdot {\mathbf{{opr}}}_{{purchase},{sandiego},{{{t0}_{0}}}} = 0\]
\[\displaystyle [24]\text{ }{\mathbf{{expd}}}_{{r},{newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{dispatch}} - 1.0 \cdot {\mathbf{{opr}}}_{{dispatch},{newyork},{{{t0}_{0}}}} = 0\]
\[\displaystyle [25]\text{ }{\mathbf{prod}}_{{r\_release},{newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{dispatch}} - 1.0 \cdot {\mathbf{{opr}}}_{{dispatch},{newyork},{{{t0}_{0}}}} = 0\]
\[\displaystyle [27]\text{ }{\mathbf{{expd}}}_{{r},{chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{dispatch}} - 1.0 \cdot {\mathbf{{opr}}}_{{dispatch},{chicago},{{{t0}_{0}}}} = 0\]
\[\displaystyle [28]\text{ }{\mathbf{prod}}_{{r\_release},{chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{dispatch}} - 1.0 \cdot {\mathbf{{opr}}}_{{dispatch},{chicago},{{{t0}_{0}}}} = 0\]
\[\displaystyle [30]\text{ }{\mathbf{{expd}}}_{{r},{topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{dispatch}} - 1.0 \cdot {\mathbf{{opr}}}_{{dispatch},{topeka},{{{t0}_{0}}}} = 0\]
\[\displaystyle [31]\text{ }{\mathbf{prod}}_{{r\_release},{topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{dispatch}} - 1.0 \cdot {\mathbf{{opr}}}_{{dispatch},{topeka},{{{t0}_{0}}}} = 0\]
\[\displaystyle [32]\text{ }{\mathbf{spend}}_{{usd},{seattle-newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 225.0 \cdot {\mathbf{{opr}}}_{{channel},{seattle-newyork},{{{t0}_{0}}}} = 0\]
\[\displaystyle [34]\text{ }{\mathbf{{impt}}}_{{r},{seattle-newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 1.0 \cdot {\mathbf{{opr}}}_{{channel},{seattle-newyork},{{{t0}_{0}}}} = 0\]
\[\displaystyle [35]\text{ }{\mathbf{{expt}}}_{{r},{seattle-newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 1.0 \cdot {\mathbf{{opr}}}_{{channel},{seattle-newyork},{{{t0}_{0}}}} = 0\]
\[\displaystyle [36]\text{ }{\mathbf{spend}}_{{usd},{seattle-chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 153.0 \cdot {\mathbf{{opr}}}_{{channel},{seattle-chicago},{{{t0}_{0}}}} = 0\]
\[\displaystyle [38]\text{ }{\mathbf{{impt}}}_{{r},{seattle-chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 1.0 \cdot {\mathbf{{opr}}}_{{channel},{seattle-chicago},{{{t0}_{0}}}} = 0\]
\[\displaystyle [39]\text{ }{\mathbf{{expt}}}_{{r},{seattle-chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 1.0 \cdot {\mathbf{{opr}}}_{{channel},{seattle-chicago},{{{t0}_{0}}}} = 0\]
\[\displaystyle [40]\text{ }{\mathbf{spend}}_{{usd},{seattle-topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 162.0 \cdot {\mathbf{{opr}}}_{{channel},{seattle-topeka},{{{t0}_{0}}}} = 0\]
\[\displaystyle [42]\text{ }{\mathbf{{impt}}}_{{r},{seattle-topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 1.0 \cdot {\mathbf{{opr}}}_{{channel},{seattle-topeka},{{{t0}_{0}}}} = 0\]
\[\displaystyle [43]\text{ }{\mathbf{{expt}}}_{{r},{seattle-topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 1.0 \cdot {\mathbf{{opr}}}_{{channel},{seattle-topeka},{{{t0}_{0}}}} = 0\]
\[\displaystyle [44]\text{ }{\mathbf{spend}}_{{usd},{sandiego-newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 225.0 \cdot {\mathbf{{opr}}}_{{channel},{sandiego-newyork},{{{t0}_{0}}}} = 0\]
\[\displaystyle [46]\text{ }{\mathbf{{impt}}}_{{r},{sandiego-newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 1.0 \cdot {\mathbf{{opr}}}_{{channel},{sandiego-newyork},{{{t0}_{0}}}} = 0\]
\[\displaystyle [47]\text{ }{\mathbf{{expt}}}_{{r},{sandiego-newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 1.0 \cdot {\mathbf{{opr}}}_{{channel},{sandiego-newyork},{{{t0}_{0}}}} = 0\]
\[\displaystyle [48]\text{ }{\mathbf{spend}}_{{usd},{sandiego-chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 162.0 \cdot {\mathbf{{opr}}}_{{channel},{sandiego-chicago},{{{t0}_{0}}}} = 0\]
\[\displaystyle [50]\text{ }{\mathbf{{impt}}}_{{r},{sandiego-chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 1.0 \cdot {\mathbf{{opr}}}_{{channel},{sandiego-chicago},{{{t0}_{0}}}} = 0\]
\[\displaystyle [51]\text{ }{\mathbf{{expt}}}_{{r},{sandiego-chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 1.0 \cdot {\mathbf{{opr}}}_{{channel},{sandiego-chicago},{{{t0}_{0}}}} = 0\]
\[\displaystyle [52]\text{ }{\mathbf{spend}}_{{usd},{sandiego-topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 125.99999999999999 \cdot {\mathbf{{opr}}}_{{channel},{sandiego-topeka},{{{t0}_{0}}}} = 0\]
\[\displaystyle [54]\text{ }{\mathbf{{impt}}}_{{r},{sandiego-topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 1.0 \cdot {\mathbf{{opr}}}_{{channel},{sandiego-topeka},{{{t0}_{0}}}} = 0\]
\[\displaystyle [55]\text{ }{\mathbf{{expt}}}_{{r},{sandiego-topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}} - 1.0 \cdot {\mathbf{{opr}}}_{{channel},{sandiego-topeka},{{{t0}_{0}}}} = 0\]

Mapping Constraints

\[\displaystyle [10]\text{ }{\mathbf{{opr}}}_{{purchase},{ntw},{{{t0}_{0}}}} - {\mathbf{{opr}}}_{{purchase},{seattle},{{{t0}_{0}}}} - {\mathbf{{opr}}}_{{purchase},{sandiego},{{{t0}_{0}}}} = 0\]
\[\displaystyle [19]\text{ }{\mathbf{{opr}}}_{{dispatch},{ntw},{{{t0}_{0}}}} - {\mathbf{{opr}}}_{{dispatch},{newyork},{{{t0}_{0}}}} - {\mathbf{{opr}}}_{{dispatch},{chicago},{{{t0}_{0}}}} - {\mathbf{{opr}}}_{{dispatch},{topeka},{{{t0}_{0}}}} = 0\]

Optimize!#

The model can now be optimized

m.usd.spend.opt()
🧭  Mapped space for spend (usd, seattle-newyork, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0002 s
🧭  Mapped space for spend (usd, seattle-newyork, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0002 s
🧭  Mapped space for spend (usd, seattle-newyork, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, seattle-newyork, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0002 s
🧭  Mapped space for spend (usd, seattle-newyork, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, seattle-chicago, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0002 s
🧭  Mapped space for spend (usd, seattle-chicago, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0002 s
🧭  Mapped space for spend (usd, seattle-chicago, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, seattle-chicago, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, seattle-chicago, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0002 s
🧭  Mapped space for spend (usd, seattle-topeka, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, seattle-topeka, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, seattle-topeka, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, seattle-topeka, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, seattle-topeka, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, sandiego-newyork, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, sandiego-newyork, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, sandiego-newyork, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, sandiego-newyork, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, sandiego-newyork, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0002 s
🧭  Mapped space for spend (usd, sandiego-chicago, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, sandiego-chicago, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0003 s
🧭  Mapped space for spend (usd, sandiego-chicago, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, sandiego-chicago, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, sandiego-chicago, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, sandiego-topeka, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0002 s
🧭  Mapped space for spend (usd, sandiego-topeka, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, sandiego-topeka, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0002 s
🧭  Mapped space for spend (usd, sandiego-topeka, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
🧭  Mapped space for spend (usd, sandiego-topeka, t0, operate, channel) ⟺ (usd, ntw, t0) ⏱ 0.0001 s
📝  Generated Program(m).mps                                                 ⏱ 0.0026 s
Read MPS format model from file Program(m).mps
Reading time = 0.00 seconds
PROGRAM(M): 57 rows, 58 columns, 124 nonzeros
📝  Generated gurobipy model. See .formulation                               ⏱ 0.0046 s
Gurobi Optimizer version 12.0.3 build v12.0.3rc0 (win64 - Windows 11.0 (26100.2))

CPU model: 13th Gen Intel(R) Core(TM) i7-13700, instruction set [SSE2|AVX|AVX2]
Thread count: 16 physical cores, 24 logical processors, using up to 24 threads

Optimize a model with 57 rows, 58 columns and 124 nonzeros
Model fingerprint: 0x3106ff68
Coefficient statistics:
  Matrix range     [1e+00, 2e+02]
  Objective range  [1e+00, 1e+00]
  Bounds range     [0e+00, 0e+00]
  RHS range        [3e+02, 6e+02]
Presolve removed 52 rows and 52 columns
Presolve time: 0.00s
Presolved: 5 rows, 6 columns, 12 nonzeros

Iteration    Objective       Primal Inf.    Dual Inf.      Time
       0    0.0000000e+00   1.125000e+02   0.000000e+00      0s
       4    1.5367500e+05   0.000000e+00   0.000000e+00      0s

Solved in 4 iterations and 0.00 seconds (0.00 work units)
Optimal objective  1.536750000e+05
📝  Generated Solution object for Program(m). See .solution                  ⏱ 0.0003 s
✅  Program(m) optimized using gurobi. Display using .output()               ⏱ 0.0117 s

Solution#

The solution pertaining to each aspect can be accessed individually.

For the whole solution, use Model.output()

Seattle serves New York and Chicago

Sandiego serves New York and Topeka

m.ship_in.output()
\[\displaystyle {\mathbf{{impt}}}_{{r},{seattle-newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=50.0\]
\[\displaystyle {\mathbf{{impt}}}_{{r},{seattle-chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=300.0\]
\[\displaystyle {\mathbf{{impt}}}_{{r},{seattle-topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=0.0\]
\[\displaystyle {\mathbf{{impt}}}_{{r},{sandiego-newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=275.0\]
\[\displaystyle {\mathbf{{impt}}}_{{r},{sandiego-chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=0.0\]
\[\displaystyle {\mathbf{{impt}}}_{{r},{sandiego-topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=275.0\]

Exports (\(\mathbf{expt}\)) and Imports (\(\mathbf{impt}\)) should match!

m.ship_out.output()
\[\displaystyle {\mathbf{{expt}}}_{{r},{seattle-newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=50.0\]
\[\displaystyle {\mathbf{{expt}}}_{{r},{seattle-chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=300.0\]
\[\displaystyle {\mathbf{{expt}}}_{{r},{seattle-topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=0.0\]
\[\displaystyle {\mathbf{{expt}}}_{{r},{sandiego-newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=275.0\]
\[\displaystyle {\mathbf{{expt}}}_{{r},{sandiego-chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=0.0\]
\[\displaystyle {\mathbf{{expt}}}_{{r},{sandiego-topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=275.0\]

Contribution to overall cost can be ascertained

m.spend.output()
\[\displaystyle {\mathbf{spend}}_{{usd},{seattle-newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=11250.0\]
\[\displaystyle {\mathbf{spend}}_{{usd},{seattle-chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=45900.0\]
\[\displaystyle {\mathbf{spend}}_{{usd},{seattle-topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=0.0\]
\[\displaystyle {\mathbf{spend}}_{{usd},{sandiego-newyork},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=61875.0\]
\[\displaystyle {\mathbf{spend}}_{{usd},{sandiego-chicago},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=0.0\]
\[\displaystyle {\mathbf{spend}}_{{usd},{sandiego-topeka},{{{t0}_{0}}},{\mathbf{{opr}}},{channel}}=34649.99999999999\]
\[\displaystyle {\mathbf{spend}}_{{usd},{ntw},{{{t0}_{0}}}}=153675.0\]

Solution as Dictionary#

m.solution.asdict()
{'consume': [350.0, 550.0],
 'release': [325.0, 300.0, 275.0],
 'operate': [900.0,
  900.0,
  350.0,
  550.0,
  325.0,
  300.0,
  275.0,
  50.0,
  300.0,
  0.0,
  275.0,
  0.0,
  275.0],
 'capacity': [350.0,
  550.0,
  325.0,
  300.0,
  275.0,
  50.0,
  300.0,
  0.0,
  275.0,
  0.0,
  275.0],
 'produce': [350.0, 550.0, 325.0, 300.0, 275.0],
 'expend': [350.0, 550.0, 325.0, 300.0, 275.0],
 'spend': [11250.0, 45900.0, 0.0, 61875.0, 0.0, 34649.99999999999, 153675.0],
 'ship_in': [50.0, 300.0, 0.0, 275.0, 0.0, 275.0],
 'ship_out': [50.0, 300.0, 0.0, 275.0, 0.0, 275.0]}