tag:blogger.com,1999:blog-5935635338347064862024-03-17T23:02:35.082-04:00Yet Another Math Programming ConsultantI am a full-time consultant and provide services related to the design, implementation and deployment of mathematical programming, optimization and data-science applications. I also teach courses and workshops. Usually I cannot blog about projects I am doing, but there are many technical notes I'd like to share. Not in the least so I have an easy way to search and find them again myself. You can reach me at <a href="mailto:erwin@amsterdamoptimization.com">erwin@amsterdamoptimization.com</a>.Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.comBlogger1422125tag:blogger.com,1999:blog-593563533834706486.post-35919120064428031602024-02-10T11:58:00.006-05:002024-02-27T19:38:07.887-05:00Math vs Programming<p> A programmer writes about this blog:</p><p><br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgfFT6HGg3kh9P_h-ZQGdAC6-ygD5OZWXbAqt84Owa1UljxWdfXykJTjnTXk7DwuHPJjedpvgxD1r1XA6qvgWAWCUiZvKgWqMoh9dlAa8oaP39xQ76PR2hA8lB0iJUi7kkyOdeDd0Unf0qTM36MVJ2KC-WyJe3RW8R7zzoRxA62yLW8AqM08Q6iAXt6Zfzh" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="317" data-original-width="802" src="https://blogger.googleusercontent.com/img/a/AVvXsEgfFT6HGg3kh9P_h-ZQGdAC6-ygD5OZWXbAqt84Owa1UljxWdfXykJTjnTXk7DwuHPJjedpvgxD1r1XA6qvgWAWCUiZvKgWqMoh9dlAa8oaP39xQ76PR2hA8lB0iJUi7kkyOdeDd0Unf0qTM36MVJ2KC-WyJe3RW8R7zzoRxA62yLW8AqM08Q6iAXt6Zfzh=s16000" /></a></div><br />(It is old, but I just came across this).<div><br /><div>In my <a href="https://yetanothermathprogrammingconsultant.blogspot.com/2024/02/small-non-convex-minlp-pyomo-vs-gams.html" target="_blank">previous post</a>, I just argued the other way around. To make sure: I don't hate programmers.<p></p></div></div><div>BTW, in quite a few programming languages for loops are very slow, and need to be replaced by something like <b>sum()</b>. Examples: Python, R, SQL. </div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com1tag:blogger.com,1999:blog-593563533834706486.post-23508225868566767292024-02-08T17:28:00.011-05:002024-02-14T17:55:50.478-05:00Small non-convex MINLP: Pyomo vs GAMS<script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style><p> In [1], the following Pyomo model (Python fragment) is presented:</p><p><br /></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">model.x = Var(name=<span style="color: blue;">"Number of batches"</span>, domain=NonNegativeIntegers, initialize=<span style="color: blue;">10</span>)
model.a = Var(name=<span style="color: blue;">"Batch Size"</span>, domain=NonNegativeIntegers, bounds=(<span style="color: blue;">5</span>,<span style="color: blue;">20</span>))
<span style="color: #008800; font-style: italic;"># Objective function</span>
<span style="color: navy; font-weight: bold;">def</span> total_production(model):
<span style="color: navy; font-weight: bold;">return</span> model.x * model.a
model.total_production = Objective(rule=total_production, sense=minimize)
<span style="color: #008800; font-style: italic;"># Constraints</span>
<span style="color: #008800; font-style: italic;"># Minimum production of the two output products</span>
<span style="color: navy; font-weight: bold;">def</span> first_material_constraint_rule(model):
<span style="color: navy; font-weight: bold;">return</span> sum(<span style="color: blue;">0.2</span> * model.a * i <span style="color: navy; font-weight: bold;">for</span> i <span style="font-weight: bold;">in</span> range(<span style="color: blue;">1</span>, value(model.x)+<span style="color: blue;">1</span>)) >= <span style="color: blue;">70</span>
model.first_material_constraint = Constraint(rule=first_material_constraint_rule)
<span style="color: navy; font-weight: bold;">def</span> second_material_constraint_rule(model):
<span style="color: navy; font-weight: bold;">return</span> sum(<span style="color: blue;">0.8</span> * model.a * i <span style="color: navy; font-weight: bold;">for</span> i <span style="font-weight: bold;">in</span> range(<span style="color: blue;">1</span>, value(model.x)+<span style="color: blue;">1</span>)) >= <span style="color: blue;">90</span>
model.second_material_constraint = Constraint(rule=second_material_constraint_rule)
<span style="color: #008800; font-style: italic;"># At least one production run</span>
<span style="color: navy; font-weight: bold;">def</span> min_production_rule(model):
<span style="color: navy; font-weight: bold;">return</span> model.x >= <span style="color: blue;">1</span>
model.min_production = Constraint(rule=min_production_rule)
</pre></div>
<br />
<span><a name='more'></a></span>This is a little bit incomplete: we miss imports, creating the model and a solve. However, we can see some real problematic issues here. The main problem is the use of <span style="font-family: courier;">value(model.x)</span> inside a constraint. This is almost never intended, as this evaluates the initial point and not the current value during optimization. In GAMS terms, this is using <span style="font-family: courier;">x.L</span> inside a constraint instead of <span style="font-family: courier;">x</span>. I have seen this Pyomo mistake several times, and I think this is not very well explained and emphasized in the documentation. Pyomo constraints are generated before the solver gets involved, and some constructs are evaluated during that phase, instead of inside the solver. A difficult concept. A good way to see how the model passed on to the solver looks like is to print the scalar version using <span style="font-family: courier;">model.pprint()</span>:<div><br /></div><div><br />
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: blue;">2</span> Var Declarations
a : Size=<span style="color: blue;">1</span>, Index=None
Key : Lower : Value : Upper : Fixed : Stale : Domain
None : <span style="color: blue;">5</span> : None : <span style="color: blue;">20</span> : False : True : NonNegativeIntegers
x : Size=<span style="color: blue;">1</span>, Index=None
Key : Lower : Value : Upper : Fixed : Stale : Domain
None : <span style="color: blue;">0</span> : <span style="color: blue;">10</span> : None : False : False : NonNegativeIntegers
<span style="color: blue;">1</span> Objective Declarations
total_production : Size=<span style="color: blue;">1</span>, Index=None, Active=True
Key : Active : Sense : Expression
None : True : minimize : x*a
<span style="color: blue;">3</span> Constraint Declarations
first_material_constraint : Size=<span style="color: blue;">1</span>, Index=None, Active=True
Key : Lower : Body : Upper : Active
None : <span style="color: blue;">70.0</span> : <span style="color: blue;">0.2</span>*a + <span style="color: blue;">0.4</span>*a + <span style="color: blue;">0.6000000000000001</span>*a + <span style="color: blue;">0.8</span>*a + a + <span style="color: blue;">1.2000000000000002</span>*a + <span style="color: blue;">1.4000000000000001</span>*a + <span style="color: blue;">1.6</span>*a + <span style="color: blue;">1.8</span>*a + <span style="color: blue;">2.0</span>*a : +Inf : True
min_production : Size=<span style="color: blue;">1</span>, Index=None, Active=True
Key : Lower : Body : Upper : Active
None : <span style="color: blue;">1.0</span> : x : +Inf : True
second_material_constraint : Size=<span style="color: blue;">1</span>, Index=None, Active=True
Key : Lower : Body : Upper : Active
None : <span style="color: blue;">90.0</span> : <span style="color: blue;">0.8</span>*a + <span style="color: blue;">1.6</span>*a + <span style="color: blue;">2.4000000000000004</span>*a + <span style="color: blue;">3.2</span>*a + <span style="color: blue;">4.0</span>*a + <span style="color: blue;">4.800000000000001</span>*a + <span style="color: blue;">5.6000000000000005</span>*a + <span style="color: blue;">6.4</span>*a + <span style="color: blue;">7.2</span>*a + <span style="color: blue;">8.0</span>*a : +Inf : True
<span style="color: blue;">6</span> Declarations: x a total_production first_material_constraint second_material_constraint min_production
</pre></div>
<br />
We can see that these summations in the constraints are based on the initial value \(\color{darkred}x^{\mathrm{init}} = 10\): ten terms are being generated. We also see that the \(\color{darkred}x\) variable itself has disappeared. Note that <span style="font-family: courier;">range(p,q)</span><span style="font-family: inherit;">in Python translates to something like \(p,\dots,q-1\).</span></div><div><span style="font-family: inherit;"><br /></span></div><div><span style="font-family: inherit;"><div>As Pyomo models are often somewhat difficult to read due to the large amount of "noise" (all kinds of syntactic stuff causing a low signal-to-noise ratio), it is a good idea to look at a mathematical model. </div><div><br /></div></span></div><div>The first constraint in Pyomo can be read as: \[\sum_{i=1}^{\color{darkred}x} 0.2\cdot\color{darkred}a \cdot i \ge 70\] A slight rewrite is: \[0.2\cdot\color{darkred}a \cdot (1+\dots+\color{darkred}x) \ge 70\] Summations with a variable upper bound are not that easy to handle with modeling tools. Often, we use a series of binary variables. Below I use a different technique. </div><div><br /></div><div><br /></div>
<table class="blueTable"><thead><tr><th>Original Pyomo Model</th></tr></thead><tbody><tr><td>\[\begin{align} \min\> & \color{darkred}a\cdot \color{darkred}x \\ & 0.2\cdot \color{darkred}a\cdot (1+\dots+\color{darkred}x) \ge 70\\ & 0.8\cdot \color{darkred}a\cdot (1+\dots+\color{darkred}x) \ge 90 \\ & \color{darkred}a \in \{5,\dots,20\} \\ & \color{darkred}x \in \{1,2,\dots\} \end{align}\]</td></tr></tbody></table>
<br />The constraints look a bit strange. I have never seen production limits like that. It says the \(i^\mathrm{th}\) batch has a yield proportional to \(i\). I really suspect this model is just not properly formulated. The logic being buried in Python code may have contributed to this. But anyway, we can substantially simplify this:
<br /><br />
<table class="blueTable"><thead><tr><th>Cleaned-up Model</th></tr></thead><tbody><tr><td>\[\begin{align} \min\> & \color{darkred}a\cdot \color{darkred}x \\ & \color{darkred}a\cdot \color{darkred}x \cdot (\color{darkred}x+1) \ge 2\cdot \max\{70/0.2,90/0.8\}\\ & \color{darkred}a \in \{5,\dots,20\} \\ & \color{darkred}x \in \{1,2,\dots\} \end{align}\]</td></tr></tbody></table>
<div><br /></div>We use here \[1+\dots+n = \frac{n\cdot(n+1)}{2}\] We replaced the summation with a variable upper bound to something that is much easier to handle inside a constraint. This is now easy to write down in GAMS:
<div><br /></div><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">variable </span></b><span style="font-family: Consolas; font-size: 10.5pt;">z </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'objective<span class="GramE">'<span style="color: black;">;</span></span></span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">integer variables</span></b></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">x </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'Number of batches'</span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">a </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'Batch size'</span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">x.lo</span></span><span style="font-family: Consolas; font-size: 10.5pt;"> = <span class="GramE">1;</span></span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">a.lo</span></span></span><span style="font-family: Consolas; font-size: 10.5pt;"> = 5;</span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">a.up</span></span></span><span style="font-family: Consolas; font-size: 10.5pt;"> = 20;</span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Equations</span></b></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">obj </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'objective'</span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">limit </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'minimum <span class="GramE">production'</span></span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">obj..</span></span><span style="font-family: Consolas; font-size: 10.5pt;"> z =e= a*<span class="GramE">x;</span></span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">limit..</span></span><span style="font-family: Consolas; font-size: 10.5pt;"> a*x*(x+1) =g= 2*</span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">max</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span style="font-family: Consolas; font-size: 10.5pt;">70/0.2,90/0.8);</span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">model </span></b><span style="font-family: Consolas; font-size: 10.5pt;">m</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /all<span class="GramE">/<span style="color: black;">;</span></span></span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">option</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">minlp</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">=<span class="GramE">baron;</span></span></p></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">solve</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> m </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">using</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">minlp</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">;</span></span></p></div></blockquote>
<br /><br />When dealing with a real model, I would store the numbers in the <span style="font-family: courier;">limit</span> equation in parameters. That would give them a (meaningful) name. <div><br /></div><div>We solve with a global MINLP solver as the problem is non-convex. This gives:</div><div><br /><div>
<br />
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"> LOWER LEVEL UPPER MARGINAL
---- EQU obj . . . <span style="color: blue;">1.0000</span>
---- EQU limit <span style="color: blue;">700.0000</span> <span style="color: blue;">780.0000</span> +INF .
obj objective
limit minimum production
LOWER LEVEL UPPER MARGINAL
---- VAR z -INF <span style="color: blue;">60.0000</span> +INF .
---- VAR x <span style="color: blue;">1.0000</span> <span style="color: blue;">12.0000</span> +INF <span style="color: blue;">5.0000</span>
---- VAR a <span style="color: blue;">5.0000</span> <span style="color: blue;">5.0000</span> <span style="color: blue;">20.0000</span> <span style="color: blue;">12.0000</span>
z objective
x Number of batches
a Batch size
</pre></div>
<br />
</div><div>This is a tiny model, so it does not take any time.</div><div><br /></div><div><br /></div><h3 style="text-align: left;">Conclusion</h3><div><br /></div><div>The original Pyomo model was a bit of a mess. There is a bit of a dichotomy between the Python language and math. And between what Python sees and what the underlying solvers see. What makes sense in Python, may not make sense in a Pyomo constraint. We can fix this easily by taking a step back from Python and look at the math. Sometimes Python code is just not at the right abstraction level for proper reasoning. As a result, new users may be totally lost even if they are proficient Python programmers. </div><div><br /></div><div>Models, whether implemented in a modeling language or a programming language, have two intended audiences: (1) the machine, or the solver if you want and (2) human readers such as colleagues, successors, or yourself. The latter group is arguably more important. But often, a readable model also has better changes to be correct and faster to solve. Just because it is easier to reason about it. This makes it the more important that model logic is written in a way, so that it is structure-revealing. Hopefully, for a well-written model, we don't need to re-engineer the math, like we did in this example. </div><div> </div><h3 style="text-align: left;">References</h3><div><br /></div><div><ol style="text-align: left;"><li>Pyomo constraints to enforce integer variables, <a href="https://stackoverflow.com/questions/77958306/pyomo-constraints-to-enforce-integer-variables">https://stackoverflow.com/questions/77958306/pyomo-constraints-to-enforce-integer-variables</a></li></ol></div></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com0tag:blogger.com,1999:blog-593563533834706486.post-11460699820813505802024-01-30T08:10:00.007-05:002024-02-06T10:09:31.018-05:00One nonzero in set of free variables<script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style>In [1] the following question is posed:<div><br /></div><div><blockquote>I have free variables \(\color{darkred}x_i\). How can I impose the constraint that at least one of the variables is nonzero: \(\color{darkred}x_i\ne 0\).</blockquote><span><a name='more'></a></span><p><br /></p><h3 style="text-align: left;">Observations and formulations</h3><p><br /></p><p></p><ul style="text-align: left;"><li>\(\color{darkred}x_i\ne 0\) is somewhat difficult. We need to write this as \[\begin{align}&\color{darkred}x_i\le -\color{darkblue}\epsilon \\ & \textbf{or} \\ & \color{darkred}x_i\ge \color{darkblue}\epsilon\end{align}\] Here \(\color{darkblue}\epsilon\gt 0\) is a small constant. This "or"-type of constraint needs a binary variable (or something similar). It can't be modeled in a pure LP setting. (We have some non-convexity here).</li><li>The constant \(\color{darkblue}\epsilon\) should not be too small, as the solver will use some <b>feasibility tolerances</b>. These tolerances are, in general, absolute (i.e. not relative). As the solver typically applies some <b>scaling</b>, this tolerance may be even larger than you think (in terms of the original constraints). And who knows what the impact of preprocessing is. I sometimes see modelers using using something like \(\color{darkblue}\epsilon = \textrm{1e-6}\). This looks too small for me. I typically use something like 0.001 or 0.0001. Of course, this depends on the order of magnitudes of the values that \(\color{darkred}x_i\) can assume. </li><li>We can split each \(\color{darkred}x_i\) into three regions: \(\lt 0, = 0, \gt 0\). An intuitive way to write this down is using <b>indicator constraints</b>: \[\begin{align}&\color{darkred}\delta_{i,1}=1 \implies \color{darkred}x_i \le -\color{darkblue}\epsilon\\ & \color{darkred}\delta_{i,2}=1 \implies -\color{darkblue}\epsilon \le \color{darkred}x_i \le \color{darkblue}\epsilon \\ &\color{darkred}\delta_{i,3}=1 \implies \color{darkred}x_i \ge \color{darkblue}\epsilon \\ & \sum_r \color{darkred}\delta_{i,r} = 1 &&\forall i \\ & \sum_i (\color{darkred}\delta_{i,1}+\color{darkred}\delta_{i,3})\ge 1\\ & \color{darkred}\delta_{i,r} \in \{0,1\} \end{align} \] The middle implication usually needs to be implemented as two constraints. Note that at the points \(\color{darkred}x_i = \pm \color{darkblue}\epsilon\) we have a bit of ambiguity. In practice, that is not a bad thing: let the solver determine the most profitable region for those cases. The last constraint can also be stated as \[\sum_i \color{darkred}\delta_{i,2}\le \color{darkblue}n-1\] where \(\color{darkblue}n\) is the size of set \(i \in I\), i.e., \(\color{darkblue}n=|I|\).</li><li>Unfortunately, not all modeling tools and solvers support indicator constraints. They really should, as this is a useful modeling concept. If we have good, tight bounds \(\color{darkred}x_i \in [\color{darkblue}L_i,\color{darkblue}U_i]\), with \(\color{darkblue}L_i \lt 0\), then we can use <b>binary variables. </b>Here is a possible formulation: \[\begin{align}&\color{darkred}x_i \le -\color{darkblue}\epsilon \cdot \color{darkred}\delta_{i,1} + \color{darkblue}U_i \cdot (1-\color{darkred}\delta_{i,1})\\ & \color{darkred}x_i \ge -\color{darkblue}\epsilon \cdot \color{darkred}\delta_{i,2} + \color{darkblue}L_i \cdot (1-\color{darkred}\delta_{i,2})\\ & \color{darkred}x_i \le \color{darkblue}\epsilon \cdot \color{darkred}\delta_{i,2} + \color{darkblue}U_i \cdot (1-\color{darkred}\delta_{i,2}) \\ & \color{darkred}x_i \ge \color{darkblue}\epsilon \cdot \color{darkred}\delta_{i,3} + \color{darkblue}L_i\cdot (1-\color{darkred}\delta_{i,3}) \\ & \sum_r \color{darkred}\delta_{i,r} = 1 &&\forall i\\ & \sum_i (\color{darkred}\delta_{i,1}+\color{darkred}\delta_{i,3})\ge 1 \\ & \color{darkred}\delta_{i,r} \in \{0,1\} \end{align} \]</li><li>If we don't have good bounds on \(\color{darkred}x_i\) and no indicator constraints, we can use so-called <b>Special Ordered Sets of Type 1</b> (a.k.a. SOS1 sets). A high-level model can look like: \[\begin{align}& |\color{darkred}x_i| \ge \color{darkblue}\epsilon \cdot \color{darkred}\gamma_i \\ & \sum_i \color{darkred}\gamma_i \ge 1 & \\ & \color{darkred}\gamma_i \in \{0,1\} \end{align}\] The non-convex absolute value constraint can be modeled as: \[\begin{align}&\color{darkred}y_i^+ - \color{darkred}y_i^- = \color{darkred}x_i \\ &\color{darkred}y_i^+ + \color{darkred}y_i^- \ge \color{darkblue}\epsilon \cdot \color{darkred}\gamma_i \\ & \color{darkred}y_i^+, \color{darkred}y_i^- \ge 0 \\ & \color{darkred}y_i^+, \color{darkred}y_i^- \in \textbf{SOS1}\end{align}\] I.e., we have \(\color{darkblue}n=|I|\) SOS1 sets with two members each. The SOS1 sets ensures that only one of \(\color{darkred}y_i^+, \color{darkred}y_i^-\) can be nonzero. This construct does the same thing as a complementarity condition \[\color{darkred}y_i^+ \cdot \color{darkred}y_i^- = 0\] We can also simulate indicator constraints directly using SOS1 sets.</li><li>In [1], I suggested somewhat of a <b>hack</b>. I should not have mentioned that. Let me explain. Instead of checking each \(\color{darkred}x_i\), we can try to do \[\color{darkred}y = \sum_i \color{darkred}x_i\] Now we just require: \(\color{darkred}y\ne 0\). That will force some \(\color{darkred}x_i \ne 0\). Note that the reverse is not true: if \(\color{darkred}y=0\), we not necessarily have that all \(\color{darkred}x_i = 0\). E.g. consider: \[\begin{align}&\color{darkred}x_1 = -1\\&\color{darkred}x_2 = +1\\&\color{darkred}x_i = 0 && i\ge 3\end{align}\] This solution would be cut off as \[\color{darkred}y = \sum_i \color{darkred}x_i = 0\] while it obeys our original requirement of at least one \(\color{darkred}x_i\ne 0\). Clearly, no free lunch here. The only reason to use this formulation is when using discrete variables for each \(\color{darkred}x_i\) is prohibitively expensive.</li></ul><h4 style="text-align: left;"><br /></h4><h3 style="text-align: left;">Numerical experiment</h3><div><br /></div><div>Let's try out these 4 formulations with the following objective: \[\min \color{darkred}z=\sum_i \color{darkred}x_i^2\] Hopefully, just one \(\color{darkred}x_i\) will be nonzero.</div><div><br /></div><div>Model 1 with <b>indicator constraints</b> does the right thing:</div><div><br /></div><div><br />
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">90</span> <span style="color: #333333;">****</span> model <span style="color: #0000dd; font-weight: bold;">1</span>: indicator constraints <span style="color: #333333;">****</span>
PARAMETER <b>epsilon </b><span style="color: #333333;">=</span> <span style="color: #6600ee; font-weight: bold;">0.001</span> <i>larger than feasibility tolerance
</i>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">90</span> VARIABLE <b>x</b><span style="color: #333333;">.</span>L <i> free variables</i>
i3 <span style="color: #6600ee; font-weight: bold;">0.001</span>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">90</span> VARIABLE <b>delta</b><span style="color: #333333;">.</span>L <i>binary indicator variable (indicates region)</i>
region2 region3
i1 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i2 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i3 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i4 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i5 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i6 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i7 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i8 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i9 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i10 <span style="color: #6600ee; font-weight: bold;">1.000</span>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">90</span> VARIABLE <b>z</b><span style="color: #333333;">.</span>L <span style="color: #333333;">=</span> <span style="color: #6600ee; font-weight: bold;">1.000000E-6</span> <i>objective variable</i>
</pre></div>
</div><div><br /></div><div>The main issue with the implementation is that GAMS does not support indicator constraints very well. It is a bit of a half-baked functionality. Firstly, a solver option file should not change the meaning of a model. Secondly, the option file reader is too primitive to handle practical cases without using some hacks. If you take integer programming seriously, you really must take indicator constraints seriously. This will be illustrated below.</div><div><br /></div><div>The second model with<b> binary variables </b>is interesting. We get incorrect results depending on the exact value of \(\color{darkblue}\epsilon\). We try the model with \(\color{darkblue}\epsilon=0.001, 0.01, 0.1\), and fixed bounds \(-1000 \le \color{darkred}x_i \le 1000\). Only for \(\color{darkblue}\epsilon=0.1\) do we get correct results! I did not expect this: I thought my values for the bounds and for \(\color{darkblue}\epsilon\) were sufficiently conservative.</div><div><br /></div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">120</span> <span style="color: #333333;">****</span> model <span style="color: #0000dd; font-weight: bold;">2</span>: binary variables <span style="color: #333333;">****</span>
PARAMETER <b>epsilon</b> <span style="color: #333333;">=</span> <span style="color: #6600ee; font-weight: bold;">0.001</span> <i>larger than feasibility tolerance
</i>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">120</span> VARIABLE <b>x</b><span style="color: #333333;">.</span>L <i>free variables
</i>
( ALL <span style="color: #6600ee; font-weight: bold;">0.000</span> )
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">120</span> VARIABLE <b>delta</b><span style="color: #333333;">.</span>L <i> binary indicator variable (indicates region)</i>
region1 region2 region3
i1 <span style="color: #6600ee; font-weight: bold;">9.999990E-7</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i2 <span style="color: #6600ee; font-weight: bold;">1.000</span> <span style="color: #6600ee; font-weight: bold;">9.999990E-7</span>
i3 <span style="color: #6600ee; font-weight: bold;">9.999990E-7</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i4 <span style="color: #6600ee; font-weight: bold;">9.999990E-7</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i5 <span style="color: #6600ee; font-weight: bold;">9.999990E-7</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i6 <span style="color: #6600ee; font-weight: bold;">9.999990E-7</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i7 <span style="color: #6600ee; font-weight: bold;">9.999990E-7</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i8 <span style="color: #6600ee; font-weight: bold;">9.999990E-7</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i9 <span style="color: #6600ee; font-weight: bold;">9.999990E-7</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i10 <span style="color: #6600ee; font-weight: bold;">9.999990E-7</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">120</span> VARIABLE <b>z</b><span style="color: #333333;">.</span>L <span style="color: #333333;">=</span> <span style="color: #6600ee; font-weight: bold;">0.000</span> <i>objective variable</i>
<span style="color: #333333;">======================================</span>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">124</span> <span style="color: #333333;">****</span> model <span style="color: #0000dd; font-weight: bold;">2</span>: binary variables <span style="color: #333333;">****</span>
PARAMETER <b>epsilon</b> <span style="color: #333333;">=</span> <span style="color: #6600ee; font-weight: bold;">0.010</span> <i>larger than feasibility tolerance</i>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">124</span> VARIABLE <b>x</b><span style="color: #333333;">.</span>L <i>free variables</i>
( ALL <span style="color: #6600ee; font-weight: bold;">0.000</span> )
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">124</span> VARIABLE <b>delta</b><span style="color: #333333;">.</span>L <i>binary indicator variable (indicates region)
</i>
region1 region3
i1 <span style="color: #6600ee; font-weight: bold;">9.999900E-6</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i2 <span style="color: #6600ee; font-weight: bold;">9.999900E-6</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i3 <span style="color: #6600ee; font-weight: bold;">9.999900E-6</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i4 <span style="color: #6600ee; font-weight: bold;">9.999900E-6</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i5 <span style="color: #6600ee; font-weight: bold;">9.999900E-6</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i6 <span style="color: #6600ee; font-weight: bold;">9.999900E-6</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i7 <span style="color: #6600ee; font-weight: bold;">9.999900E-6</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i8 <span style="color: #6600ee; font-weight: bold;">9.999900E-6</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i9 <span style="color: #6600ee; font-weight: bold;">9.999900E-6</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
i10 <span style="color: #6600ee; font-weight: bold;">9.999900E-6</span> <span style="color: #6600ee; font-weight: bold;">1.000</span>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">124</span> VARIABLE <b>z</b><span style="color: #333333;">.</span>L <span style="color: #333333;">=</span> <span style="color: #6600ee; font-weight: bold;">0.000</span> <i>objective variable</i>
<span style="color: #333333;">======================================</span>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">128</span> <span style="color: #333333;">****</span> model <span style="color: #0000dd; font-weight: bold;">2</span>: binary variables <span style="color: #333333;">****</span>
PARAMETER <b>epsilon</b> <span style="color: #333333;">=</span> <span style="color: #6600ee; font-weight: bold;">0.100</span> <i>larger than feasibility tolerance</i>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">128</span> VARIABLE <b>x</b><span style="color: #333333;">.</span>L <i>free variables</i>
i10 <span style="color: #6600ee; font-weight: bold;">0.100</span>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">128</span> VARIABLE <b>delta</b><span style="color: #333333;">.</span>L <i>binary indicator variable (indicates region)</i>
region2 region3
i1 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i2 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i3 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i4 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i5 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i6 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i7 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i8 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i9 <span style="color: #6600ee; font-weight: bold;">1.000</span>
i10 <span style="color: #6600ee; font-weight: bold;">1.000</span>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">128</span> VARIABLE <b>z</b><span style="color: #333333;">.</span>L <span style="color: #333333;">=</span> <span style="color: #6600ee; font-weight: bold;">0.010</span> <i>objective variable</i>
</pre></div>
<div><br /></div><div>The bounds are quite reasonable. But nevertheless, we observe numerical issues. Very small values in the binary variable \(\color{darkred}\delta_{i,r}\) cause feasible solutions that actually don't make sense. We can play with the (feasibility) tolerances or with the bounds. Here, I just adjusted the size of \(\color{darkblue}\epsilon\). We get proper solutions only after increasing it to 0.1 (!!!). </div><div><br /></div><div>This is a somewhat extreme example of how Big-M constraints with binary variables can cause serious problems. However, indicator constraints can really help. They are not only a tool to help modeling but also can improve numerics. </div><div><br /></div><div>The <b>SOS1 model</b> is also working correctly:</div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">157</span> <span style="color: #333333;">****</span> model <span style="color: #0000dd; font-weight: bold;">3</span>: SOS1 sets <span style="color: #333333;">****</span>
PARAMETER epsilon <span style="color: #333333;">=</span> <span style="color: #6600ee; font-weight: bold;">0.001</span> larger than feasibility tolerance
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">157</span> VARIABLE x<span style="color: #333333;">.</span>L free variables
i10 <span style="color: #6600ee; font-weight: bold;">0.001</span>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">157</span> VARIABLE y<span style="color: #333333;">.</span>L variable splitting
plus
i10 <span style="color: #6600ee; font-weight: bold;">0.001</span>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">157</span> VARIABLE gamma<span style="color: #333333;">.</span>L gamma(i)<span style="color: #333333;">=</span><span style="color: #0000dd; font-weight: bold;">1</span> <span style="color: #333333;">==></span> <span style="color: #333333;">|</span>x(i)<span style="color: #333333;">|>=</span>epsilon
i10 <span style="color: #6600ee; font-weight: bold;">1.000</span>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">157</span> VARIABLE z<span style="color: #333333;">.</span>L <span style="color: #333333;">=</span> <span style="color: #6600ee; font-weight: bold;">1.000000E-6</span> objective variable
</pre></div>
<div><br /></div><div><br /></div><div>Finally, our flawed method 4 also gives a somewhat strange solution:</div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">177</span> <span style="color: #333333;">****</span> model <span style="color: #0000dd; font-weight: bold;">4</span>: single SOS1 <span style="color: #007020;">set</span> <span style="color: #333333;">****</span>
PARAMETER <b>epsilon</b> <span style="color: #333333;">=</span> <span style="color: #6600ee; font-weight: bold;">0.001</span> <i>larger than feasibility tolerance</i>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">177</span> VARIABLE <b>x</b><span style="color: #333333;">.</span>L <i>free variables</i>
i1 <span style="color: #6600ee; font-weight: bold;">1.000192E-4</span>, i2 <span style="color: #6600ee; font-weight: bold;">1.000192E-4</span>, i3 <span style="color: #6600ee; font-weight: bold;">1.000192E-4</span>, i4 <span style="color: #6600ee; font-weight: bold;">1.000192E-4</span>, i5 <span style="color: #6600ee; font-weight: bold;">1.000192E-4</span>, i6 <span style="color: #6600ee; font-weight: bold;">1.000192E-4</span>
i7 <span style="color: #6600ee; font-weight: bold;">1.000192E-4</span>, i8 <span style="color: #6600ee; font-weight: bold;">1.000192E-4</span>, i9 <span style="color: #6600ee; font-weight: bold;">1.000192E-4</span>, i10 <span style="color: #6600ee; font-weight: bold;">1.000192E-4</span>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">177</span> VARIABLE <b>y</b>2<span style="color: #333333;">.</span>L
plus <span style="color: #6600ee; font-weight: bold;">0.001</span>
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">177</span> VARIABLE <b>z</b><span style="color: #333333;">.</span>L <span style="color: #333333;">=</span> <span style="color: #6600ee; font-weight: bold;">1.000384E-7</span> <i>objective variable</i>
</pre></div>
<div><br /></div><div>Here the deviation 0.001 is distributed over the \(\color{darkred}x_i\). That makes sense, as it makes the objective smaller.</div><div><br /></div><h3 style="text-align: left;">Conclusion</h3><div><br /></div><div><ul style="text-align: left;"><li>Indicator constraints have two important advantages:</li><ul><li>they allow for more natural, intuitive formulations</li><li>and they can be numerically more reliable than big-M constraints using binary variables.</li></ul><li>GAMS does not do indicator variables very well.</li><li>This example shows how sensitive big-M constraints can be. It should scare the xxxx out of you.</li><li>If your solver does not support indicator variables but knows about SOS1 sets, formulations using SOS1 sets can help. However, check the performance: binary variables can be faster.</li></ul><div><br /></div></div><h3 style="text-align: left;">References</h3><div><br /></div><div><ol style="text-align: left;"><li>Forcing at least one free variable to be non-zero in LP, <a href="https://stackoverflow.com/questions/77800059/forcing-at-least-one-free-variable-to-be-non-zero-in-lp">https://stackoverflow.com/questions/77800059/forcing-at-least-one-free-variable-to-be-non-zero-in-lp</a></li></ol><div><br /></div></div><h3 style="text-align: left;">Appendix: GAMS model</h3><div><br /></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 494.6pt;" valign="top" width="659"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">option</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">miqcp</span></b></span><span style="font-family: Consolas; font-size: 9pt;"> = <span class="SpellE"><span class="GramE">cplex</span></span><span class="GramE">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">*------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">* x(<span class="SpellE">i</span>) are free variables</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">*------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">set</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /i1*i10/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">r </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'regions'</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> region<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 9pt;">x(<span class="SpellE">i</span>) <= -epsilon'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> region<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 9pt;">-epsilon <= x(<span class="SpellE">i</span>) <= epsilon'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> region<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 9pt;">x(<span class="SpellE">i</span>) >= epsilon'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">scalar </span></b><span style="font-family: Consolas; font-size: 9pt;">epsilon </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'larger than feasibility tolerance'</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /0.001<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">variables</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span style="font-family: Consolas; font-size: 9pt;">z </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'objective variable'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">x(<span class="SpellE">i</span><span class="GramE">) <span style="color: #0000da;">'</span></span></span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">free variables'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">equation </span></b><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">obj;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">obj..</span></span><span style="font-family: Consolas; font-size: 9pt;"> z =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">i,<b><span style="color: #0000b3;">sqr</span></b></span></span>(x(<span class="SpellE">i</span>)));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">*------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">* 1. indicator constraints</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">* The approach in GAMS is hardly fit for human</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">* <span class="GramE">consumption</span>.</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">*------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">binary variable</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span style="font-family: Consolas; font-size: 9pt;">delta(<span class="SpellE"><span class="GramE">i,r</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'binary indicator variable (indicates region)'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">equations</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span style="font-family: Consolas; font-size: 9pt;">indic1(<span class="SpellE">i</span><span class="GramE">) <span style="color: #0000da;">"</span></span></span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">delta(i,'region1')=1 ==> x(<span class="SpellE">i</span>) <= -epsilon"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">indic2a(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">"delta(i,'region2<span class="GramE">')=</span>1 ==> x(<span class="SpellE">i</span>) >= -epsilon"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">indic2b(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">"delta(i,'region2<span class="GramE">')=</span>1 ==> x(<span class="SpellE">i</span>) <= epsilon"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">indic3(<span class="SpellE">i</span><span class="GramE">) <span style="color: #0000da;">"</span></span></span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">delta(i,'region3')=1 ==> x(<span class="SpellE">i</span>) >= epsilon"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">sumdelta</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">"one region is <span class="GramE">active</span>"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">atleastone</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">"</span></span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">at least one nonzero region is active"</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">indic1(<span class="SpellE">i</span><span class="GramE">)..</span> x(<span class="SpellE">i</span>) =l= -<span class="GramE">epsilon;</span> </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">indic2<span class="GramE">a(</span><span class="SpellE">i</span>).. x(<span class="SpellE">i</span>) =g= -<span class="GramE">epsilon;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">indic2<span class="GramE">b(</span><span class="SpellE">i</span>).. x(<span class="SpellE">i</span>) =l= <span class="GramE">epsilon;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">indic3(<span class="SpellE">i</span><span class="GramE">)..</span> x(<span class="SpellE">i</span>) =g= <span class="GramE">epsilon;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">sumdelta</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="font-family: Consolas; font-size: 9pt;">).. </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">r,delta</span></span>(<span class="SpellE">i,r</span>)) =e= 1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">atleastone</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">..</span></span><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">i,delta</span></span>(i,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'region1'</span><span style="font-family: Consolas; font-size: 9pt;">)+delta(i,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'region3'</span><span style="font-family: Consolas; font-size: 9pt;">)) =g= 1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">* <span class="GramE">the</span> last constraint can also be written as:</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">* <span class="SpellE"><span class="GramE">atleastone</span></span><span class="GramE">..</span> sum(<span class="SpellE"><span class="GramE">i,delta</span></span>(i,'region2')) =l= card(<span class="SpellE">i</span>)-1;</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">* <span class="GramE">this</span> does not work</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$<span class="SpellE">onecho</span></span><i><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> > <span class="SpellE">cplex.opt</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">indic</span></span><span style="font-family: Consolas; font-size: 9pt;"> indic1(<span class="SpellE">i</span>)$delta(i,'region1<span class="GramE">') 1</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">indic</span></span><span style="font-family: Consolas; font-size: 9pt;"> indic2a(<span class="SpellE">i</span>)$delta(i,'region2') 1</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">indic</span></span><span style="font-family: Consolas; font-size: 9pt;"> indic2b(<span class="SpellE">i</span>)$delta(i,'region2') 1</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">indic</span></span><span style="font-family: Consolas; font-size: 9pt;"> indic3(<span class="SpellE">i</span>)$delta(i,'region3<span class="GramE">') 1</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$<span class="SpellE">offecho</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">* <span class="GramE">ugly</span> workaround</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">file</span></b></span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span style="font-family: Consolas; font-size: 9pt;">opt</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /<span class="SpellE">cplex.opt</span>/</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">put</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="GramE">opt;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">loop</span></b><span style="font-family: Consolas; font-size: 9pt;">(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="font-family: Consolas; font-size: 9pt;">,</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">put</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">indic</span> '</span><span style="font-family: Consolas; font-size: 9pt;"> indic1.tn(<span class="SpellE">i</span>) </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'$'</span><span style="font-family: Consolas; font-size: 9pt;"> delta.tn(i,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">"region1"</span><span style="font-family: Consolas; font-size: 9pt;">) </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">' 1'</span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">/;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">put</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">indic</span> '</span><span style="font-family: Consolas; font-size: 9pt;"> indic2a.tn(<span class="SpellE">i</span>) </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'$'</span><span style="font-family: Consolas; font-size: 9pt;"> delta.tn(i,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">"region2"</span><span style="font-family: Consolas; font-size: 9pt;">) </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">' 1'</span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">/;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">put</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">indic</span> '</span><span style="font-family: Consolas; font-size: 9pt;"> indic2b.tn(<span class="SpellE">i</span>) </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'$'</span><span style="font-family: Consolas; font-size: 9pt;"> delta.tn(i,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">"region2"</span><span style="font-family: Consolas; font-size: 9pt;">) </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">' 1'</span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">/;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">put</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">indic</span> '</span><span style="font-family: Consolas; font-size: 9pt;"> indic3.tn(<span class="SpellE">i</span>) </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'$'</span><span style="font-family: Consolas; font-size: 9pt;"> delta.tn(i,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">"region3"</span><span style="font-family: Consolas; font-size: 9pt;">) </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">' 1'</span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">/;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">putclose</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">model </span></b><span style="font-family: Consolas; font-size: 9pt;">m1</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /all<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">m<span class="GramE">1.optfile</span>=1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> m1 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">miqcp</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">"**** model 1: indicator constraints ****<span class="GramE">"<span style="color: black;">,<span class="SpellE">epsilon</span></span></span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">,x.l,delta.l,z.l</span></span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">*------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">* 2. Binary variables</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">* Epsilon is too small.</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">*------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">Scalars</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span style="font-family: Consolas; font-size: 9pt;">LO</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /-1000/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">UP</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /1000/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">x.lo</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>) = <span class="GramE">LO;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">x.up</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>) = <span class="GramE">UP;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">equations</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span style="font-family: Consolas; font-size: 9pt;">bound1(<span class="SpellE">i</span>)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> bound2a(<span class="SpellE">i</span>)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> bound2b(<span class="SpellE">i</span>)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> bound3(<span class="SpellE">i</span>)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">bound1(<span class="SpellE">i</span><span class="GramE">)..</span> x(<span class="SpellE">i</span>) =l= -epsilon*delta(i,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'region1'</span><span style="font-family: Consolas; font-size: 9pt;">) + <span class="SpellE"><span class="GramE">x.up</span></span>(<span class="SpellE">i</span>)*(1-delta(i,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'region1'</span><span style="font-family: Consolas; font-size: 9pt;">));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">bound2<span class="GramE">a(</span><span class="SpellE">i</span>).. x(<span class="SpellE">i</span>) =g= -epsilon*delta(i,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'region2'</span><span style="font-family: Consolas; font-size: 9pt;">) + <span class="SpellE"><span class="GramE">x.lo</span></span>(<span class="SpellE">i</span>)*(1-delta(i,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'region2'</span><span style="font-family: Consolas; font-size: 9pt;">));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">bound2<span class="GramE">b(</span><span class="SpellE">i</span>).. x(<span class="SpellE">i</span>) =l= epsilon*delta(i,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'region2'</span><span style="font-family: Consolas; font-size: 9pt;">) + <span class="SpellE"><span class="GramE">x.up</span></span>(<span class="SpellE">i</span>)*(1-delta(i,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'region2'</span><span style="font-family: Consolas; font-size: 9pt;">));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">bound3(<span class="SpellE">i</span><span class="GramE">)..</span> x(<span class="SpellE">i</span>) =g= epsilon*delta(i,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'region3'</span><span style="font-family: Consolas; font-size: 9pt;">) + <span class="SpellE"><span class="GramE">x.lo</span></span>(<span class="SpellE">i</span>)*(1-delta(i,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'region3'</span><span style="font-family: Consolas; font-size: 9pt;">));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">model </span></b><span style="font-family: Consolas; font-size: 9pt;">m2</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /<span class="GramE">obj,bound</span>1,bound2a,bound2b,bound3,sumdelta,atleastone/</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> m2 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">miqcp</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">"**** model 2: binary variables ****<span class="GramE">"<span style="color: black;">,<span class="SpellE">epsilon</span></span></span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">,x.l,delta.l,z.l</span></span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">epsilon = <span class="GramE">0.01;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> m2 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">miqcp</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">"**** model 2: binary variables ****<span class="GramE">"<span style="color: black;">,<span class="SpellE">epsilon</span></span></span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">,x.l,delta.l,z.l</span></span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">epsilon = <span class="GramE">0.1;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> m2 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">miqcp</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">"**** model 2: binary variables ****<span class="GramE">"<span style="color: black;">,<span class="SpellE">epsilon</span></span></span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">,x.l,delta.l,z.l</span></span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">* <span class="GramE">reset</span> to its original value</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">epsilon = <span class="GramE">0.001;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">*------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">* 3. SOS1 variables</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">*------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">set</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span style="font-family: Consolas; font-size: 9pt;">pm </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'for variable splitting'</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /<span class="SpellE"><span class="GramE">plus,min</span></span>/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">binary variable </span></b><span style="font-family: Consolas; font-size: 9pt;">gamma(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'gamma(<span class="SpellE">i</span>)=1 ==> |x(<span class="SpellE">i</span>)|>=epsilon<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sos1 variable </span></b><span style="font-family: Consolas; font-size: 9pt;">y(<span class="SpellE"><span class="GramE">i,pm</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'variable splitting'</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">* <span class="GramE">automatically</span> y>=0</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">equations</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">def_y</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">abs_y</span>(<span class="SpellE">i</span>)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> at_least_one2</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">def_<span class="GramE">y</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="font-family: Consolas; font-size: 9pt;">).. y(<span class="SpellE">i</span>,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'plus'</span><span style="font-family: Consolas; font-size: 9pt;">)-y(<span class="SpellE">i</span>,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'min'</span><span style="font-family: Consolas; font-size: 9pt;">) =e= x(<span class="SpellE">i</span><span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">abs_<span class="GramE">y</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="font-family: Consolas; font-size: 9pt;">).. y(<span class="SpellE">i</span>,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'plus<span class="GramE">'<span style="color: black;">)+</span></span></span><span style="font-family: Consolas; font-size: 9pt;">y(<span class="SpellE">i</span>,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'min'</span><span style="font-family: Consolas; font-size: 9pt;">) =g= epsilon*</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">gamma</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">at_least_one<span class="GramE">2..</span> </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="font-family: Consolas; font-size: 9pt;">, </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">gamma</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>)) =g= 1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">model </span></b><span style="font-family: Consolas; font-size: 9pt;">m3</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /<span class="GramE">obj,def</span>_y,abs_y,at_least_one2/</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> m3 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">miqcp</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">"**** model 3: SOS1 sets ****<span class="GramE">"<span style="color: black;">,<span class="SpellE">epsilon</span></span></span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">,x.l,y.l,gamma.l,z.l</span></span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">*------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">* 4. One SOS1 Set</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">* This is a hack: it cuts off solutions.</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">*------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sos1 variable </span></b><span style="font-family: Consolas; font-size: 9pt;">y2(pm<span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 9pt;">* <span class="GramE">automatically</span> y2>=0</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">equations</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span style="font-family: Consolas; font-size: 9pt;">def_<span class="GramE">y2</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> abs_y2</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">def_y<span class="GramE">2..</span> y2(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'plus'</span><span style="font-family: Consolas; font-size: 9pt;">)-y2(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'min'</span><span style="font-family: Consolas; font-size: 9pt;">) =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">i,x</span></span>(<span class="SpellE">i</span>));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">abs_y<span class="GramE">2..</span> y2(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'plus<span class="GramE">'<span style="color: black;">)+</span></span></span><span style="font-family: Consolas; font-size: 9pt;">y2(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'min'</span><span style="font-family: Consolas; font-size: 9pt;">) =g= epsilon;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">model </span></b><span style="font-family: Consolas; font-size: 9pt;">m4</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /<span class="GramE">obj,def</span>_y2,abs_y2/</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> m4 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">miqcp</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">"**** model 4: single SOS1 set ****<span class="GramE">"<span style="color: black;">,epsilon</span></span></span><span style="font-family: Consolas; font-size: 9pt;">,x.l,y2.l,z.l;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-size: 9pt;"> </span></p></td></tr></tbody></table><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.6933px; margin: 0in 0in 8pt;"><span style="font-size: 9pt; line-height: 12.84px;"> </span></p></div><p></p></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com1tag:blogger.com,1999:blog-593563533834706486.post-28819569729607175312024-01-16T12:01:00.006-05:002024-02-06T10:09:14.073-05:00Informs Test of Time Award for CONOPT paper <p style="background-color: white; box-sizing: border-box; color: #202225; font-family: Roboto, sans-serif; font-size: 16px;"></p><blockquote><p style="background-color: white; box-sizing: border-box; color: #202225; font-family: Roboto, sans-serif; font-size: 16px;">The Test of Time Award for papers published in the <i style="box-sizing: border-box;">INFORMS Journal on Computing</i> in the years 1993–1997 is awarded to</p><div class="anchor-spacer" id="ac_i1" style="background-color: white; box-sizing: border-box; color: #202225; font-family: Roboto, sans-serif; font-size: 16px; position: relative; top: -11.875rem; visibility: hidden;"></div><h2 class="article-section__title section__title" id="_i1" style="background-color: white; box-sizing: border-box; color: #202225; font-family: Roboto, sans-serif; font-size: 1.375rem; line-height: 1.625rem; margin-bottom: 1rem; margin-top: 0px;">CONOPT: A Large-Scale GRG Code</h2><p style="background-color: white; box-sizing: border-box; color: #202225; font-family: Roboto, sans-serif; font-size: 16px;">Arne Stolbjerg Drud</p><p><i style="box-sizing: border-box; color: #202225; font-family: Roboto, sans-serif; font-size: 16px;">ORSA Journal on Computing</i><span face="Roboto, sans-serif" style="background-color: white; color: #202225; font-size: 16px;"> </span><span face="Roboto, sans-serif" style="background-color: white; color: #202225; font-size: 16px;">6(2):207–216, 1994</span> </p><p></p></blockquote><p><br /></p><p>As Arne notes in [1], he is helped a bit by the fact that CONOPT users may want to cite a published paper (and because there is no newer successor paper). Still, this is quite an achievement. </p><p><span></span></p><a name='more'></a>My impression is that large-scale non-linear programming is a little bit under the radar compared to the large number of papers published on linear and mixed-integer programming. Furthermore, CONOPT is a bit under the radar compared to famous academic large-scale NLP solvers such as MINOS and IPOPT. This is opposed to practical use, where CONOPT plays a very important role. It is usually my go-to NLP solver.<p></p><p><br /></p><h3 style="text-align: left;">References</h3><p><br /></p><p></p><ol style="text-align: left;"><li>Alice E. Smith, Note from the editor, INFORMS Journal on Computing, January 2024, <a href="https://pubsonline.informs.org/doi/10.1287/ijoc.2024.ed.v36.n1">https://pubsonline.informs.org/doi/10.1287/ijoc.2024.ed.v36.n1</a></li><li>Arne Stolbjerg Drud, CONOPT: A Large-Scale GRG Code, ORSA Journal on Computing, 1994, <a href="https://pubsonline.informs.org/doi/abs/10.1287/ijoc.6.2.207">https://pubsonline.informs.org/doi/abs/10.1287/ijoc.6.2.207</a> </li></ol><p></p>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com0tag:blogger.com,1999:blog-593563533834706486.post-34592473040237144592024-01-08T09:51:00.006-05:002024-02-02T14:40:27.695-05:00GAMS listing file: missing Unicode support<p>Newer versions of GAMS allow UTF-8 encoded strings as labels. That is very welcome, as these labels may come from data sources that just use Unicode characters. However, when printing to the listing file, we miss proper Unicode support. At first, I thought, "OK, just a few misaligned tables. No big deal." Here is a constructed example showing this may be a bit more problematic.</p><span><a name='more'></a></span><p><br /></p><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #6b006b;">$onText</span><span style="color: black;"></span></div><div><br /></div><div><span style="color: #005500;"><em> The chars 𝛽 in the labels below are Unicode characters (U+1D6FD).</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em> The name is "Mathematical Italic Small Beta"</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em> </em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em> In UTF-8 encoding they occupy 4 bytes:</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em> 0xF0 0x9D 0x9B 0xBD</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em> </em></span><span style="color: black;"></span></div><div><br /></div><div><span style="color: #6b006b;">$offText</span><span style="color: black;"></span></div><div><br /></div><div><span style="color: #0000b3;"><strong>set </strong></span><span style="color: black;">j</span><span style="color: #007400;"> /</span><span style="color: #007400;">col1*col2</span><span style="color: #007400;">/</span><span style="color: black;">;</span><span style="color: black;"></span></div><div><br /></div><div><span style="color: #0000b3;"><strong>parameter </strong></span><span style="color: black;">p</span><span style="color: black;">(*,*</span><span style="color: black;">)</span><span style="color: black;">;</span><span style="color: black;"></span></div><div><span style="color: black;">p(</span><span style="color: #007400;">'bbbb'</span><span style="color: black;">,j) = 1</span><span style="color: black;">;</span><span style="color: black;"></span></div><div><span style="color: black;">p(</span><span style="color: #007400;">'𝛽𝛽𝛽𝛽'</span><span style="color: black;">,</span><span style="color: #007400;">'col2'</span><span style="color: black;">) = 1</span><span style="color: black;">;</span><span style="color: black;"></span></div></div><p><span style="background-color: white; color: #0000b3; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;"><strong>display</strong></span><span style="background-color: white; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;"> p</span><span style="background-color: white; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;">;</span> </p><p><br /></p><p>The output is:</p><p><br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgXg5ex3khNGHNcrVKQ0qxL2Sk5o8XASfDb2kxw_vj8U-06-0n1cZwcjRGAtlAKvIYTVug0pBN9Ep1wI3JPMxaroj6m84yifk9yOHF3QggJj8Pb1_gsOQaUUNScKDsTdRPGeAXzIHEWqrQ5RQ1slQq-7NMRuk48XygA7rOkgjgW7OE7403LMr2v4WTW41AU" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="133" data-original-width="364" src="https://blogger.googleusercontent.com/img/a/AVvXsEgXg5ex3khNGHNcrVKQ0qxL2Sk5o8XASfDb2kxw_vj8U-06-0n1cZwcjRGAtlAKvIYTVug0pBN9Ep1wI3JPMxaroj6m84yifk9yOHF3QggJj8Pb1_gsOQaUUNScKDsTdRPGeAXzIHEWqrQ5RQ1slQq-7NMRuk48XygA7rOkgjgW7OE7403LMr2v4WTW41AU=s16000" /></a></div><br />This table is very misleading. The second row should have the 1.000 in column col2. If you can't trust the output of the display statement, things become a bit dicey. Admittedly, this example was carefully constructed to illustrate the point. Obviously, this needs to be fixed. <div><br /></div><div>Another issue I have not touched upon here is casing (lower vs upper case), a problem that arises as GAMS labels are case-insensitive. In my opinion (and experience) Unicode support needs to be done very rigorously and can not easily be done in some half-baked way. </div><div><br /></div><blockquote><div>A notable exception is SQLite: this is built without full Unicode support by default. Of course SQLite runs on devices like smart phones, so it needs to watch resource usage. When built without full Unicode support, SQLite will not do Unicode case-insensitive comparison or case changes correctly. This behavior can be changed by building with full Unicode support. <p></p></div></blockquote>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com0tag:blogger.com,1999:blog-593563533834706486.post-62358657989447262502024-01-04T09:35:00.034-05:002024-02-02T14:40:58.593-05:00String Art<script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style><p><br /></p><p><br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen="" class="BLOG_video_class" height="315" src="https://www.youtube.com/embed/WGccIFf6MF8" width="481" youtube-src-id="WGccIFf6MF8"></iframe></div><br /> <p></p><p>In [1], a greyscale picture is approximated by strings (lines) between points around the image. Here, I will try something similar with a formal optimization model.</p><p><span></span></p><a name='more'></a>A greyscale image can be represented by an \(m\times n\) matrix of floating point values between zero and one. A value of zero indicates a black pixel, and a value of one a white pixel. In the discussion below, when I use the term color, this means the greyscale value.<p></p><p><br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhvUzTHbbamEApG9LpDzm0uzzIK4s82dYYWONS8i4ZEBXwtFRzjXuPLcZ4eTI0Lf0bVDpeRTa2NM7Eho5fxn5ncTcKmu6t18kPltyx2K073foHHZJBL7Q0Jerx6KlXuTusSsLU-u3g7b3myJZk1G3lrK0VQQxj60eZeouLUYD6yefqSqYIFo0WKalRtlRWx" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="643" data-original-width="649" height="396" src="https://blogger.googleusercontent.com/img/a/AVvXsEhvUzTHbbamEApG9LpDzm0uzzIK4s82dYYWONS8i4ZEBXwtFRzjXuPLcZ4eTI0Lf0bVDpeRTa2NM7Eho5fxn5ncTcKmu6t18kPltyx2K073foHHZJBL7Q0Jerx6KlXuTusSsLU-u3g7b3myJZk1G3lrK0VQQxj60eZeouLUYD6yefqSqYIFo0WKalRtlRWx=w400-h396" width="400" /></a></div><br /><br /><p></p><p><span></span></p><!--more-->Here is a \(160\times 120\) image. The pixels have values between 0 and 0.97. Let's call this matrix \(\color{darkblue}{\mathit{GreyScale}}_{i,j} \in [0,1]\). Click on the picture to enlarge it a bit.<p></p><p>In my experiments, I just generate \(N=150\) random points inside the image and draw possible lines between them. (The advantage of using mathematical models is that I am not bound to some physical reality: no physical pieces of strings are needed). The pixels that are covered by the lines we draw get a greyscale equal to the sum of the greyscales of the lines. (We assume additivity here: if a pixel is covered by several lines, we add up the contribution of each line. I think this may not be the same for real-world strings.) Here is a picture of the points and possible lines:</p><p><br /></p><p></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhh_Dr4HOOM2J3CcOoN0teooM74BkBrttHdpCq_LvHCb213OibkxT7xsss1EAiFtyHeLJoJDBNBDS-7m-qMTSeach2nWeG_Aa6Zh0XoIaGX3z9c9gTaVoQ3w4jW1mU-58VX00SbPnfG0Ye5NFpOGRPTd6DBoxhlVVZD7Z6hMo1VGapcGnJP3GL9MkVdOwiM" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="576" data-original-width="528" height="400" src="https://blogger.googleusercontent.com/img/a/AVvXsEhh_Dr4HOOM2J3CcOoN0teooM74BkBrttHdpCq_LvHCb213OibkxT7xsss1EAiFtyHeLJoJDBNBDS-7m-qMTSeach2nWeG_Aa6Zh0XoIaGX3z9c9gTaVoQ3w4jW1mU-58VX00SbPnfG0Ye5NFpOGRPTd6DBoxhlVVZD7Z6hMo1VGapcGnJP3GL9MkVdOwiM=w367-h400" width="367" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">N=150 randomly placed points</td></tr></tbody></table><br /><br /><p></p><p><br /></p><p></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgmqCbVSNFihfSRXzbTxM--tLbxzBMAgWzBAyvT0x95tbI9ITYOFiOWCK1cyQXaBcmcAhzifRxs5uIUUvD4hMGmXyPuq37SS_2d2aVBUXfpdRQ-Fxt2-nHylHdkkAcNvVYsrFUMDzUPBuveoZtitZ0yHIxVsUsj8NfOcCaaFTyBnNw9VHuzT0pJWpY5GZQd" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="578" data-original-width="462" height="400" src="https://blogger.googleusercontent.com/img/a/AVvXsEgmqCbVSNFihfSRXzbTxM--tLbxzBMAgWzBAyvT0x95tbI9ITYOFiOWCK1cyQXaBcmcAhzifRxs5uIUUvD4hMGmXyPuq37SS_2d2aVBUXfpdRQ-Fxt2-nHylHdkkAcNvVYsrFUMDzUPBuveoZtitZ0yHIxVsUsj8NfOcCaaFTyBnNw9VHuzT0pJWpY5GZQd=w320-h400" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">All connecting lines</td></tr></tbody></table><br /><br /><p></p><p><br /></p><p>With \(N=150\) points, we can draw \[M=\frac{N(N+1)}{2}=11,325\] lines. This includes lines from a point to itself, i.e. singleton points. I am not sure if adding or discarding these \(N\) singletons makes a difference. </p><div>It does not look that way in the above picture, but all these lines cover 16,870 pixels (that is 88% of all pixels), while 2,330 pixels are not touched by any line. One of the pixels is covered by 278 different lines! <div><br /></div><div>It is difficult to see how selecting lines from this collection can give us something that resembles the original picture.<br /><div><br /></div><div>If each line has the same fixed color \(\color{darkblue}\gamma \in [0,1]\), then we can write the optimization problem as an unconstrained MIQP (Mixed-Integer Quadratic Programming) problem: </div><div><div><br /></div>
<table class="blueTable">
<thead><tr><th>Integer Optimization Model</th></tr></thead>
<tbody><tr><td>\[\begin{align}\min&\sum_{i,j} \left( \sum_k \color{darkblue}\gamma \cdot \color{darkblue}{\mathit{LinePixels}}_{k,i,j}\cdot \color{darkred}x_{k} -\color{darkblue}{\mathit{GreyScale}}_{i,j} \right)^2 \\ & \color{darkred}x_k \in \{0,1\} \end{align}\]</td></tr></tbody>
</table>
<div><br /><div><br /></div>
Here, the binary variable \(\color{darkred}x_{k}\) indicates whether we use line \(k\). The (very sparse) boolean parameter \(\color{darkblue}{\mathit{LinePixels}}_{k,i,j}\) tells us if pixel \((i,j)\) is covered by line \(k\).</div><div><br /></div><div>Observations:</div><div><ul style="text-align: left;"><li>By adding up the greyscale levels for pixels covered by multiple lines, we can easily end up with a total greyscale value exceeding 1. We never can go below 0, so this is a bit asymmetric. </li><li>We can skip pixels that are not covered by any line. This means using a subset of \((i,j)\).</li><li>Large MIQPs are difficult to solve to optimality. This is no exception. Whether we use some linearization or solve as a quadratic model, this is not very easy.</li><li>Solvers like Cplex may linearize this automatically. This involves forming all cross-products, and then linearize \( \color{darkred}x_{k_1}\cdot \color{darkred}x_{k_2}\). This generates a ton of extra binary variables. In some cases, as a result, Cplex was running out of memory. </li><li>Sometimes it is better to write: \[\begin{align}\min&\sum_{i,j} \color{darkred}e^2_{i,j}\\ & \color{darkred}e_{i,j}= \sum_k \color{darkblue}\gamma \cdot \color{darkblue}{\mathit{LinePixels}}_{k,i,j}\cdot \color{darkred}x_{k} -\color{darkblue}{\mathit{GreyScale}}_{i,j}\end{align}\] This makes the quadratic part (numerically) easier.</li><li>Using a LAD (Least Absolute Deviation) objective also gives us a linear model: \[\begin{align}\min&\sum_{i,j} \left( \color{darkred}e^+_{i,j}+\color{darkred}e^-_{i,j}\right) \\ & \color{darkred}e^+_{i,j}-\color{darkred}e^-_{i,j}= \sum_k \color{darkblue}\gamma \cdot \color{darkblue}{\mathit{LinePixels}}_{k,i,j}\cdot \color{darkred}x_{k} -\color{darkblue}{\mathit{GreyScale}}_{i,j}\\ & \color{darkred}e^+_{i,j},\color{darkred}e^-_{i,j}\ge 0\end{align}\] Note that the automatic linearization discussed earlier, is exact. It will give the same solutions as the quadratic problem. Here, we change the problem (from a 2-norm to a 1-norm objective), so solutions will be somewhat different.</li><li>We may not want to have pixel values above 1. An alternative objective could be: \[\min \sum_{i,j} \left( \min\left\{1,\sum_k \color{darkblue}\gamma \cdot \color{darkblue}{\mathit{LinePixels}}_{k,i,j}\cdot \color{darkred}x_{k}\right\} -\color{darkblue}{\mathit{GreyScale}}_{i,j} \right)^2\] However, this complicates the model considerably. Something like \(\color{darkred}y=\min(\color{darkblue}a,\color{darkred}x)\) requires a binary variable \(\color{darkred}\delta\in\{0,1\}\): \[\begin{align}&\color{darkred}y\le\color{darkblue}a\\&\color{darkred}y\le\color{darkred}x\\&\color{darkred}y\ge\color{darkblue}a-\color{darkblue}M\cdot\color{darkred}\delta\\&\color{darkred}y\ge\color{darkred}x-\color{darkblue}M\cdot(1-\color{darkred}\delta)\end{align}\] unless there is something we can exploit. I don't see how to do this much smarter. If no good bounds are available to determine \(\color{darkblue}M\), we can use a SOS1 set.</li><li>Here, we used that colors are additive. A different approach could be to make the observed color the maximum of the underlying line colors. I.e. \[\min\sum_{i,j} \left( \max_k \left\{ \color{darkblue}\gamma \cdot \color{darkblue}{\mathit{LinePixels}}_{k,i,j}\cdot \color{darkred}x_{k}\right\} -\color{darkblue}{\mathit{GreyScale}}_{i,j} \right)^2 \] This again (for the same reasons as the previous bullet) is making the model much more difficult.</li><li>A possible extension is to make \(\color{darkblue}\gamma\) a variable: let the model decide the best color for all selected lines. Note that \(\color{darkred}\gamma\) is not indexed by \(k\) here. So, we have a single color for all lines. Below, I discuss the case where we allow \(\color{darkred}\gamma_k\). I.e., a different color for each line. That can be combined with \(\color{darkred}x_{k}\). </li><li>In the discussion about the mathematics, [1] drops the integrality conditions and also the bounds on \(\color{darkred}x_{k}\). Removing the bounds does not make much sense to me. Also, in [1], lines are thicker and use some kind of anti-aliasing scheme. I use very thin lines without anti-aliasing.</li></ul></div><div><br /></div><div>If we want to allow that each line has its own color (determined by the model), then the problem actually becomes much easier:</div><div><div><br /></div><div><div><br /></div><table class="blueTable"><thead><tr><th>Continuous Optimization Model</th></tr></thead><tbody><tr><td>\[\begin{align}\min&\sum_{i,j} \left( \sum_k \color{darkblue}{\mathit{LinePixels}}_{k,i,j} \cdot \color{darkred}x_{k} -\color{darkblue}{\mathit{GreyScale}}_{i,j} \right)^2 \\ & \color{darkred}x_k \in [0,1] \end{align}\]</td></tr></tbody></table><div><br /><div><br /></div><div>Now \(\color{darkred}x_k \) does not just turn line \(k\) on, but also determines its color. The resulting model is an unconstrained QP (Quadratic Programming) model (but with bounds on \(\color{darkred}x\)). </div></div><div><br /></div><div>Solving this leads to the following somewhat creepy picture:</div><div><br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEiM1Q2Ngz44v1TNzFntdEFbh2FFuOmQNGVu7s5NX-YCoVSqJvjxEmvwSA2erO-GqmK8djCdEjuWo9oIx_cR8kN8vEloYE-w2rFEMUkkrc12CVt5N6e1wBqP3HtWu-_Vd2TpZpM-AxcJQv9rbQFn5DRhRfZyiDPH38lK3juAHBNy8RXlkNptJJdEkqeaz8OQ" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="576" data-original-width="463" height="400" src="https://blogger.googleusercontent.com/img/a/AVvXsEiM1Q2Ngz44v1TNzFntdEFbh2FFuOmQNGVu7s5NX-YCoVSqJvjxEmvwSA2erO-GqmK8djCdEjuWo9oIx_cR8kN8vEloYE-w2rFEMUkkrc12CVt5N6e1wBqP3HtWu-_Vd2TpZpM-AxcJQv9rbQFn5DRhRfZyiDPH38lK3juAHBNy8RXlkNptJJdEkqeaz8OQ=w322-h400" width="322" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Solution: best fit</td></tr></tbody></table><br /><br /></div><p></p><p></p><p>All pixels in the solution with a color value larger than one were reset to 1.0. I.e. the plotted pixels have a value: \[v_{i,j} := \min\left\{1,\sum_k \color{darkblue}{\mathit{LinePixels}}_{k,i,j} \cdot \color{darkred}x^*_{k}\right\}\]</p><p>Einstein's wild hair is certainly a problem for this model. But we can somewhat recognize his face.</p><p><br /></p><h3 style="text-align: left;">Conclusion</h3><div><br /></div><div>We can approximate a greyscale image by drawing lines between relatively few points. Selecting lines of the same exogenous color (greyscale value) can be modeled as a large, difficult MIQP model. Reinterpreting the problem, allowing each line to have its own endogenous color, leads to a much simpler QP model. The result is a picture that somewhat resembles the original.</div><div><br /></div><div>The mathematical review in [1] is a bit less rigorous than what I show here. I stay closer to the original optimization problem. I don't sweep the integer restrictions and bounds on the decision variables under the rug.</div><div><br /></div><h3 style="text-align: left;">References</h3><div><br /></div><p></p><ol style="text-align: left;"><li>The Mathematics of String Art, <a href="https://www.youtube.com/watch?v=WGccIFf6MF8">https://www.youtube.com/watch?v=WGccIFf6MF8</a></li></ol><div><br /></div><div><br /></div><h3 style="text-align: left;">Appendix: GAMS Model</h3><div><br /></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">data</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$include</span><i><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">data5.inc</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$<span class="SpellE">ontext</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">Summary: </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;"> data5.inc</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;"> </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;"> pixels: (240, 180)</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;"> nodes: 150</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;"> lines: 11325</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;"> sets</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">i</span> 'rows'</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;"> j 'columns'</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;"> k 'nodes'</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;"> lines(<span class="SpellE"><span class="GramE">k,k</span></span>) 'line node->node'</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">linepixels</span>(<span class="SpellE"><span class="GramE">k,k</span>,i,j</span>) 'pixels affected by line k1->k2'</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;"> parameter</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;"> greyscale(<span class="SpellE"><span class="GramE">i,j</span></span>) 'pixel values of greyscale image'</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$<span class="SpellE">offtext</span></span><span style="font-family: Consolas; font-size: 10.5pt;"></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">set </span></b><span style="font-family: Consolas; font-size: 10.5pt;">pixels(<span class="SpellE"><span class="GramE">i,j</span></span>)</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /#i.#j/</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">parameter </span></b><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">sizes(</span></span><span style="font-family: Consolas; font-size: 10.5pt;">*);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">sizes(</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">'lines'</span><span style="font-family: Consolas; font-size: 10.5pt;">) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">card</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(lines<span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">sizes(</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">'<span class="SpellE">linepixels</span>'</span><span style="font-family: Consolas; font-size: 10.5pt;">) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">card</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">linepixels</span><span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">sizes;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">pixels</span> not covered by any line?</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sets</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">covpix</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'pixels covered by some line'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">noncovpix</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'pixels not covered by any line'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">alias</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> (<span class="GramE">k,k</span>1,k2);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">covpix</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">linepixels</span>(k1,k2,i,j),1);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">noncovpix</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">not</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">covpix</span>(<span class="SpellE">i,j</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">sizes(</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">'<span class="SpellE">covpix</span>'</span><span style="font-family: Consolas; font-size: 10.5pt;">) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">card</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">covpix</span><span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">sizes(</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">'<span class="SpellE">noncovpix</span>'</span><span style="font-family: Consolas; font-size: 10.5pt;">) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">card</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">noncovpix</span><span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">sizes;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">model</span> m: unconstrained QP</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">scalar </span></b><span style="font-family: Consolas; font-size: 10.5pt;">gamma </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'color factor'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /1.0<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">option</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">miqcp</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">=<span class="SpellE"><span class="GramE">cplex,<b><span style="color: #0000b3;">rmiqcp</span></b></span></span>=<span class="SpellE">cplex,<b><span style="color: #0000b3;">limrow</span></b></span>=0,</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">limcol</span></b><span style="font-family: Consolas; font-size: 10.5pt;">=0,</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">threads</span></b><span style="font-family: Consolas; font-size: 10.5pt;">=8;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">variable </span></b><span style="font-family: Consolas; font-size: 10.5pt;">z </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'objective<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">binary variable </span></b><span style="font-family: Consolas; font-size: 10.5pt;">x(<span class="SpellE"><span class="GramE">k,k</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'select lines'</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">equation </span></b><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">obj;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">obj..</span></span><span style="font-family: Consolas; font-size: 10.5pt;"> z =e= </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">covpix</span></span><span style="font-family: Consolas; font-size: 10.5pt;">, </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sqr</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">gamma</span></b><span style="font-family: Consolas; font-size: 10.5pt;">*</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">lines,linepixels</span>(<span class="SpellE">lines,covpix</span>)*x(lines)) - greyscale(<span class="SpellE">covpix</span>)));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">model </span></b><span style="font-family: Consolas; font-size: 10.5pt;">m</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /obj<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">solve</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> m </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">using</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">rmiqcp</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><o:p> </o:p></p></td></tr></tbody></table><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.6933px; margin: 0in 0in 8pt;"><o:p> </o:p></p><div style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.6933px; margin: 0in 0in 8pt; text-align: left;">This model is skipping pixels that are not covered by any line. That is not really needed. </div></div><p></p></div></div></div></div></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com0tag:blogger.com,1999:blog-593563533834706486.post-35877636111114125132023-11-19T23:56:00.005-05:002024-01-09T08:24:25.833-05:00Grouping items: a difficult combinatorial problem<script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style>In [1], a simple problem is described:<div><br /></div><div><ul style="text-align: left;"><li>We have \(n\) items (or orders) with a certain width. </li><li>We need to combine these items in groups (called patterns) with rather tight limits on the total width. The total length of a pattern (the sum of the lengths of the items assigned to this pattern) must be between 335 and 340.<div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><span style="color: #007400;"></span></div></li><li>As a result, we may not be able to assign all items. The remaining items cannot be formed into valid patterns.</li><li>The objective is to try to place as many items as possible into patterns.</li><li>An indication of the size of the problem: \(n \approx 500\). </li></ul><div><br /></div><h3 style="text-align: left;">Data</h3><div><br /></div><div>Instead of immediately working on a full-known \(n=500\) problem, I generated a random data set with a very manageable \(n=50\) items. The widths were drawn from a <b>discrete uniform distribution </b>between 30 and 300. The data looks like:</div><div><br /></div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">---- <span style="color: blue;">15</span> PARAMETER <b>w</b> <i>item widths</i>
order1 <span style="color: blue;">76.000</span>, order2 <span style="color: blue;">258.000</span>, order3 <span style="color: blue;">179.000</span>, order4 <span style="color: blue;">111.000</span>, order5 <span style="color: blue;">109.000</span>, order6 <span style="color: blue;">90.000</span>
order7 <span style="color: blue;">124.000</span>, order8 <span style="color: blue;">262.000</span>, order9 <span style="color: blue;">48.000</span>, order10 <span style="color: blue;">165.000</span>, order11 <span style="color: blue;">300.000</span>, order12 <span style="color: blue;">186.000</span>
order13 <span style="color: blue;">298.000</span>, order14 <span style="color: blue;">236.000</span>, order15 <span style="color: blue;">65.000</span>, order16 <span style="color: blue;">203.000</span>, order17 <span style="color: blue;">73.000</span>, order18 <span style="color: blue;">97.000</span>
order19 <span style="color: blue;">211.000</span>, order20 <span style="color: blue;">147.000</span>, order21 <span style="color: blue;">127.000</span>, order22 <span style="color: blue;">125.000</span>, order23 <span style="color: blue;">65.000</span>, order24 <span style="color: blue;">70.000</span>
order25 <span style="color: blue;">189.000</span>, order26 <span style="color: blue;">255.000</span>, order27 <span style="color: blue;">92.000</span>, order28 <span style="color: blue;">210.000</span>, order29 <span style="color: blue;">240.000</span>, order30 <span style="color: blue;">112.000</span>
order31 <span style="color: blue;">59.000</span>, order32 <span style="color: blue;">166.000</span>, order33 <span style="color: blue;">73.000</span>, order34 <span style="color: blue;">266.000</span>, order35 <span style="color: blue;">101.000</span>, order36 <span style="color: blue;">107.000</span>
order37 <span style="color: blue;">190.000</span>, order38 <span style="color: blue;">225.000</span>, order39 <span style="color: blue;">200.000</span>, order40 <span style="color: blue;">155.000</span>, order41 <span style="color: blue;">142.000</span>, order42 <span style="color: blue;">61.000</span>
order43 <span style="color: blue;">115.000</span>, order44 <span style="color: blue;">42.000</span>, order45 <span style="color: blue;">121.000</span>, order46 <span style="color: blue;">79.000</span>, order47 <span style="color: blue;">204.000</span>, order48 <span style="color: blue;">181.000</span>
order49 <span style="color: blue;">238.000</span>, order50 <span style="color: blue;">110.000</span>
</pre></div>
<div><br /></div><div><br /></div><div>I stick to the pattern limits \(\color{darkblue}L=335\) and \(\color{darkblue}U=340\).</div><div><br /></div><div>We need some estimate of the number of patterns to use. We could just guess. But a better approach is the following. An upper bound for the number patterns can be established quite easily: \[{\mathit{maxj}} = \left\lfloor \frac{\sum_i \color{darkblue}w_i}{\color{darkblue}L}\right\rfloor\] For our data set this number is:</div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; text-align: left; width: auto;"><pre style="line-height: 125%; margin: 0px;">---- <span style="color: blue;">29</span> PARAMETER <b>maxj </b>= <span style="color: blue;">22.000</span> <i>max number of patterns we can fill</i>
</pre></div>
<div style="text-align: left;"><br /><br /></div><div style="text-align: left;">This means we can safely use this number as the number of bins (patterns). </div><span><a name='more'></a></span><div style="text-align: left;"><br /></div><h3 style="text-align: left;">MIP Formulations</h3><div><br /></div></div><div>In [1], the following MIP model is proposed:</div><div><br /><table class="blueTable"><thead><tr><th>MIP Model M1: original formulation</th></tr></thead><tbody><tr><td>\[\begin{align}\max&\sum_{i,j} \color{darkred}x_{i,j} \\ & \sum_j \color{darkred}x_{i,j} \le 1 &&\forall i \\ & \sum_i \color{darkblue}w_i \cdot \color{darkred}x_{i,j} \ge \color{darkblue}L \cdot \color{darkred}p_j && \forall j\\ & \sum_i \color{darkblue}w_i \cdot \color{darkred}x_{i,j} \le \color{darkblue}U \cdot \color{darkred}p_j && \forall j\\ & \color{darkred}x_{i,j} \in \{0,1\}\\ & \color{darkred}p_j \in \{0,1\} \end{align}\]</td></tr></tbody></table><br /></div><div>Here \(\color{darkred}x_{i,j}\in \{0,1\}\) indicates if order \(i\) is assigned to pattern \(j\). The binary variable \(\color{darkred}p_j \in \{0,1\}\) tells us if pattern \(j\) is used or left empty. This model is correct, but I don't really like the duplication of expressions in the last two constraints. </div><div><br /></div><div>In general, I would prefer a <b>sparse</b> version of this model: </div><div><br /></div><div><div><br /><table class="blueTable"><thead><tr><th>MIP Model M2: sparse formulation</th></tr></thead><tbody><tr><td>\[\begin{align}\max&\sum_{i,j} \color{darkred}x_{i,j} \\ & \sum_j \color{darkred}x_{i,j} \le 1 &&\forall i \\ & \color{darkred}{pw}_j = \sum_i \color{darkblue}w_i \cdot \color{darkred}x_{i,j} &&\forall j \\ & \color{darkred}{pw}_j \ge \color{darkblue}L \cdot \color{darkred}p_j&&\forall j\\ &\color{darkred}{pw}_j \le \color{darkblue}U \cdot \color{darkred}p_j&&\forall j\\ & \color{darkred}x_{i,j} \in \{0,1\}\\ & \color{darkred}p_j \in \{0,1\} \\ & \color{darkred}{pw}_j \in [0,\color{darkblue}U]\end{align}\]</td></tr></tbody></table><br /></div><div>This formulation will increase the number of constraints, and it adds a number of continuous variables. But in exchange, we have fewer non-zero elements in the matrix. I would hope that, as the problem is sparser, we can execute more Simplex iterations per unit of time and thus evaluate more branch & bound nodes (per unit of time).</div></div><div><br /></div><div>Another formulation is using <b>semi-continuous variables</b>. This directly tells the solver that a variable can assume values: zero or between a lower- and upper-bound. This would eliminate the need for the binary variables \(\color{darkred}p_j\) in the previous model.</div><div><br /></div><div><div><br /><table class="blueTable"><thead><tr><th>MIP Model M3: semi-continuous formulation</th></tr></thead><tbody><tr><td>\[\begin{align}\max&\sum_{i,j} \color{darkred}x_{i,j} \\ & \sum_j \color{darkred}x_{i,j} \le 1 &&\forall i \\ & \color{darkred}{psc}_j = \sum_i \color{darkblue}w_i \cdot \color{darkred}x_{i,j} && \forall j\\ & \color{darkred}x_{i,j} \in \{0,1\}\\ & \color{darkred}{psc}_j \in \{0\} \cup [\color{darkblue}L,\color{darkblue}U] \end{align}\]</td></tr></tbody></table><br /></div><div>Further variations are:</div></div><div><ul style="text-align: left;"><li>Adding a <b>symmetry-breaking ordering constraint</b>: \[\color{darkred}{psc}_j \ge \color{darkred}{psc}_{j+1}\] or depending on the formulation \[\color{darkred}{pw}_j \ge \color{darkred}{pw}_{j+1}\]This will reduce the size of the feasible region, but it also makes it more difficult to find integer feasible solutions. Sometimes, such a constraint is very beneficial (but not always). For our model, this seems to cause way more harm than good.</li><li>Add some <b>branching priorities</b> so that we branch on large items first. This is approximately how we would approach things when doing it by hand: first place the big items and then worry about the smaller ones. Usually, I am not able to beat the solver by setting my own branching order, but in this case, it seems to help.</li></ul></div><div><br /></div><div>When looking at some results, using a time limit of 1000 seconds, we see:</div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px; text-align: left;">---- <span style="color: blue;">156</span> PARAMETER <b>report </b><i>performance statistics</i>
Original Sparse Sp+Prior SC+Prior Sp+Order
Variables <span style="color: blue;">1123</span> <span style="color: blue;">1145</span> <span style="color: blue;">1145</span> <span style="color: blue;">1123</span> <span style="color: blue;">1145</span>
discrete <span style="color: blue;">1122</span> <span style="color: blue;">1122</span> <span style="color: blue;">1122</span> <span style="color: blue;">1122</span> <span style="color: blue;">1122</span>
Equations <span style="color: blue;">95</span> <span style="color: blue;">117</span> <span style="color: blue;">117</span> <span style="color: blue;">73</span> <span style="color: blue;">138</span>
Nonzeros <span style="color: blue;">4445</span> <span style="color: blue;">3411</span> <span style="color: blue;">3411</span> <span style="color: blue;">3323</span> <span style="color: blue;">3453</span>
Status IntFeas IntFeas Optimal IntFeas IntFeas
Objective <span style="color: blue;">44</span> <span style="color: blue;">44</span> <span style="color: blue;">44</span> <span style="color: blue;">44</span> <span style="color: blue;">35</span>
Best bound <span style="color: blue;">45</span> <span style="color: blue;">48</span> <span style="color: blue;">44</span> <span style="color: blue;">46</span> <span style="color: blue;">48</span>
Time <span style="color: blue;">1000</span> <span style="color: blue;">1003</span> <span style="color: blue;">70</span> <span style="color: blue;">1007</span> <span style="color: blue;">1004</span>
Nodes <span style="color: blue;">5534952</span> <span style="color: blue;">2711568</span> <span style="color: blue;">565030</span> <span style="color: blue;">3909796</span> <span style="color: blue;">775504</span>
Iterations <span style="color: blue;">214185798</span> <span style="color: blue;">232199570</span> <span style="color: blue;">14068906</span> <span style="color: blue;">195942501</span> <span style="color: blue;">46981242</span>
</pre></div>
<div style="text-align: left;"><br /></div><div style="text-align: left;"><br /></div><div style="text-align: left;">This table indicates that the Sparse+Priorities formulation is a good candidate to work with. All methods, expect one, find the optimal solution, but only one is able to prove global optimality within 1,000 seconds.</div><div style="text-align: left;"><br /></div><div style="text-align: left;">Looking at the solution for the 'Sp+Prior' column, we see that 44 of the 50 items could be assigned. The number of patterns used in that solution was 18 (our bound for this number was 22).</div><div style="text-align: left;"><br /></div><div style="text-align: left;">A little bit of a haphazard picture:</div><h3 style="text-align: left;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjzj0dq1A6hFmMBWYD22S7k2Ja1jQVAsLGWmADCLhOm2YF5DFh23txVdhDVFlaLO4tc4bvRa6Ok5umTMEPdhEmzMlthJ6c-tjIvu47eFDSx_LScH3LPTbu_5wrnvrS5hmY2jYSNGhiEZo4ECADbzQmU50EDUbWNSGl1Qlw2TCn1d-1QiFH5sPlBSw5b8mCU" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="827" data-original-width="1062" src="https://blogger.googleusercontent.com/img/a/AVvXsEjzj0dq1A6hFmMBWYD22S7k2Ja1jQVAsLGWmADCLhOm2YF5DFh23txVdhDVFlaLO4tc4bvRa6Ok5umTMEPdhEmzMlthJ6c-tjIvu47eFDSx_LScH3LPTbu_5wrnvrS5hmY2jYSNGhiEZo4ECADbzQmU50EDUbWNSGl1Qlw2TCn1d-1QiFH5sPlBSw5b8mCU=s16000" /></a></div><p style="text-align: left;"><span style="font-size: medium; font-weight: 400;">The y-axis represents patterns and unassigned orders. The x-axis shows the widths. The first 6 lines are unassigned orders. Below are the patterns that fit. The picture illustrates how narrow the band is for the total lengths of patterns. Not much wiggle room there.</span></p><p style="text-align: left;"><span style="font-size: medium; font-weight: 400;"><br /></span></p></h3><h3 style="text-align: left;">The big enchilada</h3><div><br /></div><div>Now let's circle back to the original question. We want to solve this with \(n=500\) orders. Let's be brave and form a data set:</div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">---- <span style="color: blue;">16</span> PARAMETER <b>w</b> <i>item widths</i>
order1 <span style="color: blue;">76.000</span>, order2 <span style="color: blue;">258.000</span>, order3 <span style="color: blue;">179.000</span>, order4 <span style="color: blue;">111.000</span>, order5 <span style="color: blue;">109.000</span>, order6 <span style="color: blue;">90.000</span>
order7 <span style="color: blue;">124.000</span>, order8 <span style="color: blue;">262.000</span>, order9 <span style="color: blue;">48.000</span>, order10 <span style="color: blue;">165.000</span>, order11 <span style="color: blue;">300.000</span>, order12 <span style="color: blue;">186.000</span>
order13 <span style="color: blue;">298.000</span>, order14 <span style="color: blue;">236.000</span>, order15 <span style="color: blue;">65.000</span>, order16 <span style="color: blue;">203.000</span>, order17 <span style="color: blue;">73.000</span>, order18 <span style="color: blue;">97.000</span>
order19 <span style="color: blue;">211.000</span>, order20 <span style="color: blue;">147.000</span>, order21 <span style="color: blue;">127.000</span>, order22 <span style="color: blue;">125.000</span>, order23 <span style="color: blue;">65.000</span>, order24 <span style="color: blue;">70.000</span>
order25 <span style="color: blue;">189.000</span>, order26 <span style="color: blue;">255.000</span>, order27 <span style="color: blue;">92.000</span>, order28 <span style="color: blue;">210.000</span>, order29 <span style="color: blue;">240.000</span>, order30 <span style="color: blue;">112.000</span>
order31 <span style="color: blue;">59.000</span>, order32 <span style="color: blue;">166.000</span>, order33 <span style="color: blue;">73.000</span>, order34 <span style="color: blue;">266.000</span>, order35 <span style="color: blue;">101.000</span>, order36 <span style="color: blue;">107.000</span>
order37 <span style="color: blue;">190.000</span>, order38 <span style="color: blue;">225.000</span>, order39 <span style="color: blue;">200.000</span>, order40 <span style="color: blue;">155.000</span>, order41 <span style="color: blue;">142.000</span>, order42 <span style="color: blue;">61.000</span>
order43 <span style="color: blue;">115.000</span>, order44 <span style="color: blue;">42.000</span>, order45 <span style="color: blue;">121.000</span>, order46 <span style="color: blue;">79.000</span>, order47 <span style="color: blue;">204.000</span>, order48 <span style="color: blue;">181.000</span>
order49 <span style="color: blue;">238.000</span>, order50 <span style="color: blue;">110.000</span>, order51 <span style="color: blue;">209.000</span>, order52 <span style="color: blue;">234.000</span>, order53 <span style="color: blue;">200.000</span>, order54 <span style="color: blue;">106.000</span>
order55 <span style="color: blue;">53.000</span>, order56 <span style="color: blue;">57.000</span>, order57 <span style="color: blue;">203.000</span>, order58 <span style="color: blue;">177.000</span>, order59 <span style="color: blue;">38.000</span>, order60 <span style="color: blue;">244.000</span>
order61 <span style="color: blue;">49.000</span>, order62 <span style="color: blue;">77.000</span>, order63 <span style="color: blue;">172.000</span>, order64 <span style="color: blue;">233.000</span>, order65 <span style="color: blue;">78.000</span>, order66 <span style="color: blue;">39.000</span>
order67 <span style="color: blue;">188.000</span>, order68 <span style="color: blue;">198.000</span>, order69 <span style="color: blue;">135.000</span>, order70 <span style="color: blue;">127.000</span>, order71 <span style="color: blue;">95.000</span>, order72 <span style="color: blue;">96.000</span>
order73 <span style="color: blue;">65.000</span>, order74 <span style="color: blue;">282.000</span>, order75 <span style="color: blue;">132.000</span>, order76 <span style="color: blue;">242.000</span>, order77 <span style="color: blue;">111.000</span>, order78 <span style="color: blue;">64.000</span>
order79 <span style="color: blue;">232.000</span>, order80 <span style="color: blue;">48.000</span>, order81 <span style="color: blue;">84.000</span>, order82 <span style="color: blue;">31.000</span>, order83 <span style="color: blue;">103.000</span>, order84 <span style="color: blue;">165.000</span>
order85 <span style="color: blue;">70.000</span>, order86 <span style="color: blue;">77.000</span>, order87 <span style="color: blue;">119.000</span>, order88 <span style="color: blue;">115.000</span>, order89 <span style="color: blue;">117.000</span>, order90 <span style="color: blue;">291.000</span>
order91 <span style="color: blue;">299.000</span>, order92 <span style="color: blue;">130.000</span>, order93 <span style="color: blue;">131.000</span>, order94 <span style="color: blue;">239.000</span>, order95 <span style="color: blue;">137.000</span>, order96 <span style="color: blue;">277.000</span>
order97 <span style="color: blue;">62.000</span>, order98 <span style="color: blue;">229.000</span>, order99 <span style="color: blue;">45.000</span>, order100 <span style="color: blue;">186.000</span>, order101 <span style="color: blue;">43.000</span>, order102 <span style="color: blue;">31.000</span>
order103 <span style="color: blue;">138.000</span>, order104 <span style="color: blue;">170.000</span>, order105 <span style="color: blue;">200.000</span>, order106 <span style="color: blue;">91.000</span>, order107 <span style="color: blue;">137.000</span>, order108 <span style="color: blue;">104.000</span>
order109 <span style="color: blue;">71.000</span>, order110 <span style="color: blue;">283.000</span>, order111 <span style="color: blue;">144.000</span>, order112 <span style="color: blue;">66.000</span>, order113 <span style="color: blue;">134.000</span>, order114 <span style="color: blue;">131.000</span>
order115 <span style="color: blue;">102.000</span>, order116 <span style="color: blue;">287.000</span>, order117 <span style="color: blue;">81.000</span>, order118 <span style="color: blue;">110.000</span>, order119 <span style="color: blue;">50.000</span>, order120 <span style="color: blue;">138.000</span>
order121 <span style="color: blue;">57.000</span>, order122 <span style="color: blue;">134.000</span>, order123 <span style="color: blue;">117.000</span>, order124 <span style="color: blue;">82.000</span>, order125 <span style="color: blue;">60.000</span>, order126 <span style="color: blue;">191.000</span>
order127 <span style="color: blue;">168.000</span>, order128 <span style="color: blue;">42.000</span>, order129 <span style="color: blue;">242.000</span>, order130 <span style="color: blue;">286.000</span>, order131 <span style="color: blue;">191.000</span>, order132 <span style="color: blue;">194.000</span>
order133 <span style="color: blue;">128.000</span>, order134 <span style="color: blue;">190.000</span>, order135 <span style="color: blue;">214.000</span>, order136 <span style="color: blue;">167.000</span>, order137 <span style="color: blue;">73.000</span>, order138 <span style="color: blue;">208.000</span>
order139 <span style="color: blue;">171.000</span>, order140 <span style="color: blue;">63.000</span>, order141 <span style="color: blue;">297.000</span>, order142 <span style="color: blue;">91.000</span>, order143 <span style="color: blue;">213.000</span>, order144 <span style="color: blue;">240.000</span>
order145 <span style="color: blue;">282.000</span>, order146 <span style="color: blue;">84.000</span>, order147 <span style="color: blue;">110.000</span>, order148 <span style="color: blue;">83.000</span>, order149 <span style="color: blue;">96.000</span>, order150 <span style="color: blue;">205.000</span>
order151 <span style="color: blue;">229.000</span>, order152 <span style="color: blue;">53.000</span>, order153 <span style="color: blue;">70.000</span>, order154 <span style="color: blue;">147.000</span>, order155 <span style="color: blue;">80.000</span>, order156 <span style="color: blue;">217.000</span>
order157 <span style="color: blue;">236.000</span>, order158 <span style="color: blue;">71.000</span>, order159 <span style="color: blue;">135.000</span>, order160 <span style="color: blue;">218.000</span>, order161 <span style="color: blue;">259.000</span>, order162 <span style="color: blue;">196.000</span>
order163 <span style="color: blue;">294.000</span>, order164 <span style="color: blue;">37.000</span>, order165 <span style="color: blue;">80.000</span>, order166 <span style="color: blue;">53.000</span>, order167 <span style="color: blue;">176.000</span>, order168 <span style="color: blue;">64.000</span>
order169 <span style="color: blue;">228.000</span>, order170 <span style="color: blue;">60.000</span>, order171 <span style="color: blue;">162.000</span>, order172 <span style="color: blue;">245.000</span>, order173 <span style="color: blue;">163.000</span>, order174 <span style="color: blue;">174.000</span>
order175 <span style="color: blue;">32.000</span>, order176 <span style="color: blue;">177.000</span>, order177 <span style="color: blue;">152.000</span>, order178 <span style="color: blue;">294.000</span>, order179 <span style="color: blue;">79.000</span>, order180 <span style="color: blue;">74.000</span>
order181 <span style="color: blue;">36.000</span>, order182 <span style="color: blue;">78.000</span>, order183 <span style="color: blue;">46.000</span>, order184 <span style="color: blue;">34.000</span>, order185 <span style="color: blue;">256.000</span>, order186 <span style="color: blue;">193.000</span>
order187 <span style="color: blue;">37.000</span>, order188 <span style="color: blue;">83.000</span>, order189 <span style="color: blue;">287.000</span>, order190 <span style="color: blue;">120.000</span>, order191 <span style="color: blue;">191.000</span>, order192 <span style="color: blue;">100.000</span>
order193 <span style="color: blue;">203.000</span>, order194 <span style="color: blue;">72.000</span>, order195 <span style="color: blue;">154.000</span>, order196 <span style="color: blue;">136.000</span>, order197 <span style="color: blue;">248.000</span>, order198 <span style="color: blue;">176.000</span>
order199 <span style="color: blue;">135.000</span>, order200 <span style="color: blue;">181.000</span>, order201 <span style="color: blue;">282.000</span>, order202 <span style="color: blue;">124.000</span>, order203 <span style="color: blue;">32.000</span>, order204 <span style="color: blue;">287.000</span>
order205 <span style="color: blue;">184.000</span>, order206 <span style="color: blue;">120.000</span>, order207 <span style="color: blue;">296.000</span>, order208 <span style="color: blue;">237.000</span>, order209 <span style="color: blue;">59.000</span>, order210 <span style="color: blue;">299.000</span>
order211 <span style="color: blue;">187.000</span>, order212 <span style="color: blue;">75.000</span>, order213 <span style="color: blue;">204.000</span>, order214 <span style="color: blue;">123.000</span>, order215 <span style="color: blue;">277.000</span>, order216 <span style="color: blue;">273.000</span>
order217 <span style="color: blue;">34.000</span>, order218 <span style="color: blue;">129.000</span>, order219 <span style="color: blue;">210.000</span>, order220 <span style="color: blue;">190.000</span>, order221 <span style="color: blue;">39.000</span>, order222 <span style="color: blue;">258.000</span>
order223 <span style="color: blue;">282.000</span>, order224 <span style="color: blue;">167.000</span>, order225 <span style="color: blue;">111.000</span>, order226 <span style="color: blue;">164.000</span>, order227 <span style="color: blue;">42.000</span>, order228 <span style="color: blue;">239.000</span>
order229 <span style="color: blue;">174.000</span>, order230 <span style="color: blue;">232.000</span>, order231 <span style="color: blue;">225.000</span>, order232 <span style="color: blue;">201.000</span>, order233 <span style="color: blue;">61.000</span>, order234 <span style="color: blue;">293.000</span>
order235 <span style="color: blue;">221.000</span>, order236 <span style="color: blue;">297.000</span>, order237 <span style="color: blue;">261.000</span>, order238 <span style="color: blue;">198.000</span>, order239 <span style="color: blue;">220.000</span>, order240 <span style="color: blue;">219.000</span>
order241 <span style="color: blue;">244.000</span>, order242 <span style="color: blue;">195.000</span>, order243 <span style="color: blue;">44.000</span>, order244 <span style="color: blue;">161.000</span>, order245 <span style="color: blue;">44.000</span>, order246 <span style="color: blue;">219.000</span>
order247 <span style="color: blue;">82.000</span>, order248 <span style="color: blue;">91.000</span>, order249 <span style="color: blue;">250.000</span>, order250 <span style="color: blue;">298.000</span>, order251 <span style="color: blue;">233.000</span>, order252 <span style="color: blue;">224.000</span>
order253 <span style="color: blue;">30.000</span>, order254 <span style="color: blue;">101.000</span>, order255 <span style="color: blue;">253.000</span>, order256 <span style="color: blue;">252.000</span>, order257 <span style="color: blue;">263.000</span>, order258 <span style="color: blue;">87.000</span>
order259 <span style="color: blue;">153.000</span>, order260 <span style="color: blue;">40.000</span>, order261 <span style="color: blue;">117.000</span>, order262 <span style="color: blue;">149.000</span>, order263 <span style="color: blue;">115.000</span>, order264 <span style="color: blue;">66.000</span>
order265 <span style="color: blue;">249.000</span>, order266 <span style="color: blue;">142.000</span>, order267 <span style="color: blue;">68.000</span>, order268 <span style="color: blue;">156.000</span>, order269 <span style="color: blue;">106.000</span>, order270 <span style="color: blue;">272.000</span>
order271 <span style="color: blue;">47.000</span>, order272 <span style="color: blue;">142.000</span>, order273 <span style="color: blue;">122.000</span>, order274 <span style="color: blue;">156.000</span>, order275 <span style="color: blue;">204.000</span>, order276 <span style="color: blue;">204.000</span>
order277 <span style="color: blue;">121.000</span>, order278 <span style="color: blue;">57.000</span>, order279 <span style="color: blue;">275.000</span>, order280 <span style="color: blue;">88.000</span>, order281 <span style="color: blue;">279.000</span>, order282 <span style="color: blue;">152.000</span>
order283 <span style="color: blue;">54.000</span>, order284 <span style="color: blue;">131.000</span>, order285 <span style="color: blue;">142.000</span>, order286 <span style="color: blue;">139.000</span>, order287 <span style="color: blue;">60.000</span>, order288 <span style="color: blue;">233.000</span>
order289 <span style="color: blue;">247.000</span>, order290 <span style="color: blue;">36.000</span>, order291 <span style="color: blue;">160.000</span>, order292 <span style="color: blue;">105.000</span>, order293 <span style="color: blue;">274.000</span>, order294 <span style="color: blue;">34.000</span>
order295 <span style="color: blue;">214.000</span>, order296 <span style="color: blue;">287.000</span>, order297 <span style="color: blue;">273.000</span>, order298 <span style="color: blue;">273.000</span>, order299 <span style="color: blue;">266.000</span>, order300 <span style="color: blue;">135.000</span>
order301 <span style="color: blue;">166.000</span>, order302 <span style="color: blue;">255.000</span>, order303 <span style="color: blue;">193.000</span>, order304 <span style="color: blue;">52.000</span>, order305 <span style="color: blue;">186.000</span>, order306 <span style="color: blue;">190.000</span>
order307 <span style="color: blue;">215.000</span>, order308 <span style="color: blue;">73.000</span>, order309 <span style="color: blue;">119.000</span>, order310 <span style="color: blue;">115.000</span>, order311 <span style="color: blue;">170.000</span>, order312 <span style="color: blue;">128.000</span>
order313 <span style="color: blue;">75.000</span>, order314 <span style="color: blue;">215.000</span>, order315 <span style="color: blue;">166.000</span>, order316 <span style="color: blue;">186.000</span>, order317 <span style="color: blue;">225.000</span>, order318 <span style="color: blue;">215.000</span>
order319 <span style="color: blue;">35.000</span>, order320 <span style="color: blue;">257.000</span>, order321 <span style="color: blue;">222.000</span>, order322 <span style="color: blue;">72.000</span>, order323 <span style="color: blue;">195.000</span>, order324 <span style="color: blue;">209.000</span>
order325 <span style="color: blue;">82.000</span>, order326 <span style="color: blue;">128.000</span>, order327 <span style="color: blue;">199.000</span>, order328 <span style="color: blue;">228.000</span>, order329 <span style="color: blue;">142.000</span>, order330 <span style="color: blue;">72.000</span>
order331 <span style="color: blue;">33.000</span>, order332 <span style="color: blue;">32.000</span>, order333 <span style="color: blue;">288.000</span>, order334 <span style="color: blue;">294.000</span>, order335 <span style="color: blue;">291.000</span>, order336 <span style="color: blue;">262.000</span>
order337 <span style="color: blue;">68.000</span>, order338 <span style="color: blue;">43.000</span>, order339 <span style="color: blue;">179.000</span>, order340 <span style="color: blue;">79.000</span>, order341 <span style="color: blue;">299.000</span>, order342 <span style="color: blue;">249.000</span>
order343 <span style="color: blue;">112.000</span>, order344 <span style="color: blue;">53.000</span>, order345 <span style="color: blue;">146.000</span>, order346 <span style="color: blue;">124.000</span>, order347 <span style="color: blue;">61.000</span>, order348 <span style="color: blue;">188.000</span>
order349 <span style="color: blue;">150.000</span>, order350 <span style="color: blue;">141.000</span>, order351 <span style="color: blue;">277.000</span>, order352 <span style="color: blue;">87.000</span>, order353 <span style="color: blue;">90.000</span>, order354 <span style="color: blue;">176.000</span>
order355 <span style="color: blue;">201.000</span>, order356 <span style="color: blue;">118.000</span>, order357 <span style="color: blue;">70.000</span>, order358 <span style="color: blue;">281.000</span>, order359 <span style="color: blue;">98.000</span>, order360 <span style="color: blue;">46.000</span>
order361 <span style="color: blue;">114.000</span>, order362 <span style="color: blue;">40.000</span>, order363 <span style="color: blue;">252.000</span>, order364 <span style="color: blue;">92.000</span>, order365 <span style="color: blue;">141.000</span>, order366 <span style="color: blue;">111.000</span>
order367 <span style="color: blue;">150.000</span>, order368 <span style="color: blue;">224.000</span>, order369 <span style="color: blue;">190.000</span>, order370 <span style="color: blue;">65.000</span>, order371 <span style="color: blue;">73.000</span>, order372 <span style="color: blue;">115.000</span>
order373 <span style="color: blue;">185.000</span>, order374 <span style="color: blue;">102.000</span>, order375 <span style="color: blue;">39.000</span>, order376 <span style="color: blue;">216.000</span>, order377 <span style="color: blue;">212.000</span>, order378 <span style="color: blue;">120.000</span>
order379 <span style="color: blue;">235.000</span>, order380 <span style="color: blue;">77.000</span>, order381 <span style="color: blue;">214.000</span>, order382 <span style="color: blue;">212.000</span>, order383 <span style="color: blue;">255.000</span>, order384 <span style="color: blue;">169.000</span>
order385 <span style="color: blue;">106.000</span>, order386 <span style="color: blue;">180.000</span>, order387 <span style="color: blue;">142.000</span>, order388 <span style="color: blue;">49.000</span>, order389 <span style="color: blue;">248.000</span>, order390 <span style="color: blue;">120.000</span>
order391 <span style="color: blue;">52.000</span>, order392 <span style="color: blue;">185.000</span>, order393 <span style="color: blue;">35.000</span>, order394 <span style="color: blue;">231.000</span>, order395 <span style="color: blue;">275.000</span>, order396 <span style="color: blue;">181.000</span>
order397 <span style="color: blue;">158.000</span>, order398 <span style="color: blue;">224.000</span>, order399 <span style="color: blue;">169.000</span>, order400 <span style="color: blue;">270.000</span>, order401 <span style="color: blue;">239.000</span>, order402 <span style="color: blue;">67.000</span>
order403 <span style="color: blue;">101.000</span>, order404 <span style="color: blue;">214.000</span>, order405 <span style="color: blue;">151.000</span>, order406 <span style="color: blue;">291.000</span>, order407 <span style="color: blue;">289.000</span>, order408 <span style="color: blue;">273.000</span>
order409 <span style="color: blue;">118.000</span>, order410 <span style="color: blue;">153.000</span>, order411 <span style="color: blue;">191.000</span>, order412 <span style="color: blue;">268.000</span>, order413 <span style="color: blue;">76.000</span>, order414 <span style="color: blue;">201.000</span>
order415 <span style="color: blue;">239.000</span>, order416 <span style="color: blue;">184.000</span>, order417 <span style="color: blue;">37.000</span>, order418 <span style="color: blue;">249.000</span>, order419 <span style="color: blue;">105.000</span>, order420 <span style="color: blue;">147.000</span>
order421 <span style="color: blue;">121.000</span>, order422 <span style="color: blue;">189.000</span>, order423 <span style="color: blue;">185.000</span>, order424 <span style="color: blue;">177.000</span>, order425 <span style="color: blue;">186.000</span>, order426 <span style="color: blue;">294.000</span>
order427 <span style="color: blue;">117.000</span>, order428 <span style="color: blue;">236.000</span>, order429 <span style="color: blue;">290.000</span>, order430 <span style="color: blue;">287.000</span>, order431 <span style="color: blue;">99.000</span>, order432 <span style="color: blue;">118.000</span>
order433 <span style="color: blue;">88.000</span>, order434 <span style="color: blue;">77.000</span>, order435 <span style="color: blue;">228.000</span>, order436 <span style="color: blue;">103.000</span>, order437 <span style="color: blue;">235.000</span>, order438 <span style="color: blue;">197.000</span>
order439 <span style="color: blue;">108.000</span>, order440 <span style="color: blue;">230.000</span>, order441 <span style="color: blue;">32.000</span>, order442 <span style="color: blue;">264.000</span>, order443 <span style="color: blue;">34.000</span>, order444 <span style="color: blue;">146.000</span>
order445 <span style="color: blue;">127.000</span>, order446 <span style="color: blue;">221.000</span>, order447 <span style="color: blue;">142.000</span>, order448 <span style="color: blue;">178.000</span>, order449 <span style="color: blue;">123.000</span>, order450 <span style="color: blue;">219.000</span>
order451 <span style="color: blue;">282.000</span>, order452 <span style="color: blue;">157.000</span>, order453 <span style="color: blue;">87.000</span>, order454 <span style="color: blue;">168.000</span>, order455 <span style="color: blue;">129.000</span>, order456 <span style="color: blue;">283.000</span>
order457 <span style="color: blue;">48.000</span>, order458 <span style="color: blue;">166.000</span>, order459 <span style="color: blue;">136.000</span>, order460 <span style="color: blue;">85.000</span>, order461 <span style="color: blue;">173.000</span>, order462 <span style="color: blue;">189.000</span>
order463 <span style="color: blue;">123.000</span>, order464 <span style="color: blue;">98.000</span>, order465 <span style="color: blue;">178.000</span>, order466 <span style="color: blue;">178.000</span>, order467 <span style="color: blue;">45.000</span>, order468 <span style="color: blue;">132.000</span>
order469 <span style="color: blue;">293.000</span>, order470 <span style="color: blue;">132.000</span>, order471 <span style="color: blue;">72.000</span>, order472 <span style="color: blue;">157.000</span>, order473 <span style="color: blue;">137.000</span>, order474 <span style="color: blue;">85.000</span>
order475 <span style="color: blue;">200.000</span>, order476 <span style="color: blue;">30.000</span>, order477 <span style="color: blue;">166.000</span>, order478 <span style="color: blue;">30.000</span>, order479 <span style="color: blue;">171.000</span>, order480 <span style="color: blue;">256.000</span>
order481 <span style="color: blue;">49.000</span>, order482 <span style="color: blue;">236.000</span>, order483 <span style="color: blue;">108.000</span>, order484 <span style="color: blue;">96.000</span>, order485 <span style="color: blue;">148.000</span>, order486 <span style="color: blue;">129.000</span>
order487 <span style="color: blue;">179.000</span>, order488 <span style="color: blue;">50.000</span>, order489 <span style="color: blue;">276.000</span>, order490 <span style="color: blue;">43.000</span>, order491 <span style="color: blue;">252.000</span>, order492 <span style="color: blue;">244.000</span>
order493 <span style="color: blue;">208.000</span>, order494 <span style="color: blue;">136.000</span>, order495 <span style="color: blue;">141.000</span>, order496 <span style="color: blue;">264.000</span>, order497 <span style="color: blue;">294.000</span>, order498 <span style="color: blue;">185.000</span>
order499 <span style="color: blue;">115.000</span>, order500 <span style="color: blue;">153.000</span>
---- <span style="color: blue;">30</span> PARAMETER <b>maxj </b>= <span style="color: blue;">233.000</span> <i>max number of patterns we can fill</i>
</pre></div>
<div><br /></div><div><br /></div><div>This leads to a very big model:</div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">MODEL STATISTICS
BLOCKS OF EQUATIONS <span style="color: blue;">5</span> SINGLE EQUATIONS <span style="color: blue;">1</span>,<span style="color: blue;">200</span>
BLOCKS OF VARIABLES <span style="color: blue;">4</span> SINGLE VARIABLES <span style="color: blue;">116</span>,<span style="color: blue;">967</span>
NON ZERO ELEMENTS <span style="color: blue;">350</span>,<span style="color: blue;">666</span> DISCRETE VARIABLES <span style="color: blue;">116</span>,<span style="color: blue;">733</span>
</pre></div>
<div><br /></div><div><br /></div><div>But, low and behold, we can solve this model! The model can assign all 500 orders. The number of patterns used is 231: two unused patterns from our estimate. The time to solve this was about an hour (actually my time limit was 3600 seconds).</div><div><br /></div><div>Obligatory picture:</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhAYLOfWyk55cCcLy_-BzWilx0wV_E2SCC0eKe9W22PMSQCCZ5H3TA3c2sCD_novx2RQ1RDGJGIZ1YrGS9_iSedYxPN9KTM21tJO3YWl-HDP8wEgt8EyeUqrH-RAeHfOFTpWy7kAsnDFAxUeVwI1InnOd8_xMApt_6ushffTYhnCTBs5kZaTmxR0ZG_ft_Q" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="1227" data-original-width="1114" src="https://blogger.googleusercontent.com/img/a/AVvXsEhAYLOfWyk55cCcLy_-BzWilx0wV_E2SCC0eKe9W22PMSQCCZ5H3TA3c2sCD_novx2RQ1RDGJGIZ1YrGS9_iSedYxPN9KTM21tJO3YWl-HDP8wEgt8EyeUqrH-RAeHfOFTpWy7kAsnDFAxUeVwI1InnOd8_xMApt_6ushffTYhnCTBs5kZaTmxR0ZG_ft_Q=s16000" /></a></div></div><h3 style="text-align: left;">Another data set</h3><div><br /></div><div>Here is a strange result with another data set:</div><div><br /></div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">---- <span style="color: blue;">160</span> PARAMETER report performance statistics
Original Sparse Sp+Prior SC+Prior Sp+Order
Variables <span style="color: blue;">2223</span> <span style="color: blue;">2245</span> <span style="color: blue;">2245</span> <span style="color: blue;">2223</span> <span style="color: blue;">2245</span>
discrete <span style="color: blue;">2222</span> <span style="color: blue;">2222</span> <span style="color: blue;">2222</span> <span style="color: blue;">2222</span> <span style="color: blue;">2222</span>
Equations <span style="color: blue;">145</span> <span style="color: blue;">167</span> <span style="color: blue;">167</span> <span style="color: blue;">123</span> <span style="color: blue;">188</span>
Nonzeros <span style="color: blue;">8845</span> <span style="color: blue;">6711</span> <span style="color: blue;">6711</span> <span style="color: blue;">6623</span> <span style="color: blue;">6753</span>
Status Optimal Optimal Optimal Optimal IntFeas
Objective <span style="color: blue;">99</span> <span style="color: blue;">99</span> <span style="color: blue;">98</span> <span style="color: blue;">99</span> <span style="color: blue;">98</span>
Best bound <span style="color: blue;">99</span> <span style="color: blue;">99</span> <span style="color: blue;">98</span> <span style="color: blue;">99</span> <span style="color: blue;">99</span>
Time <span style="color: blue;">5</span> <span style="color: blue;">15</span> <span style="color: blue;">19</span> <span style="color: blue;">20</span> <span style="color: blue;">1006</span>
Nodes <span style="color: blue;">30279</span> <span style="color: blue;">110096</span> <span style="color: blue;">62538</span> <span style="color: blue;">67546</span> <span style="color: blue;">2198318</span>
Iterations <span style="color: blue;">394979</span> <span style="color: blue;">1127380</span> <span style="color: blue;">903107</span> <span style="color: blue;">1129896</span> <span style="color: blue;">15112872</span>
Maxj <span style="color: blue;">22</span> <span style="color: blue;">22</span> <span style="color: blue;">22</span> <span style="color: blue;">22</span> <span style="color: blue;">22</span>
Patterns <span style="color: blue;">22</span> <span style="color: blue;">22</span> <span style="color: blue;">22</span> <span style="color: blue;">22</span> <span style="color: blue;">22</span>
</pre></div>
<br /><br /><div>
We see that the original formulation is the fastest here. But more worrisome, the solver Cplex delivers wrong results for the Sparse + Branching Priorities run. Again we see how good the maxj estimate is.<div> <h3 style="text-align: left;">Conclusion</h3><div><br /></div><div>This problem of assigning orders with a given width to patterns with a short range for allowed total width is a combinatorial difficult problem, related to bin-packing. But, we actually can find optimal solutions for the large \(n=500\) problem using a standard formulation (and about an hour of time).</div><h3 style="text-align: left;"><br /></h3><h3 style="text-align: left;">References</h3><div><br /></div><div><ol style="text-align: left;"><li>MILP optimizer in Python Pyomo/PuLP not finding a feasible solution with open-source solvers, <a href="https://stackoverflow.com/questions/77492342/milp-optimizer-in-python-pyomo-pulp-not-finding-a-feasible-solution-with-open-so">https://stackoverflow.com/questions/77492342/milp-optimizer-in-python-pyomo-pulp-not-finding-a-feasible-solution-with-open-so</a></li></ol></div></div></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com0tag:blogger.com,1999:blog-593563533834706486.post-26671899417587933942023-10-21T07:49:00.027-04:002023-11-30T12:27:48.843-05:00Scheduling Team Meetings<script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style><p>This is a simple problem from [1]:</p><div style="background-color: white; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="color: #d4d4d4;"><span style="color: #005500;"><em></em></span></div><blockquote style="color: #d4d4d4;"><div><span style="color: #005500;"><em>I'm rusty on constraint optimization and am looking for help in this particular</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>use case. There are individuals who are each member to several teams. This is a</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>fixed many-to-many relationship and is determined a-priori. There are 3 time</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>slots where the teams can be scheduled to conduct a business meeting, but if an</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>individual is a member of more than one team which are both meeting at a given</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>time slot, they'll only be able to attend one. The objective is to schedule the</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>teams into the time slots, minimizing the number of overlaps of individuals.</em></span></div></blockquote><div style="color: #d4d4d4;"><span style="color: #005500;"><em></em></span><span style="color: black;"></span></div><div style="color: #d4d4d4;"></div></div><div>For beginners, it is often a good idea to split the task in two:</div><div><ol style="text-align: left;"><li>Formulate a mathematical model (on a piece of paper)</li><li>Implement the model in code</li></ol><div><span><a name='more'></a></span>If you did a good job on (1), (2) becomes usually a breeze. Once more experienced, you don't need to explicitly do step (1). This also depends on the "distance" between the tool and the math. Using modeling tools (closer to math) can help with this. </div></div><div><br /></div><div>We start with the indices. We have: \[\begin{align}&i&&\text{individuals}\\&t && \text{teams} \\ &s &&\text{time slots}\end{align}\] Next we have the data: \[\color{darkblue}m_{i,t} = \begin{cases}1 & \text{if individual $i$ is part of team $t$}\\0 & \text{otherwise}\end{cases}\]</div><div><br /></div><div>I generated some random data. In GAMS, we often use sets instead of binary parameters. Here is my random data:</div><div><br /></div><div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; text-align: left; width: auto;"><pre style="line-height: 125%; margin: 0px;">---- <span style="color: blue;">23</span> SET <b>member </b><i>team membership</i>
team1 team2 team3 team4 team5 team6
individual1 YES YES
individual2 YES
individual3 YES YES
individual4 YES YES
individual5 YES
individual6 YES YES
individual7 YES
individual8 YES YES
individual10 YES YES YES
individual11 YES YES YES YES
individual12 YES YES
individual13 YES YES
individual14 YES YES YES
individual15 YES YES
individual17 YES YES YES YES
individual18 YES
individual19 YES YES
individual20 YES YES
</pre></div>
</div><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><div><p>
We are missing some individuals: they are not in any of the teams. This is just a result of how the random set <b>member</b> was generated. We could remove those from the set \(i\), but I decided to leave them in. It is a good check to see if the model is robust enough to handle this.
</p></div></blockquote><div><br /></div><div>The binary decision variables can be: \[\color{darkred}x_{t,s} = \begin{cases}1 &\text{if team $t$ is meeting during time slot $s$}\\ 0 & \text{otherwise}\end{cases}\] and \[\color{darkred}y_{i,s} = \begin{cases}1 &\text{if individual $i$ has a meeting during time slot $s$}\\ 0 & \text{otherwise}\end{cases}\]</div><div><br /></div><div>Each team meeting is scheduled exactly once. This is simply \[\sum_s \color{darkred}x_{t,s}=1\>\>\forall t\] </div><div><br /></div><div>Minimizing the number of times an individual is double booked is a bit difficult to use as an objective. This is because checking whether a discrete variable is 2 or more requires some thought. It is easier to maximize the number of meetings each individual can attend. We can say: \[\begin{align} \max &\sum_{i,s}\color{darkred}y_{i,s} \\ & \color{darkred}y_{i,s}\le \sum_t \color{darkblue}m_{i,t}\cdot \color{darkred}x_{t,s}&&\forall i,s \end{align}\]</div><div><br /></div><div><b>This will implicitly minimize the double bookings!</b></div><div><br /></div><div>To summarize, my complete model is: \[\begin{align}\max &\sum_{i,s}\color{darkred}y_{i,s} \\ & \sum_s \color{darkred}x_{t,s}=1&&\forall t \\ & \color{darkred}y_{i,s}\le \sum_t \color{darkblue}m_{i,t}\cdot \color{darkred}x_{t,s}&&\forall i,s \\ & \color{darkred}x_{t,s} \in \{0,1\} \\ &\color{darkred}y_{i,s} \in \{0,1\} \end{align}\]</div><div><br /></div><div>We could relax \(\color{darkred}y_{i,s}\) to be continuous between 0 and 1. The results look like:</div><div><br /></div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">---- <span style="color: blue;">46</span> VARIABLE <b>x</b>.L <i>schedule team meetings at time slot</i>
timeslot1 timeslot2 timeslot3
team1 <span style="color: blue;">1</span>
team2 <span style="color: blue;">1</span>
team3 <span style="color: blue;">1</span>
team4 <span style="color: blue;">1</span>
team5 <span style="color: blue;">1</span>
team6 <span style="color: blue;">1</span>
---- <span style="color: blue;">46</span> VARIABLE <b>y</b>.L <i>individual is in meeting at time slot</i>
timeslot1 timeslot2 timeslot3
individual1 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual2 <span style="color: blue;">1</span>
individual3 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual4 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual5 <span style="color: blue;">1</span>
individual6 <span style="color: blue;">1</span>
individual7 <span style="color: blue;">1</span>
individual8 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual10 <span style="color: blue;">1</span> <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual11 <span style="color: blue;">1</span> <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual12 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual13 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual14 <span style="color: blue;">1</span> <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual15 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual17 <span style="color: blue;">1</span> <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual18 <span style="color: blue;">1</span>
individual19 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual20 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
</pre></div>
<div><br /></div><div>With a bit of postprocessing, we can see how many double bookings we have:</div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">---- <span style="color: blue;">51</span> PARAMETER <b>meetingcount </b><i>number of meetings</i>
timeslot1 timeslot2 timeslot3
individual1 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual2 <span style="color: blue;">1</span>
individual3 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual4 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual5 <span style="color: blue;">1</span>
individual6 <span style="color: blue;">2</span>
individual7 <span style="color: blue;">1</span>
individual8 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual10 <span style="color: blue;">1</span> <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual11 <span style="color: blue;">1</span> <span style="color: blue;">2</span> <span style="color: blue;">1</span>
individual12 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual13 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual14 <span style="color: blue;">1</span> <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual15 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual17 <span style="color: blue;">2</span> <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual18 <span style="color: blue;">1</span>
individual19 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual20 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
</pre></div>
<div><br /></div><div>Here meeting count is calculated as \(\sum_t \color{darkblue}m_{i,t}\cdot \color{darkred}x^*_{t,s}\).</div><div><br /></div><div>We see three instances where an individual has to miss a meeting. The double bookings are nicely distributed over different individuals. This is more or less by accident. We can observe solutions with one single person having a lot of missed meetings.</div><div><br /></div><div>We note that individuals missing in the team membership data, \(\color{darkblue}m_{i,t}\), are indeed not in the solution.</div><div> </div><h3 style="text-align: left;">Minimizing overbookings</h3><div><br /></div><div>The previous model maximizes the number of meetings each individual can attend. Here, I want to minimize the number of times an individual has to miss a meeting because 2 or more of its meetings are scheduled on the same day. In terms of the original post: <b>minimize the number of overlaps</b>.</div><div><br /></div><div>We can use something like: </div><div><br /></div><div> \[\begin{align}\min &\sum_{i,s}\color{darkred}c^{\ge 2}_{i,s} \\ & \sum_s \color{darkred}x_{t,s}=1&&\forall t \\ & \color{darkred}c^1_{i,s}+\color{darkred}c^{\ge 2}_{i,s}= \sum_t \color{darkblue}m_{i,t}\cdot \color{darkred}x_{t,s}&&\forall i,s \\ & \color{darkred}x_{t,s} \in \{0,1\} \\ &\color{darkred}c^1_{i,s} \in [0,1], \color{darkred}c^{\ge 2}_{i,s}\ge 0 \end{align}\]</div><div><br /></div><div>So we split the meet count \(\sum_t \color{darkblue}m_{i,t}\cdot \color{darkred}x_{t,s}\) into two parts. \(\color{darkred}c^1_{i,s}\) holds the part up to 1, while \(\color{darkred}c^2_{i,s}\) takes care of the counts greater than or equal to 2. We minimize the second part. That part represents the number of overlaps. The variables \(\color{darkred}c^1_{i,s}\) and \(\color{darkred}c^{\ge 2}_{i,s}\) are automatically integer-valued, so I made them continuous in the model. </div><div><br /></div><div>A slight improvement is to drop \(\color{darkred}c^1_{i,s}\) and write:</div><div><br /></div><div><div>\[\begin{align}\min &\sum_{i,s}\color{darkred}c^{\ge 2}_{i,s} \\ & \sum_s \color{darkred}x_{t,s}=1&&\forall t \\ & 1 +\color{darkred}c^{\ge 2}_{i,s}\ge \sum_t \color{darkblue}m_{i,t}\cdot \color{darkred}x_{t,s}&&\forall i,s \\ & \color{darkred}x_{t,s} \in \{0,1\} \\ & \color{darkred}c^{\ge 2}_{i,s}\ge 0 \end{align}\]</div><div><br /></div></div><div>A simpler interpretation of \(\color{darkred}c^{\ge 2}_{i,s}\) is: \[\color{darkred}c^{\ge 2}_{i,s} = \max\{0,\sum_t \color{darkblue}m_{i,t}\cdot \color{darkred}x_{t,s}-1\}\]</div><div><br /></div><div>There are many optimal solutions, so don't expect to get exactly the same schedule. However, you should see the same number of missed meetings. Here is a solution:</div><div><br /></div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">---- <span style="color: blue;">86</span> VARIABLE <b>x</b>.L <i>schedule team meetings at time slot</i>
timeslot1 timeslot2 timeslot3
team1 <span style="color: blue;">1</span>
team2 <span style="color: blue;">1</span>
team3 <span style="color: blue;">1</span>
team4 <span style="color: blue;">1</span>
team5 <span style="color: blue;">1</span>
team6 <span style="color: blue;">1</span>
---- <span style="color: blue;">86</span> VARIABLE <b>y2</b>.L <i>rest of y (part that represents >=<span style="color: blue;">2</span>)</i>
timeslot2
individual11 <span style="color: blue;">1</span>
individual14 <span style="color: blue;">1</span>
individual17 <span style="color: blue;">1</span>
---- <span style="color: blue;">86</span> PARAMETER <b>meetingcount</b> <i>number of meetings</i>
timeslot1 timeslot2 timeslot3
individual1 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual2 <span style="color: blue;">1</span>
individual3 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual4 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual5 <span style="color: blue;">1</span>
individual6 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual7 <span style="color: blue;">1</span>
individual8 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual10 <span style="color: blue;">1</span> <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual11 <span style="color: blue;">1</span> <span style="color: blue;">2</span> <span style="color: blue;">1</span>
individual12 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual13 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual14 <span style="color: blue;">1</span> <span style="color: blue;">2</span>
individual15 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual17 <span style="color: blue;">1</span> <span style="color: blue;">2</span> <span style="color: blue;">1</span>
individual18 <span style="color: blue;">1</span>
individual19 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
individual20 <span style="color: blue;">1</span> <span style="color: blue;">1</span>
</pre></div>
<div><br /></div><div><br /></div><div>Indeed, we have again 3 double bookings.</div><div><br /></div><h3 style="text-align: left;">Conclusions</h3><div><br /></div><div><ul style="text-align: left;"><li>Writing down the mathematical model is a useful exercise. Coding is much easier afterward. A math model is a blue print for the code.</li><li>Instead of minimizing double bookings, we can maximize the number of meetings attended. Both give similar solutions.</li><li>This is a nice little example with some interesting modeling angles. With a little bit of thought, we can create quite compact models. </li><li>Of course this problem is small enough for complete enumeration. Question: how many ways are there to assign 6 team meetings to three days? </li><li>The models have a lot of symmetry. E.g., we can fix the first team (or the largest team) to time slot 1.</li></ul><div><br /></div></div><h3 style="text-align: left;">References</h3><div><br /></div><div><ol style="text-align: left;"><li>Google-OR Tools: Assignment minimizing overlapping members, <a href="https://or.stackexchange.com/questions/11115/google-or-tools-assignment-minimizing-overlapping-members">https://or.stackexchange.com/questions/11115/google-or-tools-assignment-minimizing-overlapping-members</a></li></ol><div><br /></div></div><h3 style="text-align: left;">Appendix: GAMS Model</h3><div><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.6933px; margin: 0in 0in 8pt;"><o:p> </o:p></p><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.5467px; margin: 0in 0in 8pt;"><o:p> </o:p></p><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$onText</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">I'm rusty on constraint optimization and am looking for help in this particular</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">use case. There are individuals who are each member to several teams. This is a</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">fixed many-to-many relationship and is determined a-priori. There are 3 time</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">slots where the teams can be scheduled to conduct a business meeting, but if an</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">individual is a member of more than one team which are both meeting at a given</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">time slot, they'll only be able to attend one. The objective is to schedule the</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">teams into the time slots, minimizing the number of overlaps of individuals.</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">https://or.stackexchange.com/questions/11115/google-or-tools-assignment-minimizing-overlapping-members</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$offText</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* data</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">set</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">i </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'individuals'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /individual1*individual20/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">t </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'teams'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /team1*team6/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">s </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'time slot'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /timeslot1*timeslot3/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">member(i,t) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'team membership'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">member(i,t) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">uniform</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(0,1)<0.25;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> member;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* we miss some individuals in member set</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">parameter </span></b><span style="font-family: Consolas; font-size: 10.5pt;">numindiv(*) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'number of individuals'</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">numindiv(</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">'in set i'</span><span style="font-family: Consolas; font-size: 10.5pt;">) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">card</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(i);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">numindiv(</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">'team members'</span><span style="font-family: Consolas; font-size: 10.5pt;">) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(i$</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(member(i,t),1),1);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">option</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> numindiv:0;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> numindiv;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* model 1: maximize number meetings for each individual</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">binary Variables</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">x(t,s) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'schedule team meetings at time slot'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">y(i,s) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'individual is in meeting at time slot'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">variable </span></b><span style="font-family: Consolas; font-size: 10.5pt;">total </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'total number of meeting participation'</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">equations</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">obj </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'objective'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">schedule_teams(t) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'exactly one time'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">schedule_indiv(i,s) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'bound'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">schedule_teams(t).. </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(s,x(t,s)) =e= 1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">schedule_indiv(i,s).. y(i,s) =l= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(member(i,t),x(t,s));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">obj.. total =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">((i,s),y(i,s));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">model </span></b><span style="font-family: Consolas; font-size: 10.5pt;">schedule</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /all/</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">solve</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> schedule </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">maximizing</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> total </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">using</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">mip</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">option</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> x:0,y:0;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> x.l,y.l;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">parameter </span></b><span style="font-family: Consolas; font-size: 10.5pt;">meetingcount(i,s) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'number of meetings'</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">meetingcount(i,s) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(member(i,t), x.l(t,s));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">option</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> meetingcount:0;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> meetingcount;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* model 2: minimize number of double bookings</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">positive variables</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">y1(i,s) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'first part of y (0 or 1)'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">y2(i,s) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'rest of y (part that represents >=2)'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">y1.up(i,s) = 1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">variable </span></b><span style="font-family: Consolas; font-size: 10.5pt;">overbookings;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Equations</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">nummeet </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'number of meetings'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">obj2 </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'minimize double bookings'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">nummeet(i,s).. y1(i,s) + y2(i,s) =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(member(i,t),x(t,s));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">obj2.. overbookings =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">((i,s),y2(i,s));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">model </span></b><span style="font-family: Consolas; font-size: 10.5pt;">schedule2</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /obj2,nummeet,schedule_teams/</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">solve</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> schedule2 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> overbookings </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">using</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">mip</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">meetingcount(i,s) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(member(i,t), x.l(t,s));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">option</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> y2:0;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> x.l,y2.l,meetingcount;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* model 3: variant of model 2</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Equations</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">nummeet2 </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'number of meetings (bound)'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">nummeet2(i,s).. 1 + y2(i,s) =g= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(member(i,t),x(t,s));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">model </span></b><span style="font-family: Consolas; font-size: 10.5pt;">schedule3</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /obj2,nummeet2,schedule_teams/</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">solve</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> schedule3 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> overbookings </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">using</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">mip</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">meetingcount(i,s) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(member(i,t), x.l(t,s));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> x.l,y2.l,meetingcount;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p></td></tr></tbody></table><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.5467px; margin: 0in 0in 8pt;"><o:p> </o:p></p></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com2tag:blogger.com,1999:blog-593563533834706486.post-32139870219069700192023-10-20T06:54:00.014-04:002023-10-21T01:51:07.207-04:00GAMS: SMAX and sparsity<script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style><p>This is a discussion about the SMAX function in GAMS and how it behaves for sparse data.</p><p>The data structure we were facing was something like:</p><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #0000b3;"><strong>set</strong></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #0000b3;"><strong> </strong></span><span style="color: black;">i </span><span style="color: #0000da;">'cases'</span><span style="color: #007400;"> /</span><span style="color: #007400;">case1*case100000</span><span style="color: #007400;">/</span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #007400;"> </span><span style="color: black;">j </span><span style="color: #0000da;">'attribute'</span><span style="color: #007400;"> /</span><span style="color: #007400;">j1*j25</span><span style="color: #007400;">/</span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #007400;"> </span><span style="color: black;">k </span><span style="color: #0000da;">'attribute'</span><span style="color: #007400;"> /</span><span style="color: #007400;">k1*k25</span><span style="color: #007400;">/</span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #007400;"> </span><span style="color: black;">t </span><span style="color: #0000da;">'type'</span><span style="color: #007400;"> /</span><span style="color: #007400;">typ1*typ2</span><span style="color: #007400;">/</span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;">;</span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><br /></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #0000b3;"><strong>parameter </strong></span><span style="color: black;">p</span><span style="color: black;">(i,j,k,t</span><span style="color: black;">) </span><span style="color: #0000da;">'positive numbers'</span><span style="color: black;">;</span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #005500;"><em>* note: for each i we have only one (j,k) </em></span></div></div></blockquote><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div><div></div></div><p><span></span></p><a name='more'></a>The data for parameter \(\color{darkblue}p_{i,j,k,t}\) is originating from a database. A small (simulated) data set can look like:<p></p><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #005500;"><em></em></span></div></div><blockquote><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #005500;"><em>---- 20 PARAMETER p positive numbers</em></span><span style="color: black;"></span></div><div><br /></div><div><span style="color: #005500;"><em> typ1 typ2</em></span><span style="color: black;"></span></div><div><br /></div><div><span style="color: #005500;"><em>case1 .j5 .k22 0.550 0.301</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>case2 .j8 .k6 0.350 0.856</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>case3 .j2 .k13 0.998 0.579</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>case4 .j25.k20 0.131 0.640</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>case5 .j4 .k7 0.669 0.435</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>case6 .j9 .k9 0.131 0.150</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>case7 .j15.k21 0.231 0.666</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>case8 .j20.k8 0.110 0.502</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>case9 .j5 .k22 0.265 0.286</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>case10.j15.k19 0.628 0.464</em></span><span style="color: black;"></span></div><div></div></div><p></p></blockquote><p>We see that for each case \(i\), we have exactly one \(j\) and \(k\). </p><p><br /></p><h3 style="text-align: left;">First slow SMAX implementation</h3><p><br /></p><p>We want to calculate:</p><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #0000b3;"><strong>parameter </strong></span><span style="color: black;">q</span><span style="color: black;">(i,j,k</span><span style="color: black;">) </span><span style="color: #0000da;">'smax(t, p(i,j,k,t))'</span><span style="color: black;">;</span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;">q(i,j,k) = </span><span style="color: #0000b3;"><strong>smax</strong></span><span style="color: black;">(t,p(i,j,k,t))</span><span style="color: black;">;</span></div></div></blockquote><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div><div></div></div><p>This obviously gives:</p><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: #005500;"><em>---- 51 PARAMETER q smax(t, p(i,j,k,t))</em></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><br /></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: #005500;"><em>case1 .j5 .k22 0.550</em></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: #005500;"><em>case2 .j8 .k6 0.856</em></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: #005500;"><em>case3 .j2 .k13 0.998</em></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: #005500;"><em>case4 .j25.k20 0.640</em></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: #005500;"><em>case5 .j4 .k7 0.669</em></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: #005500;"><em>case6 .j9 .k9 0.150</em></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: #005500;"><em>case7 .j15.k21 0.666</em></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: #005500;"><em>case8 .j20.k8 0.502</em></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: #005500;"><em>case9 .j5 .k22 0.286</em></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: #005500;"><em>case10.j15.k19 0.628</em></span></div></div></blockquote><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="text-align: left;"><span style="color: black;"></span></div><div></div></div><p>Although this calculation is correct, it is painfully slow for large data. The reason is that parameter \(\color{darkblue}p\) is very sparse: for every \(i\) we have one \((j,k)\). It is noted that GAMS uses <b>sparse storage</b> of data: i.e. "<i>does not exist and being zero is the same</i>". In GAMS, <b>the sum function is very fast</b> when running over sparse data: we can safely skip the zero values. However, when calculating the smax function, we can't skip safely all zeros. It will evaluate the maximum over all possible combinations \((i,j,k)\) including ones we have no data for. When using 100,000 cases this smax calculation takes 7.2 seconds. </p><p></p><blockquote><p>For \(|I|=10\) cases, we have \(|I|\cdot|J|\cdot|K| = 10\cdot25\cdot25 = 6,250\). For \(|I|=100,000\) this becomes 62.5 million. These are large numbers!</p></blockquote><p><br /></p><h3 style="text-align: left;">Faster alternatives: exploit sparsity</h3><p><br /></p><p>A fast version will protect us from running over the Cartesian product \(I\times J\times K\). A first version is:</p><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #0000b3;"><strong>parameter </strong></span><span style="color: black;">q2</span><span style="color: black;">(i,j,k</span><span style="color: black;">)</span><span style="color: black;">;</span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;">q2(i,j,k)$</span><span style="color: #0000b3;"><strong>sum</strong></span><span style="color: black;">(t,p(i,j,k,t)) = </span><span style="color: #0000b3;"><strong>smax</strong></span><span style="color: black;">(t,p(i,j,k,t))</span><span style="color: black;">;</span></div></div></blockquote><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div><div></div></div><p>This assumes \(\color{darkblue}p\ge 0\). The <span style="font-family: courier;">$sum</span> construct says: only do the assignment if one or more of the \(\color{darkblue}p_{i,j,k,t}\) is non-zero. This version does not work always correctly if negative \(\color{darkblue}p\) are allowed. For instance \(-2+2=0\), so a sum of zero does not imply that each value is zero. In the case where we allow negative values, we can do something like:</p><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #0000b3;"><strong>parameter </strong></span><span style="color: black;">q3</span><span style="color: black;">(i,j,k</span><span style="color: black;">)</span><span style="color: black;">;</span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;">q3(i,j,k)$</span><span style="color: #0000b3;"><strong>sum</strong></span><span style="color: black;">(t$p(i,j,k,t),1) = </span><span style="color: #0000b3;"><strong>smax</strong></span><span style="color: black;">(t,p(i,j,k,t))</span><span style="color: black;">;</span></div></div></blockquote><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div><div></div></div><p>This version explicitly counts the number of nonzero elements \(\color{darkblue}p_{i,j,k,t}\) over \(t\). The profiling information </p><p><span style="font-family: courier;">--- Profile Summary (6 records processed)<br /> 7.187 0.034GB 27 Assignment q (100000)<br /> 0.047 0.043GB 36 Assignment q2 (100000)<br /> 0.031 0.051GB 42 Assignment q3 (100000)</span> </p><p>indicates that our fast versions are more than 100 times as fast (the first column contains the timings). The difference in timings between versions q2 and q3 is just noise.</p><p>My preferred approach is to explicitly store the sparsity pattern of the \((i,j,k)\) tuples into a separate set. We can do:</p><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #0000b3;"><strong>set </strong></span><span style="color: black;">ijk</span><span style="color: black;">(i,j,k</span><span style="color: black;">)</span><span style="color: black;">;</span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;">ijk(i,j,k) = </span><span style="color: #0000b3;"><strong>sum</strong></span><span style="color: black;">(t$p(i,j,k,t),1)</span><span style="color: black;">;</span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #0000b3;"><strong>parameter </strong></span><span style="color: black;">q4</span><span style="color: black;">(i,j,k</span><span style="color: black;">)</span><span style="color: black;">;</span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;">q4(ijk) = </span><span style="color: #0000b3;"><strong>smax</strong></span><span style="color: black;">(t,p(ijk,t))</span><span style="color: black;">;</span></div></div></blockquote><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div></div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;"></span></div><div></div></div><p class="MsoNormal"><o:p></o:p></p><div style="text-align: left;">Often, when we import sparse data tables, it is a good idea to form sets representing the sparsity patterns. That will allow us to more efficiently operate on the data.</div><h3 style="text-align: left;"><br /></h3><h3 style="text-align: left;">Conclusion</h3><div><br /></div><div>Often, exploiting sparsity comes naturally in GAMS models. But sometimes, we need to pay close attention and make sure we don't operate on the Cartesian product of sets. <b>Large, data-intensive models require much more care than small ones.</b> </div><div><br /></div><h3 style="text-align: left;">Appendix: GAMS model</h3><div><br /></div><div>Experiments with randomly generated data.</div><div><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.6933px; margin: 0in 0in 8pt;"><o:p> </o:p></p><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">set</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* <span class="SpellE">i</span> 'cases' /case1*case10/</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">i</span></span><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'cases'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /case1*case100000/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">j </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'attribute'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /j1*j25/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">k </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'attribute'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /k1*k25/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">t </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'type'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /typ1*typ2/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">parameter </span></b><span style="font-family: Consolas; font-size: 10.5pt;">p(<span class="SpellE"><span class="GramE">i,j</span>,k,t</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'positive numbers'</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* note: for each <span class="SpellE">i,</span> we have only one (<span class="SpellE"><span class="GramE">j,k</span></span>)</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">scalar </span></b><span style="font-family: Consolas; font-size: 10.5pt;">s<span class="GramE">1,s</span>2;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">loop</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">i</span></span><span style="font-family: Consolas; font-size: 10.5pt;">,</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;"> s1 = </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">uniformint</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="GramE">1,<b><span style="color: #0000b3;">card</span></b></span>(j));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;"> s2 = </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">uniformint</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="GramE">1,<b><span style="color: #0000b3;">card</span></b></span>(k));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;"> p(<span class="SpellE"><span class="GramE">i,j</span>,k,t</span>)$(</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">ord</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(j)=s1 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">and</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">ord</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(k)=s2) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">uniform</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(0,1); </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">option</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">p:3:3:1</span>;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;">$(</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">card</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>)<=100) <span class="GramE">p;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">option</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">profile</span></b><span style="font-family: Consolas; font-size: 10.5pt;">=<span class="GramE">1;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* version <span class="GramE">1 (</span>very slow)</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* This calculates the <span class="SpellE">smax</span> for all combinations (<span class="SpellE"><span class="GramE">i,j</span>,k</span>) (<span class="SpellE">cartesian</span> product)</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">parameter </span></b><span style="font-family: Consolas; font-size: 10.5pt;">q(<span class="SpellE"><span class="GramE">i,j</span>,k</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'<span class="SpellE">smax</span>(t, p(<span class="SpellE">i,j,k,t</span>))'</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">q(<span class="SpellE"><span class="GramE">i,j</span>,k</span>) = </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">smax</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">t,p</span>(<span class="SpellE">i,j,k,t</span>));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">option</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">q:3:0:1</span>;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;">$(</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">card</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>)<=100) <span class="GramE">q;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* version <span class="GramE">2 (</span>fast)</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* This skips the <span class="SpellE">smax</span> for non-existent combinations (<span class="SpellE"><span class="GramE">i,j</span>,k</span>)</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">assumption</span>: p>=0</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">parameter </span></b><span style="font-family: Consolas; font-size: 10.5pt;">q2(<span class="SpellE"><span class="GramE">i,j</span>,k</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">q2(<span class="SpellE"><span class="GramE">i,j</span>,k</span>)$</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">t,p</span>(<span class="SpellE">i,j,k,t</span>)) = </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">smax</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">t,p</span>(<span class="SpellE">i,j,k,t</span>));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">version</span> 3: also works with negative values p (fast)</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* H<span class="GramE">ere,</span> the $sum is counting nonzero values</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">parameter </span></b><span style="font-family: Consolas; font-size: 10.5pt;">q3(<span class="SpellE"><span class="GramE">i,j</span>,k</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">q3(<span class="SpellE"><span class="GramE">i,j</span>,k</span>)$</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">t$p</span>(<span class="SpellE">i,j,k,t</span>),1) = </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">smax</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">t,p</span>(<span class="SpellE">i,j,k,t</span>));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">version</span> 4. Introduce a set with existing <span class="GramE">combinations</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* (<span class="GramE">also</span> fast, but ijk+q4 takes a bit more time)</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">set </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">ijk</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span>,k</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">ijk</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span>,k</span>) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">t$p</span>(<span class="SpellE">i,j,k,t</span>),1);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">parameter </span></b><span style="font-family: Consolas; font-size: 10.5pt;">q4(<span class="SpellE"><span class="GramE">i,j</span>,k</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span lang="NL" style="font-family: Consolas; font-size: 10.5pt;">q</span></span><span lang="NL" style="font-family: Consolas; font-size: 10.5pt;">4(ijk) = </span><span class="SpellE"><b><span lang="NL" style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">smax</span></b></span><span lang="NL" style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">t,p</span>(<span class="SpellE">ijk,t</span>));</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p></td></tr></tbody></table><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.6933px; margin: 0in 0in 8pt;"><span lang="NL"> </span></p></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com0tag:blogger.com,1999:blog-593563533834706486.post-79875209128038042012023-10-19T03:11:00.008-04:002023-10-21T01:59:41.298-04:00Plotting NUTS-2 maps from GAMS<p> NUTS-2 regions are statistical subnational regions (often provinces), mainly for the EU and UK [1]. </p><p><br /></p><p></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEiAJsP9eyii06MpsLW_NeyMXyMrtpYPLkcuiQEOp57QU_VF6TiHlswsT4FDEo3CvPANSmOYm5lRqjYDyEkJP_EAnQLcnECCTmin5kdzuVuwEamSv6rpYQiMdS1eKfxFNnIHDYLf_TIUMilihssiAkSx8q5MqIx5aJ6-4wSnsNOHLZnP4K20UmErDemjlj7j" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="420" data-original-width="504" src="https://blogger.googleusercontent.com/img/a/AVvXsEiAJsP9eyii06MpsLW_NeyMXyMrtpYPLkcuiQEOp57QU_VF6TiHlswsT4FDEo3CvPANSmOYm5lRqjYDyEkJP_EAnQLcnECCTmin5kdzuVuwEamSv6rpYQiMdS1eKfxFNnIHDYLf_TIUMilihssiAkSx8q5MqIx5aJ6-4wSnsNOHLZnP4K20UmErDemjlj7j=s16000" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">NUTS hierarchy (from [1])</td></tr></tbody></table><br />In [2] we can find mapping information in the form of Shapefiles[3] and related formats. I used the <b>GeoJSON</b>[4]<b> </b>format, and created a Python notebook script to extract a GAMS set from that file. The file is reproduced in the appendix below. The NUTS-2 codes form the set elements, and the name is stored as explanatory text. There is an option to generate Latin names instead of using the native alphabet. The Latin names are also inside the geojson file. E.g. we have: <p></p><p><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">EL<span class="GramE">65 <span style="color: #005078;">'</span></span></span><span class="SpellE" face="Calibri, sans-serif" style="font-size: 14.6667px;"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Πελο</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">πόννησος'</span></p><p>which is in the Greek alphabet. Using the Latin name, this would look like:</p><p class="MsoNormal" style="background: white; line-height: 14.25pt; margin-bottom: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">EL65 </span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">'Peloponnisos'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;"><o:p></o:p></span></p><p><span></span></p><a name='more'></a>I like to have this set available for use in a GAMS model, so we don't have to guess what the plottable regions are. Furthermore, we can use this set as a domain, so GAMS will check we don't use an unknown region. The include file is written using UTF-8 encoding to allow accurate representation of the region names. In GAMS, we can use unicode string only for set elements and explanatory text. Programming languages like Python and Julia allow unicode identifiers, but GAMS does not.<p></p><p>To make a map, I generate from GAMS an HTML document that uses the d3 Javascript library [5]. Using random values:</p><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #005500;"><em>*-----------------------------------------------------------------------</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>* random data</em></span><span style="color: black;"></span></div><div><span style="color: #005500;"><em>*-----------------------------------------------------------------------</em></span><span style="color: black;"></span></div><div><span style="color: #0000b3;"><strong>alias</strong></span><span style="color: black;">(r,nuts2)</span><span style="color: black;">;</span><span style="color: black;"></span></div><div><br /></div><div><span style="color: #0000b3;"><strong>parameter </strong></span><span style="color: black;">data</span><span style="color: black;">(r</span><span style="color: black;">) </span><span style="color: #0000da;">'random data'</span><span style="color: black;">;</span><span style="color: black;"></span></div><div><span style="color: black;">data(r) = </span><span style="color: #0000b3;"><strong>uniform</strong></span><span style="color: black;">(0,100)</span><span style="color: black;">;</span><span style="color: black;"></span></div><div><span style="color: #0000b3;"><strong>display</strong></span><span style="color: black;"> data</span><span style="color: black;">;</span><span style="color: black;"></span></div><div></div></div><p>a demo map looks like:</p><p><br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEh0ehRfr09UdcebYNLWmcPXwWNELrP1VhXxXi9LX2TEFjz6KXCSJx7wrVIIilD9Ytl4vkv5pp1rMDRFn1umMe00It9SRF6_WsE4iEQ_pSQf2APCp9FcTjXRVi4p_YPMjwiwMDzmWFQp9y_tkFr00_at1WkfJavTR4Lvd8Sr1xgDoLsSPGRD_QxLVQ9aqX5j" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="759" data-original-width="972" height="501" src="https://blogger.googleusercontent.com/img/a/AVvXsEh0ehRfr09UdcebYNLWmcPXwWNELrP1VhXxXi9LX2TEFjz6KXCSJx7wrVIIilD9Ytl4vkv5pp1rMDRFn1umMe00It9SRF6_WsE4iEQ_pSQf2APCp9FcTjXRVi4p_YPMjwiwMDzmWFQp9y_tkFr00_at1WkfJavTR4Lvd8Sr1xgDoLsSPGRD_QxLVQ9aqX5j=w640-h501" width="640" /></a></div><br />The map is interactive. Hovering the mouse cursor over a region gives more information:<div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjgNYhDxkuVUvi6YAqVrD_YXyFFxFI691BHO1xTh0KDqkLbXylwRgE0oEBhX5pnd3CVSg5MwxxqCvOmICi3Xey9EyKIP-1DqL9HBRz69ODFu_PZhRJKg-3DWX8oCsyrhoghCXONMwfZYFQuVE0zn6SMqYmaM-ymTVw6MmG8OeEie-8XBSW4rpyuhQtuYhhz" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="284" data-original-width="363" height="240" src="https://blogger.googleusercontent.com/img/a/AVvXsEjgNYhDxkuVUvi6YAqVrD_YXyFFxFI691BHO1xTh0KDqkLbXylwRgE0oEBhX5pnd3CVSg5MwxxqCvOmICi3Xey9EyKIP-1DqL9HBRz69ODFu_PZhRJKg-3DWX8oCsyrhoghCXONMwfZYFQuVE0zn6SMqYmaM-ymTVw6MmG8OeEie-8XBSW4rpyuhQtuYhhz" width="307" /></a></div>Again, this map can be configured to display the Latin names instead.<br /><br /><p></p><h3 style="text-align: left;">Conclusion</h3><p><br /></p><p>This is a simple tool to generate maps from GAMS model results. It is useful to produce quick visualizations. I have used this approach also for other projects, using different maps.</p><p><br /></p><h3 style="text-align: left;">References</h3><p><br /></p><p></p><ol style="text-align: left;"><li>NUTS - Nomenclature of territorial units for statistics, Background, <a href="https://ec.europa.eu/eurostat/web/nuts/background">https://ec.europa.eu/eurostat/web/nuts/background</a></li><li><a href="https://ec.europa.eu/eurostat/web/gisco/geodata/reference-data/administrative-units-statistical-units/nuts">https://ec.europa.eu/eurostat/web/gisco/geodata/reference-data/administrative-units-statistical-units/nuts</a></li><li>Shapefile, <a href="https://en.wikipedia.org/wiki/Shapefile">https://en.wikipedia.org/wiki/Shapefile</a></li><li>GeoJSON, <a href="https://en.wikipedia.org/wiki/GeoJSON">https://en.wikipedia.org/wiki/GeoJSON</a></li><li><a href="https://d3js.org/">https://d3js.org/</a></li></ol><div><br /></div><h3 style="text-align: left;">Appendix: Generated GAMS include file</h3><div><br /></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* Regions extracted from c:/users/erwin/nuts2map/nuts2.geojson</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* Contents:</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">set nuts</span>2: all nuts2 regions in the <span class="SpellE">geojson</span> file</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">ordered</span> alphabetically</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">* Generated: 2023-10-18</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #005500; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">set </span></b><span style="font-family: Consolas; font-size: 10.5pt;">nuts2 </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'NUTS2 regions'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;">AL<span class="GramE">01 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Veri</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> AL<span class="GramE">02 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Qender</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> AL<span class="GramE">03 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Jug</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">AT<span class="GramE">11 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Burgenland'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> AT<span class="GramE">12 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Niederösterreich'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> AT<span class="GramE">13 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Wien'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> AT<span class="GramE">21 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Kärnten'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> AT<span class="GramE">22 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Steiermark'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> AT<span class="GramE">31 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Oberösterreich</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> AT<span class="GramE">32 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Salzburg'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> AT<span class="GramE">33 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Tirol'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> AT<span class="GramE">34 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Vorarlberg'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;">BE<span class="GramE">10 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Région</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> de Bruxelles-<span class="SpellE">Capitale</span>/ Brussels Hoofdstedelijk Gewest'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">BE<span class="GramE">21 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Prov. Antwerpen'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> BE<span class="GramE">22 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Prov. Limburg (BE)'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> BE<span class="GramE">23 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Prov. </span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Oost-Vlaanderen'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> BE<span class="GramE">24 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Prov. Vlaams-Brabant'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">BE<span class="GramE">25 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Prov. West-<span class="SpellE">Vlaanderen</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> BE<span class="GramE">31 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Prov. Brabant Wallon'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> BE<span class="GramE">32 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Prov. Hainaut'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> BE<span class="GramE">33 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Prov. Liège'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> BE<span class="GramE">34 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Prov. Luxembourg (BE)'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> BE<span class="GramE">35 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Prov. Namur'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> BG<span class="GramE">31 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Северозападен</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> BG<span class="GramE">32 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Северен</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">централен</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> BG<span class="GramE">33 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Североизточен</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> BG<span class="GramE">34 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Югоизточен</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> BG<span class="GramE">41 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Югозападен</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> BG<span class="GramE">42 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Южен</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">централен</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> CH<span class="GramE">01 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Région</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">lémanique</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> CH<span class="GramE">02 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Espace</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">Mittelland</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> CH<span class="GramE">03 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Nordwestschweiz</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> CH<span class="GramE">04 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Zürich'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> CH<span class="GramE">05 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Ostschweiz</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> CH<span class="GramE">06 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Zentralschweiz</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> CH<span class="GramE">07 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Ticino'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> CY<span class="GramE">00 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Κύ</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">προς'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> CZ<span class="GramE">01 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Praha'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> CZ<span class="GramE">02 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Střední</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">Čechy</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> CZ<span class="GramE">03 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Jihozápad</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> CZ<span class="GramE">04 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Severozápad</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> CZ<span class="GramE">05 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Severovýchod</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> CZ<span class="GramE">06 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Jihovýchod</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> CZ<span class="GramE">07 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Střední</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> Morava'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> CZ<span class="GramE">08 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Moravskoslezsko</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">11 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Stuttgart'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;">DE<span class="GramE">12 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Karlsruhe'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">13 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Freiburg'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">14 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Tübingen'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">21 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Oberbayern</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">22 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Niederbayern</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">23 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Oberpfalz</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">24 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Oberfranken'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">25 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Mittelfranken</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">26 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Unterfranken</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">27 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Schwaben</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">30 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Berlin'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">40 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Brandenburg'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">50 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Bremen'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">60 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Hamburg'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">71 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Darmstadt'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">72 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Gießen</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">73 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Kassel'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">80 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Mecklenburg-Vorpommern</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">91 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Braunschweig'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">92 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Hannover'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">93 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Lüneburg</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DE<span class="GramE">94 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Weser-Ems</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DEA<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Düsseldorf'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DEA<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Köln'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DEA<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Münster'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">DEA<span class="GramE">4 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Detmold'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DEA<span class="GramE">5 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Arnsberg'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DEB<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Koblenz'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;">DEB<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Trier'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DEB<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Rheinhessen-Pfalz</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DEC<span class="GramE">0 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Saarland'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">DED<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Dresden'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DED<span class="GramE">4 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Chemnitz'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DED<span class="GramE">5 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Leipzig'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;">DEE<span class="GramE">0 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Sachsen-Anhalt</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DEF<span class="GramE">0 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Schleswig</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">-Holstein'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DEG<span class="GramE">0 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Thüringen'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DK<span class="GramE">01 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Hovedstaden</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DK<span class="GramE">02 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Sjælland</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DK<span class="GramE">03 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Syddanmark</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DK<span class="GramE">04 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Midtjylland</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> DK<span class="GramE">05 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Nordjylland</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> EE<span class="GramE">00 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Eesti'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> EL<span class="GramE">30 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">A</span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">ττική</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> EL<span class="GramE">41 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Βόρειο</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Αιγ</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">αίο</span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> EL<span class="GramE">42 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Νότιο</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Αιγ</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">αίο</span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> EL<span class="GramE">43 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Κρήτη</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> EL<span class="GramE">51 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">A</span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">να<span class="SpellE">τολική</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Μα<span class="SpellE">κεδονί</span>α</span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">, </span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Θράκη</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> EL<span class="GramE">52 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Κεντρική</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Μα<span class="SpellE">κεδονί</span>α</span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> EL<span class="GramE">53 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Δυτική</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Μα<span class="SpellE">κεδονί</span>α</span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> EL<span class="GramE">54 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Ήπ<span class="SpellE">ειρος</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> EL<span class="GramE">61 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Θεσσ</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">αλία</span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> EL<span class="GramE">62 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Ιόνι</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">α</span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Νησιά</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> EL<span class="GramE">63 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Δυτική</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Ελλάδ</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">α</span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> EL<span class="GramE">64 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Στερεά</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Ελλάδ</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">α</span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">EL<span class="GramE">65 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Πελο</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">πόννησος'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">11 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Galicia'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">12 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Principado</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> de Asturias'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">13 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Cantabria'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">21 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">País Vasco'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">22 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Comunidad</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> Foral de Navarra'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">23 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">La Rioja'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">24 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Aragón'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">30 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Comunidad</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> de Madrid'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">41 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Castilla y León'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">42 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Castilla-La Mancha'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">43 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Extremadura'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">51 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Cataluña'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">52 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Comunitat</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> Valenciana'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">53 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Illes <span class="SpellE">Balears</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">61 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Andalucía'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">62 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Región</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> de Murcia'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">63 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Ciudad de Ceuta'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ES<span class="GramE">64 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Ciudad de Melilla'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FI<span class="GramE">19 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Länsi</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">-Suomi'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FI1<span class="GramE">B <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Helsinki-<span class="SpellE">Uusimaa</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FI1<span class="GramE">C <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Etelä</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">-Suomi'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FI1<span class="GramE">D <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Pohjois</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">- ja <span class="SpellE">Itä</span>-Suomi'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FI<span class="GramE">20 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Åland</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;">FR<span class="GramE">10 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Ile</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">-de-France'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRB<span class="GramE">0 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Centre — Val de Loire'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">FRC<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Bourgogne'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRC<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Franche-Comté'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRD<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Basse-Normandie'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;">FRD<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Haute-<span class="SpellE">Normandie</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRE<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Nord-Pas de Calais'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">FRE<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Picardie'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRF<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Alsace'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRF<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Champagne-Ardenne'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRF<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Lorraine'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRG<span class="GramE">0 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Pays de la Loire'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRH<span class="GramE">0 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Bretagne'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRI<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Aquitaine'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRI<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Limousin'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRI<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Poitou-Charentes'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRJ<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Languedoc-Roussillon'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRJ<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Midi-Pyrénées'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRK<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Auvergne'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRK<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Rhône-Alpes'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRL<span class="GramE">0 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Provence-Alpes-Côte d’Azur'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> FRM<span class="GramE">0 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Corse'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> HR<span class="GramE">02 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Panonska</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> Hrvatska'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> HR<span class="GramE">03 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Jadranska</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> Hrvatska'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;">HR<span class="GramE">05 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Grad</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> Zagreb'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> HR<span class="GramE">06 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Sjeverna</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> Hrvatska'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> HU<span class="GramE">11 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Budapest'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> HU<span class="GramE">12 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Pest'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> HU<span class="GramE">21 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Közép-Dunántúl</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> HU<span class="GramE">22 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Nyugat-Dunántúl</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> HU<span class="GramE">23 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Dél-<span class="SpellE">Dunántúl</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> HU<span class="GramE">31 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Észak-Magyarország</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> HU<span class="GramE">32 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Észak-Alföld</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">HU<span class="GramE">33 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Dél-Alföld</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> IE<span class="GramE">04 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Northern and Western'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> IE<span class="GramE">05 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Southern'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> IE<span class="GramE">06 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Eastern and Midland'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> IS<span class="GramE">00 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Ísland</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITC<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Piemonte'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITC<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Valle d’Aosta/<span class="SpellE">Vallée</span> <span class="SpellE">d’Aoste</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITC<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Liguria'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITC<span class="GramE">4 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Lombardia</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITF<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Abruzzo'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITF<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Molise'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITF<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Campania'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITF<span class="GramE">4 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Puglia'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITF<span class="GramE">5 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Basilicata'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITF<span class="GramE">6 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Calabria'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITG<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Sicilia'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITG<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Sardegna'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITH<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Provincia</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">Autonoma</span> di Bolzano/<span class="SpellE">Bozen</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITH<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Provincia</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">Autonoma</span> di Trento'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITH<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Veneto'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITH<span class="GramE">4 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Friuli-Venezia Giulia'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITH<span class="GramE">5 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Emilia-Romagna'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITI<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Toscana'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITI<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Umbria'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITI<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Marche'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ITI<span class="GramE">4 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Lazio'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> LI<span class="GramE">00 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Liechtenstein'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> LT<span class="GramE">01 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Sostinės</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">regionas</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> LT<span class="GramE">02 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Vidurio</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">ir</span> <span class="SpellE">vakarų</span> <span class="SpellE">Lietuvos</span> <span class="SpellE">regionas</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> LU<span class="GramE">00 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Luxembourg'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> LV<span class="GramE">00 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Latvija</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> ME<span class="GramE">00 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Црна</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">Гора</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> MK<span class="GramE">00 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Северна</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">Македонија</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> MT<span class="GramE">00 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Malta'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> NL<span class="GramE">11 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Groningen'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;">NL<span class="GramE">12 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Friesland (NL)'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> NL<span class="GramE">13 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Drenthe'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> NL<span class="GramE">21 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Overijssel'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> NL<span class="GramE">22 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Gelderland'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> NL<span class="GramE">23 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Flevoland'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> NL<span class="GramE">31 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Utrecht'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> NL<span class="GramE">32 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Noord-Holland'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> NL<span class="GramE">33 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Zuid-Holland'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> NL<span class="GramE">34 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Zeeland'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> NL<span class="GramE">41 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Noord-Brabant'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> NL<span class="GramE">42 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Limburg (NL)'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">NO<span class="GramE">02 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Innlandet</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> NO<span class="GramE">06 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Trøndelag</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> NO<span class="GramE">07 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Nord-Norge'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> NO<span class="GramE">08 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Oslo <span class="SpellE">og</span> Viken'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> NO<span class="GramE">09 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Agder <span class="SpellE">og</span> <span class="SpellE">Sør-Østlandet</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> NO0<span class="GramE">A <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Vestlandet</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">21 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Małopolskie</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">22 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Śląskie</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">41 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Wielkopolskie</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">42 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Zachodniopomorskie</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">43 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Lubuskie</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">51 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Dolnośląskie</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">52 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Opolskie</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">61 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Kujawsko-pomorskie</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">62 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Warmińsko-mazurskie</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">63 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Pomorskie</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">71 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Łódzkie</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">72 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Świętokrzyskie</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">81 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Lubelskie</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">82 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Podkarpackie</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">84 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Podlaskie</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">91 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Warszawski <span class="SpellE">stołeczny</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PL<span class="GramE">92 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Mazowiecki <span class="SpellE">regionalny</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PT<span class="GramE">11 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Norte'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PT<span class="GramE">15 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Algarve'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PT<span class="GramE">16 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Centro (PT)'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PT<span class="GramE">17 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Área</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">Metropolitana</span> de Lisboa'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> PT<span class="GramE">18 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Alentejo</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> RO<span class="GramE">11 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Nord-Vest'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> RO<span class="GramE">12 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Centru</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> RO<span class="GramE">21 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Nord-Est'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> RO<span class="GramE">22 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Sud-Est'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> RO<span class="GramE">31 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Sud-<span class="SpellE">Muntenia</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> RO<span class="GramE">32 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Bucureşti</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">-Ilfov'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> RO<span class="GramE">41 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Sud-Vest <span class="SpellE">Oltenia</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> RO<span class="GramE">42 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Vest'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> RS<span class="GramE">11 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Београдски</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">регион</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> RS<span class="GramE">12 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Регион</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">Војводине</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> RS<span class="GramE">21 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Регион</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">Шумадије</span> и <span class="SpellE">Западне</span> <span class="SpellE">Србије</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> RS<span class="GramE">22 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Регион</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">Јужне</span> и <span class="SpellE">Источне</span> <span class="SpellE">Србије</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> SE<span class="GramE">11 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Stockholm'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> SE<span class="GramE">12 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Östra</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">Mellansverige</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> SE<span class="GramE">21 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Småland</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> med <span class="SpellE">öarna</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> SE<span class="GramE">22 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Sydsverige</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;">SE<span class="GramE">23 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Västsverige</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> SE<span class="GramE">31 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Norra</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">Mellansverige</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> SE<span class="GramE">32 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Mellersta</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">Norrland</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> SE<span class="GramE">33 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Övre</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">Norrland</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> SI<span class="GramE">03 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Vzhodna</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> Slovenija'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> SI<span class="GramE">04 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Zahodna</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> Slovenija'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> SK<span class="GramE">01 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Bratislavský</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">kraj</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> SK<span class="GramE">02 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Západné</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> Slovensko'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> SK<span class="GramE">03 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Stredné</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> Slovensko'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> SK<span class="GramE">04 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Východné</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> Slovensko'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">10 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">İstanbul'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">21 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Tekirdağ</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">, <span class="SpellE">Edirne</span>, <span class="SpellE">Kırklareli</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">22 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Balıkesir</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">, <span class="SpellE">Çanakkale</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">31 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">İzmir'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">32 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Aydın</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">, Denizli, <span class="SpellE">Muğla</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">33 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Manisa</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">, <span class="SpellE">Afyonkarahisar</span>, <span class="SpellE">Kütahya</span>, <span class="SpellE">Uşak</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">41 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Bursa, <span class="SpellE">Eskişehir</span>, <span class="SpellE">Bilecik</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">42 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Kocaeli</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">, <span class="SpellE">Sakarya</span>, <span class="SpellE">Düzce</span>, <span class="SpellE">Bolu</span>, <span class="SpellE">Yalova</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">51 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Ankara'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">52 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Konya, <span class="SpellE">Karaman</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">61 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Antalya, <span class="SpellE">Isparta</span>, <span class="SpellE">Burdur</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">62 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Adana, Mersin'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">63 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Hatay</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">, <span class="SpellE">Kahramanmaraş</span>, <span class="SpellE">Osmaniye</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">71 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Kırıkkale</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">, <span class="SpellE">Aksaray</span>, <span class="SpellE">Niğde</span>, <span class="SpellE">Nevşehir</span>, <span class="SpellE">Kırşehir</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">72 <span style="color: #005078;">'</span></span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Kayseri, <span class="SpellE">Sivas</span>, <span class="SpellE">Yozgat</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">81 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Zonguldak</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">, <span class="SpellE">Karabük</span>, <span class="SpellE">Bartın</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">82 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Kastamonu</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">, <span class="SpellE">Çankırı</span>, <span class="SpellE">Sinop</span>'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TR<span class="GramE">83 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Samsun</span></span><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;">, <span class="SpellE">Tokat</span>, <span class="SpellE">Çorum</span>, Amasya'</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">TR<span class="GramE">90 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Trabzon, <span class="SpellE">Ordu</span>, Giresun, <span class="SpellE">Rize</span>, <span class="SpellE">Artvin</span>, <span class="SpellE">Gümüşhane</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TRA<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Erzurum, Erzincan, Bayburt'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TRA<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Ağrı</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">, Kars, <span class="SpellE">Iğdır</span>, <span class="SpellE">Ardahan</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TRB<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Malatya, <span class="SpellE">Elazığ</span>, Bingöl, <span class="SpellE">Tunceli</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TRB<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Van, <span class="SpellE">Muş</span>, <span class="SpellE">Bitlis</span>, Hakkari'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TRC<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Gaziantep, Adıyaman, Kilis'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TRC<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Şanlıurfa</span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">, <span class="SpellE">Diyarbakır</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> TRC<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Mardin, Batman, <span class="SpellE">Şırnak</span>, <span class="SpellE">Siirt</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKC<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Tees Valley and Durham'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKC<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Northumberland and Tyne and Wear'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKD<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Cumbria'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKD<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Greater Manchester'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKD<span class="GramE">4 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Lancashire'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKD<span class="GramE">6 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Cheshire'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKD<span class="GramE">7 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Merseyside'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKE<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">East Yorkshire and Northern Lincolnshire'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKE<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">North Yorkshire'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKE<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">South Yorkshire'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKE<span class="GramE">4 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">West Yorkshire'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKF<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Derbyshire and Nottinghamshire'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKF<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Leicestershire, Rutland and Northamptonshire'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKF<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Lincolnshire'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKG<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Herefordshire, Worcestershire and Warwickshire'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKG<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Shropshire and Staffordshire'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKG<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">West Midlands'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKH<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">East Anglia'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKH<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Bedfordshire and Hertfordshire'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKH<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Essex'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKI<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Inner London — West'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKI<span class="GramE">4 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Inner London — East'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKI<span class="GramE">5 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Outer London — East and North East'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKI<span class="GramE">6 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Outer London — South'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKI<span class="GramE">7 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Outer London — West and North West'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKJ<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Berkshire, Buckinghamshire and Oxfordshire'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKJ<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Surrey, East and West Sussex'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKJ<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Hampshire and Isle of Wight'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKJ<span class="GramE">4 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Kent'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKK<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Gloucestershire, Wiltshire and Bristol/Bath area'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKK<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Dorset and Somerset'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKK<span class="GramE">3 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Cornwall and Isles of Scilly'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKK<span class="GramE">4 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Devon'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKL<span class="GramE">1 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">West Wales and The Valleys'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKL<span class="GramE">2 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">East <span class="SpellE">Wales'</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKM<span class="GramE">5 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">North Eastern Scotland'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKM<span class="GramE">6 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Highlands and Islands'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKM<span class="GramE">7 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Eastern Scotland'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKM<span class="GramE">8 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">West Central Scotland'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKM<span class="GramE">9 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Southern Scotland'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> UKN<span class="GramE">0 <span style="color: #005078;">'</span></span></span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">Northern Ireland'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">/</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p></td></tr></tbody></table><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.6933px; margin: 0in 0in 8pt;"><o:p> </o:p></p></div><p></p></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com0tag:blogger.com,1999:blog-593563533834706486.post-69786996602745877652023-10-05T04:20:00.023-04:002023-10-09T14:44:15.638-04:00Linear Programming Nonsense?<h3 style="text-align: left;">1. Inventory balance constraints</h3><div><br /></div><script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style>I came accross this text [1]:<div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEirVglwS7E-eO1fHjrvU1_epQDMDFzfDFO8S8lfYxtyVBWLY2HrebBIzg9F1aRQ0PjenxuM5gXqoHDhOiDMUBPZRDCR-ElwVd9GVl1fVkyfbGs5MqVxMTD1ex9Ki-7pyASLljR9Azni-AmMwzIdhrBueNI7bQFjpSLdpx3LK5AW893IrWvp17JoW37Od5FT" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="419" data-original-width="786" src="https://blogger.googleusercontent.com/img/a/AVvXsEirVglwS7E-eO1fHjrvU1_epQDMDFzfDFO8S8lfYxtyVBWLY2HrebBIzg9F1aRQ0PjenxuM5gXqoHDhOiDMUBPZRDCR-ElwVd9GVl1fVkyfbGs5MqVxMTD1ex9Ki-7pyASLljR9Azni-AmMwzIdhrBueNI7bQFjpSLdpx3LK5AW893IrWvp17JoW37Od5FT=s16000" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Inventory Balance Constraint</td></tr></tbody></table><br /><br /></div><span><a name='more'></a></span><div><br /><div>Here \(S_t\) is the reservoir storage level. This is just a fairly standard <b>inventory balance constraint</b>. We use this all the time in LP/MIP models. So actually <i>we can use this equation as a constraint</i>. This misunderstanding of LP modeling leads to more problematic modeling constructs. </div><div><br /></div><div><br /></div><div><h3>2. Substituting out variables</h3></div><div><br /></div><div>Instead of bounds on \(S_t\) they come up with:</div></div><div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjabuYTwScIOLj00Yp6VFdz0UNsQKCPwzBbS6XDoHMNIsJpxa-Bm43tD503bYKBcmSzjTIRS-SnzAh7GYWiNcwyd0yTuPHS3BUD3qePXe3Ss3EnnPzNwZnpiWk-VtpYeewaQWLt2tFFVGZywZtJI8zW8bqZPEcdBiVs4iWXDfggmBYtspqrvIaJd8nPAFZi" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="563" data-original-width="811" src="https://blogger.googleusercontent.com/img/a/AVvXsEjabuYTwScIOLj00Yp6VFdz0UNsQKCPwzBbS6XDoHMNIsJpxa-Bm43tD503bYKBcmSzjTIRS-SnzAh7GYWiNcwyd0yTuPHS3BUD3qePXe3Ss3EnnPzNwZnpiWk-VtpYeewaQWLt2tFFVGZywZtJI8zW8bqZPEcdBiVs4iWXDfggmBYtspqrvIaJd8nPAFZi=s16000" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Simple bounds rewritten as more complex constraints.</td></tr></tbody></table><br />This is exactly what we don't want to see: <i>duplication of expressions</i>. In large-scale modeling, substituting out variables is often a bad idea: it can destroy the sparsity of model. More importantly, it hurts the readability of the model.</div><div><br /></div><h3 style="text-align: left;">3. Variables vs Parameters</h3><div><div><br /></div><div>In the table </div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEipkXnVi6coj3OTcSJ_Jdbu9Uyjw7KyN3mazq04V1nQa_FrzE57VRP72ieSTLb5nbLgj0IjTFqcn6GqNVrrFkPzPIld77tXRK4UpHo98HSB5t7pLqQ1f-I9rOuQnzxSpfc6Nddq_HXrJgIex-9upVZ4UPnR-wTAQLveVY8CmHy1c_sVnGFyi1UfIwEL2yco" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="422" data-original-width="574" src="https://blogger.googleusercontent.com/img/a/AVvXsEipkXnVi6coj3OTcSJ_Jdbu9Uyjw7KyN3mazq04V1nQa_FrzE57VRP72ieSTLb5nbLgj0IjTFqcn6GqNVrrFkPzPIld77tXRK4UpHo98HSB5t7pLqQ1f-I9rOuQnzxSpfc6Nddq_HXrJgIex-9upVZ4UPnR-wTAQLveVY8CmHy1c_sVnGFyi1UfIwEL2yco=s16000" /></a></div><br />all quantities are referred to as variables. In modeling, we make an important distinction between variables (endogenous with values to be determined by the solver) and parameters (exogenous or data: constants during the solve). Just calling everything "variables" is wrong.</div><div><br /></div></div><h3 style="text-align: left;">4. Single period vs multi-period models</h3><div><br /></div><div><div>Note that we can solve models like this as one big model or as a model per time step. These approaches are not the same. In the full anticipatory, forward-looking model, we have foresight. In the LP per time step, we are greedy, myopic. The anticipatory model will give better solutions, but we need all data (or forecasts) at the start. In reservoir planning, we may have reasonable forecasts (weather, demand), at least for shorter-range models. Indeed, I have never seen single-period reservoir planning models. These concepts need to be fully understood before even starting with writing down the LP model.</div><div><br /></div><div>The model presented in [1] looks like:</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEh9K_Z2VuYElFtmVcl8oM5rT8f0cfXc8erwycQTq5wkdcl8m4rJvoCuEOXWWU38LhsXbcUBzVG1VfVb8LOSxb3vneAWyoo2xkB5OXROrbpq3CfB7uRDDEr2FvLYaFQqxf3zWHBajI6wKPCa61XkVe_otqYzwepO1lvseF94UyJF9bfnCj_AqqCq3rfObyae" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="311" data-original-width="497" src="https://blogger.googleusercontent.com/img/a/AVvXsEh9K_Z2VuYElFtmVcl8oM5rT8f0cfXc8erwycQTq5wkdcl8m4rJvoCuEOXWWU38LhsXbcUBzVG1VfVb8LOSxb3vneAWyoo2xkB5OXROrbpq3CfB7uRDDEr2FvLYaFQqxf3zWHBajI6wKPCa61XkVe_otqYzwepO1lvseF94UyJF9bfnCj_AqqCq3rfObyae=s16000" /></a></div><br />They don't state this explicitly, but this is a simple-minded single-period model where \(S_{t-1}\) is exogenous. Again, this is not what is used in practice. A multi-period model would have a \(\sum_t\) in the objective and \(\forall t\) in the constraints. My guess is that this model is misspecified.</div><div><br /></div><h3 style="text-align: left;">My Thoughts</h3><div><br /></div></div><div>This is just bad modeling advice.</div><div><br /></div><div>I think that one of the underlying reasons for this is that most introductory linear programming textbooks pay too much attention to algorithms and not enough to modeling. As a result, it is much easier to teach algorithms (just follow the textbook) than modeling. </div><div><br /></div><div>Another beginner's error is to assume some ordering in the calculations. Instead, we deal with <b>simultaneous equations</b>. I.e., all variables are calculated at the same time. This is a concept that can be difficult to explain to decision-makers.</div><div><br /></div><div>Sometimes, newby modelers are confusing <i>assignments</i> with <i>equations</i>. Something like \[i := i+1\] we will never encounter in an LP model: the equation \[i=i+1\] would make the model infeasible. </div><div><br /></div><div>I have tried to give some feedback in the comment section of [1], but that has been removed. The page contains some misleading information that deserves some serious editing.</div><div><br /></div><h3 style="text-align: left;">Conclusion</h3><div><br /></div><div>Modeling requires some precision. This is missing from [1]. Also, there are several obvious misstatements. </div><div><br /></div><h3 style="text-align: left;">References</h3><div><br /></div><div><ol style="text-align: left;"><li><a href="https://waterprogramming.wordpress.com/2023/10/02/an-introduction-to-linear-programming-for-reservoir-operations-part-1">https://waterprogramming.wordpress.com/2023/10/02/an-introduction-to-linear-programming-for-reservoir-operations-part-1</a></li></ol></div><div><br /></div><div><br /></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com0tag:blogger.com,1999:blog-593563533834706486.post-33469260544896837662023-09-27T21:00:00.010-04:002024-02-26T04:32:56.908-05:00Math and ChatGPT<script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style><p>Performing symbolic math steps is often related to pattern recognition. In theory, ChatGPT could be doing a good job here. I wanted to find the inverse of \[f(x) = {\mathrm{sign}}(x) \log(1+|x|)\] This function is a form of a signed logarithmic scaling. So, let's see what ChatGPT is telling us:</p><span><a name='more'></a></span><p><br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjWmgVHQnkDVtaRAE39-Dpjy8pQpkJMN4YPnZjo5Vikg5Sfsb63yx31d9KmB_H6NfuPqw46IQgWkRtEijZzdWJ0lVDDVcs0oaqfYeMC93-eIWxVeTVIM1IpRdWFa3CdNnYeM_s6-M1po2WyTATqH3VcuU_wjpaNqNSiH4XpiBv10CG73o0O8aCay32k2wOH" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="861" data-original-width="928" src="https://blogger.googleusercontent.com/img/a/AVvXsEjWmgVHQnkDVtaRAE39-Dpjy8pQpkJMN4YPnZjo5Vikg5Sfsb63yx31d9KmB_H6NfuPqw46IQgWkRtEijZzdWJ0lVDDVcs0oaqfYeMC93-eIWxVeTVIM1IpRdWFa3CdNnYeM_s6-M1po2WyTATqH3VcuU_wjpaNqNSiH4XpiBv10CG73o0O8aCay32k2wOH=s16000" /></a></div><br />The idea to split this into two branches is excellent. Strictly speaking, we should handle \(x=0\) also in one of the branches, but let's ignore that for now. More worisome, somehow, it looses the \({\mathrm{sign}}(x)\) function in step 2 (needed for the \(x\lt 0\) branch). So, let's inform ChatGPT about this:<p></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjpogawhfJ-QN_FvaItJiLjnxa0gG0eaWuQZtJdZT0M7gSyIJdaTb2-BF4Eh87o6pGrEv0WaQ8pGrqlQ7BMTrTO9SLL0XceUhRSctJeYjHS1bDo-2zR2etEzRLXz4Hdzq9nzle9kiv5RzyVikDiWo0vb7OYT0EZA-P3DXZh-ZMbEDUgaaY9v1ShVSWM5b4y" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="864" data-original-width="945" src="https://blogger.googleusercontent.com/img/a/AVvXsEjpogawhfJ-QN_FvaItJiLjnxa0gG0eaWuQZtJdZT0M7gSyIJdaTb2-BF4Eh87o6pGrEv0WaQ8pGrqlQ7BMTrTO9SLL0XceUhRSctJeYjHS1bDo-2zR2etEzRLXz4Hdzq9nzle9kiv5RzyVikDiWo0vb7OYT0EZA-P3DXZh-ZMbEDUgaaY9v1ShVSWM5b4y=s16000" /></a></div><br />It says, "Let's include the \({\mathrm{sign}}(x)\) factor," but then it does not actually do that.<p></p><p>Doing the inverse by hand yields: \[f^{-1}(x) = {\mathrm{sign}}(x)(\exp(|x|)-1)\]</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhrVMPKC7q2VnCFKRUl4OOfkz3cGphIQuvy3FZRnYHFGXjzX4Tspnre9wAGqof-eYL804bn8idNHiqztE8aVQBxpIczbc-wkMTqOZ1aOHSCkj-0WL3on1AxzWG3et62d8OCaBupQtgvuLpa0TaC9OVFh610iXmHBpg-Ag9NrtTlnlnqQxpmD4xZvjIUWoXV" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="925" data-original-width="941" src="https://blogger.googleusercontent.com/img/a/AVvXsEhrVMPKC7q2VnCFKRUl4OOfkz3cGphIQuvy3FZRnYHFGXjzX4Tspnre9wAGqof-eYL804bn8idNHiqztE8aVQBxpIczbc-wkMTqOZ1aOHSCkj-0WL3on1AxzWG3et62d8OCaBupQtgvuLpa0TaC9OVFh610iXmHBpg-Ag9NrtTlnlnqQxpmD4xZvjIUWoXV=s16000" /></a></div><br />Hmm. ChatGPT does not really understand much of my feedback. It is rather polite, but it is just ignoring what I say.<p></p><h3 style="text-align: left;">Update 1: Wolfram Alpha</h3><div><br /></div><div>Wolfram Alpha [1] is based on the same symbolic math foundations as Mathematica. I tried the command:</div><div><br /></div><div></div><blockquote><div><span style="font-family: courier;">inverse of sign(x)*log(1+|x|)</span></div><div></div></blockquote><div><br /></div><div>The response is:</div><div><br /></div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEh-wqsWvK92Y6Q76aJ-v3Vjpn6Rhr5ZaBpHYHmymkI_8z736ma-KD7EZXs63M9pePtqgVxzTSa54fC7Xqoy8t6SZjL-sQM0-0gTa0neqb1p92nDfGoK62x1Qo_o5Jwu9jBs0s1PDoy7q6F6RH4r06ciFXyOFN2SEhDd8Vw9Zr60rnXYSsMtkNdaWR6km3Uh" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="886" data-original-width="889" src="https://blogger.googleusercontent.com/img/a/AVvXsEh-wqsWvK92Y6Q76aJ-v3Vjpn6Rhr5ZaBpHYHmymkI_8z736ma-KD7EZXs63M9pePtqgVxzTSa54fC7Xqoy8t6SZjL-sQM0-0gTa0neqb1p92nDfGoK62x1Qo_o5Jwu9jBs0s1PDoy7q6F6RH4r06ciFXyOFN2SEhDd8Vw9Zr60rnXYSsMtkNdaWR6km3Uh=s16000" /></a></div><br /><br /></div><div>This does not look too good either:</div><div><ul style="text-align: left;"><li>The inverse function is incorrect </li><li>and the blue line is not the plot of \(e^x-1\). </li></ul></div><div><br /></div><div>It is noted that ChatGPT can use Wolfram Alpha [2].</div><div><br /></div><h3 style="text-align: left;">Update 2: Sage</h3><div><br /></div><div>Sage is a well-known open-source symbolic math package. An online version is available [3]. This does not seem to work either:</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEj6qqvXoa0dZy-BOqKOJPrAiRj9FJYCJsUa27upEZfj1kNrx2plkZ4Q1ZyUIOQJUWwpyB5GqlAwGRQCt2mjnEVXDeRVBZZaGCkRyIvLd285FuaA0aBXgOtt73yMjzM_5EZZ5bjc2jRQZwyhcJPdH4BQ3y-nD3mgpmPWNoSn39x5LCILUrvTgt-ZtfyG49fc" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="413" data-original-width="529" src="https://blogger.googleusercontent.com/img/a/AVvXsEj6qqvXoa0dZy-BOqKOJPrAiRj9FJYCJsUa27upEZfj1kNrx2plkZ4Q1ZyUIOQJUWwpyB5GqlAwGRQCt2mjnEVXDeRVBZZaGCkRyIvLd285FuaA0aBXgOtt73yMjzM_5EZZ5bjc2jRQZwyhcJPdH4BQ3y-nD3mgpmPWNoSn39x5LCILUrvTgt-ZtfyG49fc=s16000" /></a></div><div><br /></div><div>Sage cannot solve this. I tried doing it for the branches \(x\ge 0\) and \(g \lt 0\) separately. That worked fine. The complete function, however, seems out of reach.</div><div><br /></div><h3 style="text-align: left;">Update 3: Google Gemini</h3><div><br /></div><div>Much better:</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjDoBngNo7bNkT-JeNE4H8QC2YiclxXKc-3L3RRR_hVMVrscNdF3uexe0BqLlr7KY0-SqFiVyF_1sVuvTLusezJ85QKJU_QLuc9YKczp9aoEHDg-cKAfQCBGwWoI0eR5Sik4YXHaxyOgNBKehdHLG_RTFZHxBHjy01uFyuNaK4yyadwXxTXbbBZm7JS0jC9" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="840" data-original-width="793" src="https://blogger.googleusercontent.com/img/a/AVvXsEjDoBngNo7bNkT-JeNE4H8QC2YiclxXKc-3L3RRR_hVMVrscNdF3uexe0BqLlr7KY0-SqFiVyF_1sVuvTLusezJ85QKJU_QLuc9YKczp9aoEHDg-cKAfQCBGwWoI0eR5Sik4YXHaxyOgNBKehdHLG_RTFZHxBHjy01uFyuNaK4yyadwXxTXbbBZm7JS0jC9=s16000" /></a></div><br />Finally: this result is correct. We could simplify things a bit: 2 branches instead of 3, or even use the sign(x) function.</div><br /><h3 style="text-align: left;">Conclusion</h3></div><div><br /></div><div>A pen and a piece of paper is sometimes the most reliable tool to do math.</div><div><br /></div><h3 style="text-align: left;">References</h3><div><ol style="text-align: left;"><li><a href="https://www.wolframalpha.com/">https://www.wolframalpha.com/</a></li><li>ChatGPT Gets Its “Wolfram Superpowers”!, <a href="https://writings.stephenwolfram.com/2023/03/chatgpt-gets-its-wolfram-superpowers/">https://writings.stephenwolfram.com/2023/03/chatgpt-gets-its-wolfram-superpowers/</a></li><li><a href="https://sagecell.sagemath.org/">https://sagecell.sagemath.org/</a></li></ol></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com2tag:blogger.com,1999:blog-593563533834706486.post-57650610109757816692023-09-20T09:09:00.040-04:002023-10-08T21:26:33.600-04:00Julia vs Python<script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style>
I gave a talk to economists (i.e., not professional programmers) about a Julia project we were working on. Julia is famous for its speed. It uses LLVM [1] as back-end for its JIT (Just In Time) compilation. As seeing is believing, here is an example algorithm which is used to compare performance between different languages and tools. This example was chosen as it is small, easy to explain, and easy to program while still showing meaningful time differences.<div><br /></div><div>We have a square \([-1,+1]\times[-1,+1]\) and an inscribing circle with radius \(1\). See the dynamic figure below. Their areas are \(4\) and \(\pi\) respectively. The idea is to draw \(n\) points \[\begin{align}& x_i \sim U(-1,+1) \\ & y_i \sim U(-1,+1)\end{align}\]Let \(m\) be the number of points inside the circle, i.e. with \[x_i^2+y_i^2\lt 1\] Obviously, from the ratio of the areas, we have \[\frac{m}{n} \approx \frac{\pi}{4}\] It follows that an estimate of \(\pi\) is \[\hat{\pi}=4\frac{m}{n}\]</div><div><br /></div><div><br /></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; width: 100%;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_4hKTIIGoJdaLH3PlfZTlG-dynntXbq_izv0BHnEa7dZCNOy9S5S93UVjoUxOo2t1Trua7RaDUauOotnRB_Hrli0ziLoiGO8VtVY0zM1WRZ5Qpt_jYu1RG3LJcwwv6xss2FwiF--fTBpk0QbzgrrdUTg2uGoi2VsHKxURKw4DoRIYh3crJZEM3OE0EZb3/s1000/tmp.gif" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="500" data-original-width="1000" height="377" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_4hKTIIGoJdaLH3PlfZTlG-dynntXbq_izv0BHnEa7dZCNOy9S5S93UVjoUxOo2t1Trua7RaDUauOotnRB_Hrli0ziLoiGO8VtVY0zM1WRZ5Qpt_jYu1RG3LJcwwv6xss2FwiF--fTBpk0QbzgrrdUTg2uGoi2VsHKxURKw4DoRIYh3crJZEM3OE0EZb3/w753-h377/tmp.gif" width="753" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Simulation with n=1000</td></tr></tbody></table><div class="separator" style="clear: both; text-align: center;"><br /></div><div><span><a name='more'></a></span>Here, I look at five different implementations of this simulation, in increasing speed:</div><div><ol style="text-align: left;"><li>A straightforward implementation in <b>Python using a for loop</b>. This is very slow.</li><li>A <b>GAMS </b>version of this algorithm. Just for the heck of it.</li><li>A <b>set-driven GAMS version</b> replaces the inner loop with a sum. This version was suggested by [4].</li><li>A <b>Python </b>version that uses the <b>Numba</b> JIT compiler [2]. Numba uses the same LLVM [1] back-end as Julia. This is 10 times as fast. Numba does not support f-strings, so the print statement must be changed. This version was not in my talk. I added it for completeness. And out of curiosity.</li><li>A <b>Python </b>implementation using <b>NumPy</b> [3]. Here, we use arrays instead of explicit loops. Of course, NumPy will still use loops behind the scenes, but that is done inside a more high-performance C library implementation. This formulation gives a big performance boost. Lesson: in Python, loops are very expensive. This variant is not very close to our original version. It is, however, significantly faster than the Numba version.</li><li>This is the same intuitive implementation as in 1., but now using <b>Julia</b>. This is the fastest of all, by a large margin. The looped version is very fast and it will require some esoteric code to improve on this. [5]</li></ol></div><div>A single simulation uses 1 million points. We repeat this 10 times.</div><div><br /></div>
<table>
<tbody><tr><td><h4>1. Python loop</h4><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjNouSN916u12rHoRCBdY6TOXSb0KIoaSS5xBag4aJ0xuLIztX1s96L5PAgZqaTBji0llIfUODsgyvcTHxUX_6aVDP81BBDqRKNag4bimjFvLVjRs5W7V0o9gxgSsUGG8Ud4nDsC0S4Dl_SAtfWf7DPV1v8czQetEGA5ZpltN_HDy95QAtvuziAlwOogbny" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="602" data-original-width="603" height="528" src="https://blogger.googleusercontent.com/img/a/AVvXsEjNouSN916u12rHoRCBdY6TOXSb0KIoaSS5xBag4aJ0xuLIztX1s96L5PAgZqaTBji0llIfUODsgyvcTHxUX_6aVDP81BBDqRKNag4bimjFvLVjRs5W7V0o9gxgSsUGG8Ud4nDsC0S4Dl_SAtfWf7DPV1v8czQetEGA5ZpltN_HDy95QAtvuziAlwOogbny=w529-h528" width="529" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div></td><td>Output:<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhoyq0-maWQa2byJbLYjnIDj4sQ8Xwzn8zWdHnl5_5o6tr675xBA-hCC3sPrUbFPRW1Bj1XAokNl_fyatm6v-XHuDa9VJmR24_qAEUn3PGeAqxb6BhCqUNOSSi0X0Ue8OFDejmrwo0HeZLz8NdNkp1tvjic0TQyLoIO5Puao4wfK0Q9Dx8iNfW11SY0V2KY" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="275" data-original-width="346" height="206" src="https://blogger.googleusercontent.com/img/a/AVvXsEhoyq0-maWQa2byJbLYjnIDj4sQ8Xwzn8zWdHnl5_5o6tr675xBA-hCC3sPrUbFPRW1Bj1XAokNl_fyatm6v-XHuDa9VJmR24_qAEUn3PGeAqxb6BhCqUNOSSi0X0Ue8OFDejmrwo0HeZLz8NdNkp1tvjic0TQyLoIO5Puao4wfK0Q9Dx8iNfW11SY0V2KY=w259-h206" width="259" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><br />This is a scalar loop executed in pure Python. It is the slowest version.</td></tr>
<tr><td><h4>2. GAMS scalar loop</h4><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEiih8mg4nOiRoMZaF77o6bclHAPnFRrtUhACTr_QSTiD3uKeUUl5D0dE8fbsF8YynWgMwLT4hDn96TFdjEkoz98MeWcU8c7FkWIRl20RCOuK39aL4fKnZfIzF7L31zwW9CgVj-xKGCFvBdIXp5yWaU2dtASPxOfF7G26N8po42KDUBozkEhJGGtM0XXYMAM" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="442" data-original-width="451" height="394" src="https://blogger.googleusercontent.com/img/a/AVvXsEiih8mg4nOiRoMZaF77o6bclHAPnFRrtUhACTr_QSTiD3uKeUUl5D0dE8fbsF8YynWgMwLT4hDn96TFdjEkoz98MeWcU8c7FkWIRl20RCOuK39aL4fKnZfIzF7L31zwW9CgVj-xKGCFvBdIXp5yWaU2dtASPxOfF7G26N8po42KDUBozkEhJGGtM0XXYMAM=w404-h394" width="404" /></a></div><br /><br /><br /></td><td>Output:<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhZEBh1wgwsZsa8nGZPO2_KjO3_m-qaSyTtC7WjTRn2lMXw9xSrBTLD-rk92uvg9fgmVK9e3H49YRlN_mfizCznOgH_rvF6w2YOK8xTPMv3Hqry5x3ay1EbZUb83xWIwd__7tijDz_h0w7JD3glp6W2FUJ40hGHkLga3cNWbJfoykLNAtsVC28qzTdsIbJm" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="548" data-original-width="763" height="269" src="https://blogger.googleusercontent.com/img/a/AVvXsEhZEBh1wgwsZsa8nGZPO2_KjO3_m-qaSyTtC7WjTRn2lMXw9xSrBTLD-rk92uvg9fgmVK9e3H49YRlN_mfizCznOgH_rvF6w2YOK8xTPMv3Hqry5x3ay1EbZUb83xWIwd__7tijDz_h0w7JD3glp6W2FUJ40hGHkLga3cNWbJfoykLNAtsVC28qzTdsIbJm=w374-h269" width="374" /></a></div><br />A bit faster than the Python loop.</td></tr>
<tr><td><h4>3. Set-driven GAMS formulation</h4><div><br /></div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjFJP4fzueFJcHq5LE2THR_-DkrcUV_f5oUiJRZHVxhQAPnuwTutkouWWZCxbjyIlhKNMN5SXerbdlQNLOgXu7-FOAOOBD_d-npJLQJguiKjKBPGKhjo9i0o7UMRpBmBn2jgbhu19kl-Cc7zZOoQC6kN78k2fR1dcKADkO8yeQ4LiViMMW8xfnj582xe0pO" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="214" data-original-width="616" src="https://blogger.googleusercontent.com/img/a/AVvXsEjFJP4fzueFJcHq5LE2THR_-DkrcUV_f5oUiJRZHVxhQAPnuwTutkouWWZCxbjyIlhKNMN5SXerbdlQNLOgXu7-FOAOOBD_d-npJLQJguiKjKBPGKhjo9i0o7UMRpBmBn2jgbhu19kl-Cc7zZOoQC6kN78k2fR1dcKADkO8yeQ4LiViMMW8xfnj582xe0pO=s16000" /></a></div><br /><br /><br /></td><td>Output:<br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhpcj0QsWn8eGoLr8AIw4aHInwGxOzlthVs_nizkef1F2nz4BZDS9MIkx2lEK2N-gqgDBNtuwCxw3TyXe4s34ldh5gHw28ahEieeqW-SH-SuLnejAnS6YBovQmNQSbOPu26LVoYtvlxY8WSyOc8pJgqYrf075-SVmXrutdbt4jwHblM-CGfg4MJE0CCNk6L" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="459" data-original-width="644" height="228" src="https://blogger.googleusercontent.com/img/a/AVvXsEhpcj0QsWn8eGoLr8AIw4aHInwGxOzlthVs_nizkef1F2nz4BZDS9MIkx2lEK2N-gqgDBNtuwCxw3TyXe4s34ldh5gHw28ahEieeqW-SH-SuLnejAnS6YBovQmNQSbOPu26LVoYtvlxY8WSyOc8pJgqYrf075-SVmXrutdbt4jwHblM-CGfg4MJE0CCNk6L" width="320" /></a></div><br />This is twice as fast as the "for i" loop in the previous GAMS fragment.</td></tr>
<tr><td><h4>4. Python/Numba loop</h4><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEj_IN5jiZFxh8pvjGv_NHRLLZVCRN6iMdJfCsOlx3OJM37LC4C2OtpHwzmBRJsqWUOW8sEYBHbpO9z2eS1XLqdSN8AI1KueD_tZLb3iV4vC6G211PajZ6TSxz8s0zOyBObCEXD_DtyAlehUSsNCSUZDGfljQJzm7wuGIkZ3AYA4OKxeIe5XKX5HnTJ6IIqY" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="635" data-original-width="620" height="540" src="https://blogger.googleusercontent.com/img/a/AVvXsEj_IN5jiZFxh8pvjGv_NHRLLZVCRN6iMdJfCsOlx3OJM37LC4C2OtpHwzmBRJsqWUOW8sEYBHbpO9z2eS1XLqdSN8AI1KueD_tZLb3iV4vC6G211PajZ6TSxz8s0zOyBObCEXD_DtyAlehUSsNCSUZDGfljQJzm7wuGIkZ3AYA4OKxeIe5XKX5HnTJ6IIqY=w527-h540" width="527" /></a></div><br /><br /></td><td>Output:<br /><br /><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhY6FdjB568IkQlaix1fXy_BXARiRw37XAVmK9aCDSdPDgBAWbHGtAC4CM9qjgW-o8J_Y3fDuwLv2juH5F1gXt-wcVtztYTHXxYsvQZ8TqgJkgNPxNwBInNq6L-azzQVoBJ9wRNJQlmQvtUubvQN9z5Q9Nz9cOwX4RobXK19NGUFjQjnoBbpu-pBG92UcBr" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="276" data-original-width="360" height="204" src="https://blogger.googleusercontent.com/img/a/AVvXsEhY6FdjB568IkQlaix1fXy_BXARiRw37XAVmK9aCDSdPDgBAWbHGtAC4CM9qjgW-o8J_Y3fDuwLv2juH5F1gXt-wcVtztYTHXxYsvQZ8TqgJkgNPxNwBInNq6L-azzQVoBJ9wRNJQlmQvtUubvQN9z5Q9Nz9cOwX4RobXK19NGUFjQjnoBbpu-pBG92UcBr=w266-h204" width="266" /></a></div><br /><br /></div>Here we use the Numba JIT compiler to speed up the loop. We achieve a speed-up of about 10x. Nothing to sneeze at.</td></tr>
<tr><td><h4>5. Python/NumPy without loops</h4><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEh8Ws4a2sTfKuvY-Q1aUqFv6OtaRKAihIWfYF2noDu-BsZ2PW5YRno086FzSihvvW8xPi_l3l8ZXC0FJSJ6sXqn00fAUXnQHK-ZT0Fd2gUpxD5uSTvW9An0oMxvuNf-Nb2BiUlqJEWYP85TKZMysYWCarpTHP0lAWJ9kETO34KgIkaQyuCC-sFCkVpFmzkO" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="529" data-original-width="607" height="453" src="https://blogger.googleusercontent.com/img/a/AVvXsEh8Ws4a2sTfKuvY-Q1aUqFv6OtaRKAihIWfYF2noDu-BsZ2PW5YRno086FzSihvvW8xPi_l3l8ZXC0FJSJ6sXqn00fAUXnQHK-ZT0Fd2gUpxD5uSTvW9An0oMxvuNf-Nb2BiUlqJEWYP85TKZMysYWCarpTHP0lAWJ9kETO34KgIkaQyuCC-sFCkVpFmzkO=w520-h453" width="520" /></a></div><br /></td><td>Output:<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEh4qVuAQVe0aJ9LUCYYHYgYcpMqucjpUeJC4rfMMFof3JN4NQjdZMPk4CP2D0yaD4sm1QjJqtVcCgnA3-csn0-ruUQ8nrHUgHjbXHXzZl1skNdN57Qbk1-odJk0iI67GC0hIFBDAODZ8YOldZKC7uv1RY4_sqVmOyRyllkJLqvEnzfPxlivOSY9o9ybnWTP" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="278" data-original-width="360" height="212" src="https://blogger.googleusercontent.com/img/a/AVvXsEh4qVuAQVe0aJ9LUCYYHYgYcpMqucjpUeJC4rfMMFof3JN4NQjdZMPk4CP2D0yaD4sm1QjJqtVcCgnA3-csn0-ruUQ8nrHUgHjbXHXzZl1skNdN57Qbk1-odJk0iI67GC0hIFBDAODZ8YOldZKC7uv1RY4_sqVmOyRyllkJLqvEnzfPxlivOSY9o9ybnWTP=w275-h212" width="275" /></a></div><br /><br />Here we use NumPy arrays so we don't need loops. This is faster than the Numba example. This gives us a 25x speed-up.</td></tr>
<tr><td><h4>6. Julia loop</h4><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgeh1EGgOzfgvls-teliBCrZ1Io2IE_zKxCMJ4VYCLF89lP6f0b6TffY95_c8YakEPZ-R4gpfSQ3BFDU7sFY9JTx_0smIWxYzqMljbzDQ8u3tbCwJZRURRmwYFM1YvS2d5e33HR1X05BD-k8lAbmsDnBBVMY_s6FkObu9vc5WqNRxOWa_j2E9PPYMoKVTWj" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="716" data-original-width="570" height="650" src="https://blogger.googleusercontent.com/img/a/AVvXsEgeh1EGgOzfgvls-teliBCrZ1Io2IE_zKxCMJ4VYCLF89lP6f0b6TffY95_c8YakEPZ-R4gpfSQ3BFDU7sFY9JTx_0smIWxYzqMljbzDQ8u3tbCwJZRURRmwYFM1YvS2d5e33HR1X05BD-k8lAbmsDnBBVMY_s6FkObu9vc5WqNRxOWa_j2E9PPYMoKVTWj=w517-h650" width="517" /></a></div><br /></td><td>Output:<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjMAYSdHaNG4GIJl5p5Y290UWEInXdOs2LiPlRwltWsL4NFThy9C_EInaMeA3WBJ0FOeYHp4TX7boy-gceeZ6tTvgWvOs1ZtdUmkiKEKoyI_Ez_FyrgSQiY6Z46sykY7IHhubBW5xD1l7wSFm0GNHtO0_1nS1cXfP4enDcZFA9S1qBDaGcSg9d9WWtCFb0-" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="280" data-original-width="536" height="185" src="https://blogger.googleusercontent.com/img/a/AVvXsEjMAYSdHaNG4GIJl5p5Y290UWEInXdOs2LiPlRwltWsL4NFThy9C_EInaMeA3WBJ0FOeYHp4TX7boy-gceeZ6tTvgWvOs1ZtdUmkiKEKoyI_Ez_FyrgSQiY6Z46sykY7IHhubBW5xD1l7wSFm0GNHtO0_1nS1cXfP4enDcZFA9S1qBDaGcSg9d9WWtCFb0-=w354-h185" width="354" /></a></div><br />Note the use of \(\in\) and \(4m\). This Julia version is very fast. We recorded here a 150x speed-up compared to the first example. The main expenditure here is the random number generation.</td></tr>
</tbody></table>
<div><br /></div><div>The performance is summarized in the following table:</div><div><br /></div>
<div>
<table class="blueTable">
<thead><tr><th>Implementation</th><th>Time for 10 <br />simulations (seconds)</th><th>Approximate<br />speed-up</th></tr></thead>
<tbody><tr><td>1. Pure Python with loops</td><td>4.66</td><td></td></tr>
<tr><td>2. GAMS scalar loop</td><td>2.27</td><td>2x</td></tr>
<tr><td>3. Set-driven GAMS</td><td>1.17</td><td>4x</td></tr>
<tr><td>4. Python/Numba with loops</td><td>0.45 </td><td>10x</td></tr>
<tr><td>5. Python/NumPy without loops</td><td>0.18</td><td>25x</td></tr>
<tr><td>6. Julia with loops</td><td>0.03</td><td>150x</td></tr> </tbody>
</table></div>
<div><br /></div><div>I find these numbers to be rather astounding. </div><div><br /></div><div>It is a bit of a surprise to me that GAMS is about 2x as fast as Python, using the same loop-based algorithm. As GAMS is not a general-purpose programming language, including it here is a bit of a gimmick. When programming in Python, it is not unusual to write several different implementations: one that works and then some faster versions. It certainly is beneficial in this case. An argument for using Julia could be that our first, intuitive, implementation is already very fast.</div><div><br /></div><h3 style="text-align: left;">Conclusion</h3><div><br /></div><div>Explicit loops in Python are expensive. We have to rewrite things considerably to get decent performance. This is not the case for Julia: loops are cheap. A first, straightforward implementation in Julia performs better than our Python attempts. </div><div><br /></div><div>All versions here are serial. Sometimes, NumPy may do some parallelization under the hood.</div><div><br /></div><h3 style="text-align: left;">References</h3><div><br /></div><div><ol style="text-align: left;"><li>The <b>LLVM</b> Compiler Infrastructure, https://llvm.org/</li><li>https://numba.pydata.org/</li><li>https://numpy.org/</li><li>Thomas Rutherford, University of Wisconsin, Private Communication </li><li><a href="https://julialang.slack.com/archives/C67910KEH/p1696273686727619?thread_ts=1696266934.797769&cid=C67910KEH">https://julialang.slack.com/archives/C67910KEH/p1696273686727619?thread_ts=1696266934.797769&cid=C67910KEH</a> demonstrates some Julia code using VectorizedRNG.</li></ol></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com6tag:blogger.com,1999:blog-593563533834706486.post-48557476203028760782023-09-04T23:00:00.003-04:002023-09-24T13:53:42.501-04:00Critiquing a GAMS Model<script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style><p>It is always interesting to read GAMS models written by someone else. There are probably three things one can observe:</p><p></p><ul style="text-align: left;"><li>A nice formulation or concept that is useful to learn about.</li><li>A bad implementation: something that really should not be done that way.</li><li>A piece of code that is correct and defensible, but I would write it differently. This includes things like style, layout, formatting, etc.</li></ul><div>My way of reading GAMS code is often to start editing and make it "my code". It is a bit slower process, but that comes with its advantages: better understanding of what is going on, and often cleaner code.</div><div><br /></div><div>Here, I am looking at the model <b>sambal.gms</b> in the GAMS model library [1]. It is a very small model, but I have many thoughts about it. The complete model is reproduced in Appendix 1. Let's walk through it.</div><div><br /></div><div>The<b> matrix balancing problem </b>is to find a nearby matrix such that row- and column sums are obeyed. A relative quadratic objective is used to minimize the sum of the squared deviations between the original data (the priors) and the final matrix. Zeros in the matrix need to be maintained: they can't become nonzero. This is sometimes called sparsity preservation. Often, sign-preservation is another condition. That is not part of this model. Note that, in this model, not only the matrix is updated but also the row and column totals. </div><span><a name='more'></a></span><div><br /></div><h3 style="text-align: left;">Data</h3><div><br /></div><div>The data entry and data prep step in <b>sambal.gms</b> is: </div><div><br /></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Set </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">i</span></span><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'accounts'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> / lab, h1, h2, p1, p2 /</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Alias</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> (<span class="SpellE">i,j</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Table </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">xb</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i,j</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'original estimate'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> </span></b><b><span lang="NL" style="color: #005b00; font-family: Consolas; font-size: 10.5pt;">lab h1 h2 p1 p2</span></b><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span lang="NL" style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> lab </span></b><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> 15 3 130 80</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span lang="NL" style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> h1 </span></b><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> na</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span lang="NL" style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> </span></b><b><span style="color: #005b00; font-family: Consolas; font-size: 10.5pt;">h2 </span></b><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">na</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> p1 </span></b><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> 15 130 20</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> p2 </span></b><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> 25 40 55 </span><span style="font-family: Consolas; font-size: 10.5pt;">;<o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Parameter</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">tb(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'original totals'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> / lab </span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">220</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">, (h1,h2) </span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">na</span></span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">, p1 </span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">190</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">, p2 </span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">105 </span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">tw</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'wights for totals'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">xw</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i,j</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'weights for cells'</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">tw</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>) = 1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">xw</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i,j</span>) = 1$xb(<span class="SpellE">i,j</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">tw</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>)$(</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">mapval</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(tb(<span class="SpellE">i</span>)) = </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">mapval</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">na</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">)) = 0;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">xw</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i,j</span>)$(</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">mapval</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">xb</span>(<span class="SpellE">i,j</span>)) = </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">mapval</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">na</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">)) = 0;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">tw</span>, <span class="SpellE">xw</span>;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p></td></tr></tbody></table><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.4px; margin: 0in 0in 8pt;"><o:p> </o:p></p></div><p></p><div>The first thing to note is that the table has some special values: <b>NA</b>. I usually use capitals for this to make it stand out more. There are also some blank cells that are zero. In GAMS, sparse storage is used throughout. So the important rule to remember is "<i>zero is the same as 'does not exist'</i>". A cell with <b>NA</b> does exist (i.e., it is nonzero), but it has a special value. I assume <b>xb</b> means "<b>x</b> before".</div><div><br /></div><div>The zero values in the matrix have a special meaning. They need to be preserved, i.e., the solution values for these should also be zero.</div><p></p><div>The table also has a rim with totals. In this model, they are specified separately. I would combine them into one. I.e.:</div><div><br /></div><div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #0000b3;"><strong>Table </strong></span><span style="color: black;">xb</span><span style="color: black;">(*,*</span><span style="color: black;">) </span><span style="color: #0000da;">'original estimate'</span><span style="color: black;"></span></div><div><span style="color: #005b00;"><strong> lab h1 h2 p1 p2 total</strong></span><span style="color: black;"></span></div><div><span style="color: #005b00;"><strong> lab </strong></span><span style="color: #005078;"> 15 3 130 80 220</span><span style="color: black;"></span></div><div><span style="color: #005b00;"><strong> h1 </strong></span><span style="color: #005078;"> na na</span><span style="color: black;"></span></div><div><span style="color: #005b00;"><strong> h2 </strong></span><span style="color: #005078;"> na na</span><span style="color: black;"></span></div><div><span style="color: #005b00;"><strong> p1 </strong></span><span style="color: #005078;"> 15 130 20 190 </span><span style="color: black;"></span></div><div><span style="color: #005b00;"><strong> p2 </strong></span><span style="color: #005078;"> 25 40 55 105</span><span style="color: black;"></span></div><div><span style="color: #005b00;"><strong> total </strong></span><span style="color: #005078;">220 na na 190 105 </span><span style="color: black;"></span></div><div><span style="color: black;">;</span></div></div></div><div><br /></div><div>This conveys better the underlying problem: our matrix needs to obey some row- and column-sum constraints. It is always better to use domain checking (which is turned off by using *), so I would suggest:</div><div><br /></div><div><div style="background-color: white; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div style="color: #d4d4d4;"><span style="color: #0000b3;"><strong>Set</strong></span><span style="color: black;"></span></div><div style="color: #d4d4d4;"><span style="color: #0000b3;"><strong> </strong></span><span style="color: black;">iext </span><span style="color: #0000da;">'extended:accounts+totals'</span><span style="color: #007400;"> /</span><span style="color: #007400;"> lab</span><span style="color: #007400;">,</span><span style="color: #007400;"> h1</span><span style="color: #007400;">,</span><span style="color: #007400;"> h2</span><span style="color: #007400;">,</span><span style="color: #007400;"> p1</span><span style="color: #007400;">,</span><span style="color: #007400;"> p2</span><span style="color: #007400;">,</span><span style="color: #007400;"> total</span><span style="color: #007400;"> /</span><span style="color: black;"></span></div><div style="color: #d4d4d4;"><span style="color: #007400;"> </span><span style="color: black;">i</span><span style="color: black;">(iext</span><span style="color: black;">) </span><span style="color: #0000da;">'accounts'</span><span style="color: #007400;"> /</span><span style="color: #007400;"> lab</span><span style="color: #007400;">,</span><span style="color: #007400;"> h1</span><span style="color: #007400;">,</span><span style="color: #007400;"> h2</span><span style="color: #007400;">,</span><span style="color: #007400;"> p1</span><span style="color: #007400;">,</span><span style="color: #007400;"> p2</span><span style="color: #007400;"> /</span><span style="color: black;"></span></div><div style="color: #d4d4d4;"><span style="color: black;">;</span><span style="color: black;"></span></div><div><span style="color: #787878;"><i>
</i></span><b style="color: #0000b3;">Table </b><span style="color: black;">xb</span><span style="color: black;">(iext,iext</span><span style="color: black;">) </span><span style="color: #0000da;">'original estimate'</span></div><div style="color: #d4d4d4;"><span style="color: black;"></span></div><div style="color: #d4d4d4;"><span style="color: #005b00;"><strong> lab h1 h2 p1 p2 total</strong></span><span style="color: black;"></span></div><div style="color: #d4d4d4;"><span style="color: #005b00;"><strong> lab </strong></span><span style="color: #005078;"> 15 3 130 80 220</span><span style="color: black;"></span></div><div style="color: #d4d4d4;"><span style="color: #005b00;"><strong> h1 </strong></span><span style="color: #005078;"> na na</span><span style="color: black;"></span></div><div style="color: #d4d4d4;"><span style="color: #005b00;"><strong> h2 </strong></span><span style="color: #005078;"> na na</span><span style="color: black;"></span></div><div style="color: #d4d4d4;"><span style="color: #005b00;"><strong> p1 </strong></span><span style="color: #005078;"> 15 130 20 190 </span><span style="color: black;"></span></div><div style="color: #d4d4d4;"><span style="color: #005b00;"><strong> p2 </strong></span><span style="color: #005078;"> 25 40 55 105</span><span style="color: black;"></span></div><div style="color: #d4d4d4;"><span style="color: #005b00;"><strong> total </strong></span><span style="color: #005078;">220 na na 190 105 </span><span style="color: black;"></span></div><div style="color: #d4d4d4;"><span style="color: black;">;</span><span style="color: black;"></span></div><div style="color: #d4d4d4;"></div></div></div><div><br /></div><div>The blanks in the table (zeros) have a special meaning: zeros have to be preserved. We can fix the corresponding variables to zero, or, as is done in this model, we can skip these empty cells. Opposed to this, the <b>NA</b> values are to be included in the add-up constraints but skipped in the objective as we can't calculate a deviation from this. </div><div><br /></div><div>The typo in the explanatory text indicates we really need an IDE with spell-checking. My GAMS code often contains many comments, as I need to pass on code to other people who are not necessarily GAMS experts or even very familiar with the underlying models. So, I tend to be more verbose. Spell-checking can help there. </div><div><br /></div><div>I don't agree with how the assignments to <b>tw</b> and <b>xw</b> are written. Let me explain why.</div><div><br /></div><div>The <b>mapval</b>(x)<b> </b>function is an exotic function that gives back a numerical value corresponding to the type of x:</div><div><div><br /></div><div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #787878;"><em> 0: is not a special value</em></span><span style="color: black;"></span></div><div><span style="color: #787878;"><em> 4: is UNDF (undefined)</em></span><span style="color: black;"></span></div><div><span style="color: #787878;"><em> 5: is NA (not available)</em></span><span style="color: black;"></span></div><div><span style="color: #787878;"><em> 6: is INF ( )</em></span><span style="color: black;"></span></div><div><span style="color: #787878;"><em> 7: is -INF ( )</em></span><span style="color: black;"></span></div><div><span style="color: #787878;"><em> 8: is EPS</em></span><span style="color: black;"></span></div><div><span style="color: #787878;"><em> >8: is an acronym</em></span><span style="color: black;"></span></div><div></div></div><div><br /></div></div><div>I don't think I have ever used this function. There is almost never a good reason to use it in this way, as we can say:</div><div><br /></div><div><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">tw</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>)$(</span><span style="font-family: Consolas; font-size: 10.5pt;">tb(<span class="SpellE">i</span><span class="GramE">)=</span></span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">na</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">) = 0;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">xw</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>)$(</span><span style="font-family: Consolas; font-size: 10.5pt;"><span class="SpellE">xb</span>(<span class="SpellE">i,j</span>)=</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">na</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">) = 0;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p></div><div><span style="font-family: Consolas; font-size: 10.5pt;"><br /></span></div><div>which is both shorter and clearer. </div><div><br /></div><div></div><blockquote><div>There are two audiences when you write code: one is the machine (in this case the GAMS compiler) and the other, more importantly, are human beings. It is very important to write code that is as readable as possible. In the fragment above this is obviously violated by obscuring the meaning of these assignments. </div><div></div></blockquote><div><br /></div><div>The <b>weights </b>here are 0 or 1. They are modeled by a <b>parameter</b>. For boolean values, an arguably better representation is a <b>set</b>. A set element can only have two values (YES or NO), while a parameter can have any value. So I would probably write something like: </div><div><br /></div><div><div style="color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;"><span style="color: #0000b3;"><strong>set </strong></span><span style="color: black;"></span></div><div style="color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;"><span style="color: #0000b3;"><strong> </strong></span><span style="color: black;">ii</span><span style="color: black;">(i</span><span style="color: black;">) </span><span style="color: #0000da;">'indicates if t(i) is included in the obj'</span><span style="color: black;"></span></div><div style="color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;"><span style="color: #0000da;"> </span><span style="color: black;">ij</span><span style="color: black;">(i,j</span><span style="color: black;">) </span><span style="color: #0000da;">'indicates if x(i,j) is included in the obj'</span><span style="color: black;"></span></div><div style="color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;"><span style="color: black;">;</span></div><div style="color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;"><br /></div><div style="color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;"><span style="color: black;">ii(i) = tb(i)<></span><span style="color: #0000b3;"><strong>na</strong></span><span style="color: black;">;</span><span style="color: black;"></span></div><div style="color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;"><span style="color: black;">ij(i,j) = xb(i,j)<>0 </span><span style="color: #0000b3;"><strong>and</strong></span><span style="color: black;"> xb(i,j)<></span><span style="color: #0000b3;"><strong>na</strong></span><span style="color: black;">;</span><span style="color: black;"></span></div><div style="color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;"><span style="color: #0000b3;"><strong>display</strong></span><span style="color: black;"> ii, ij</span><span style="color: black;">;</span></div><div style="color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;"><span style="color: black;"></span></div></div><div><br /></div><div></div><blockquote><div>Nerdy detail: the second assignment cannot be written as:</div><div><br /></div><div><div style="color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;"><span style="color: black;">ij(i,j) = xb(i,j) </span><span style="color: #0000b3;"><strong>and</strong></span><span style="color: black;"> xb(i,j)<></span><span style="color: #0000b3;"><strong>na</strong></span><span style="color: black;">;</span><span style="color: black;"></span></div></div><div><span style="color: black;"><br /></span></div><div>as the rhs resolves for <b>na</b> values to <strong style="color: #0000b3; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;">na</strong><span style="color: black; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;"> </span><span style="color: #0000b3; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;"><strong>and</strong></span><span style="color: black; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;"> 0</span> which is <b>na</b>.</div><div></div></blockquote><div><br /></div><h3 style="text-align: left;">Model equations</h3><div><br /></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Variable</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">x(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'estimated cells'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">t(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'estimated totals'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">dev </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'deviations<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Equation</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">rbal</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'row balance'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">cbal</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(j) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'column balance'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">devsqr</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'</span></span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">definition of square deviations'</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">rbal</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">i</span></span><span style="font-family: Consolas; font-size: 10.5pt;">).. t(<span class="SpellE">i</span>) =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">j$xb</span>(<span class="SpellE"><span class="GramE">i,j</span></span>), x(<span class="SpellE">i,j</span>));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">cbal</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span style="font-family: Consolas; font-size: 10.5pt;">j).. t(j) =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i$xb</span>(<span class="SpellE"><span class="GramE">i,j</span></span>), x(<span class="SpellE">i,j</span>));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">devsqr</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">..</span></span><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">dev =</span>e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">((<span class="SpellE">i,j</span>)$<span class="SpellE">xw</span>(<span class="SpellE">i,j</span>), <span class="SpellE">xw</span>(<span class="SpellE">i,j</span>)*</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sqr</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">xb</span>(<span class="SpellE">i,j</span>) - x(<span class="SpellE">i,j</span>))/<span class="SpellE">xb</span>(<span class="SpellE">i,j</span>))</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;"> + </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i$tw</span>(<span class="SpellE">i</span>), <span class="SpellE">tw</span>(<span class="SpellE">i</span>)*</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sqr</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(tb(<span class="SpellE">i</span>) - t(<span class="SpellE">i</span>))/tb(<span class="SpellE">i</span>));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p></td></tr></tbody></table></div><div><br /></div><div><br /></div><div>The variables are (by default) <b>free variables</b>. That means <b>x</b> and <b>t</b> can become negative. Many matrix-balancing exercises want positive only results or at least sign preservation w.r.t to the priors. For SAMs (Social Accounting Matrices) we don't want to introduce negative values, so I would make <b>x</b> and <b>t</b> positive variables.</div><div><br /></div><div>The constraints <b>rbal</b> and <b>cbal</b> can be marginally simplified by using an extra set:</div><div><br /></div><div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #0000b3;"><strong>set </strong></span><span style="color: black;">nz</span><span style="color: black;">(i,j</span><span style="color: black;">) </span><span style="color: #0000da;">'(i,j) is nonzero: include in constraints'</span><span style="color: black;">;</span><span style="color: black;"></span></div><div><span style="color: black;">nz(i,j) = xb(i,j)</span><span style="color: black;">;</span><span style="color: black;"></span></div><div><br /></div><div><span style="color: black;">rbal(i)</span><span style="color: black;">..</span><span style="color: black;"> t(i) =e= </span><span style="color: #0000b3;"><strong>sum</strong></span><span style="color: black;">(nz(i,j), x(i,j))</span><span style="color: black;">;</span><span style="color: black;"></span></div><div><span style="color: black;">cbal(j)</span><span style="color: black;">..</span><span style="color: black;"> t(j) =e= </span><span style="color: #0000b3;"><strong>sum</strong></span><span style="color: black;">(nz(i,j), x(i,j))</span><span style="color: black;">;</span><span style="color: black;"></span></div><div></div></div></div><div><br /></div><div>I am a big fan of making equations simpler by precalculating sets. Arguably, the gain is here too small to be worthwhile.</div><div><br /></div><div>The equation <b>devsqr </b>is much more problematic. The summation <b style="font-family: Calibri, sans-serif; font-size: 14.6667px;"><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">((<span class="SpellE">i,j</span>)$<span style="background-color: #ffe599;"><span class="SpellE">xw</span>(<span class="SpellE">i,j</span>)</span>, <span style="background-color: #ffe599;"><span class="SpellE">xw</span>(<span class="SpellE">i,j</span>)</span>*</span><span class="SpellE" face="Calibri, sans-serif" style="font-size: 14.6667px;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sqr</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(.)/.)</span> has the weights <b>xw</b> duplicated: both as filter on the summation and also as a factor in the summand. The dollar condition says: if the weight exists (i.e. is nonzero) add the summand. Similarly for the second sum: <b style="font-family: Calibri, sans-serif; font-size: 14.6667px;"><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i$<span style="background-color: #ffe599;">tw</span></span><span style="background-color: #ffe599;">(<span class="SpellE">i</span>)</span>, <span style="background-color: #ffe599;"><span class="SpellE">tw</span>(<span class="SpellE">i</span>)</span>*</span><span class="SpellE" face="Calibri, sans-serif" style="font-size: 14.6667px;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sqr</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(.)/.).</span> This duplication is not needed. We can simplify things by dropping either the dollar conditions or the factors. Remember that the weights are 0 or 1. So we can write:</div><div><br /></div><div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;">devsqr</span><span style="color: black;">..</span><span style="color: black;"> dev =e= </span><span style="color: #0000b3;"><strong>sum</strong></span><span style="color: black;">((i,j), xw(i,j)*</span><span style="color: #0000b3;"><strong>sqr</strong></span><span style="color: black;">(xb(i,j) - x(i,j))/xb(i,j))</span><span style="color: black;"></span></div><div><span style="color: black;"> + </span><span style="color: #0000b3;"><strong>sum</strong></span><span style="color: black;">(i, tw(i)*</span><span style="color: #0000b3;"><strong>sqr</strong></span><span style="color: black;">(tb(i) - t(i))/tb(i))</span><span style="color: black;">;</span><span style="color: black;"></span></div><div></div></div></div><div><br /></div><div>We can also do it the other way around. Using our new sets <span style="font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;">ii</span> and <span style="font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;">ij </span>and dropping the weight parameters, we can write:</div><div><br /></div><div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: black;">devsqr</span><span style="color: black;">..</span><span style="color: black;"> dev =e= </span><span style="color: #0000b3;"><strong>sum</strong></span><span style="color: black;">(ij, </span><span style="color: #0000b3;"><strong>sqr</strong></span><span style="color: black;">(xb(ij) - x(ij))/xb(ij))</span><span style="color: black;"></span></div><div><span style="color: black;"> + </span><span style="color: #0000b3;"><strong>sum</strong></span><span style="color: black;">(ii, </span><span style="color: #0000b3;"><strong>sqr</strong></span><span style="color: black;">(tb(ii) - t(ii))/tb(ii))</span><span style="color: black;">;</span><span style="color: black;"></span></div><div></div></div></div><div><br /></div><div>Note that this functional form assumes that the priors <b>xb</b> and <b>tb</b> are positive. We would be suddenly maximizing if they are negative. This can be repaired by replacing \[\min \sum_{i,j|\color{darkblue}{\mathit{xb}}_{i,j}>0} \frac{\left(\color{darkred}x_{i,j}-\color{darkblue}{\mathit{xb}}_{i,j}\right)^2}{\color{darkblue}{\mathit{xb}}_{i,j}}\] by [2]: \[\min \sum_{i,j|\color{darkblue}{\mathit{xb}}_{i,j}\ne 0} \frac{\left(\color{darkred}x_{i,j}-\color{darkblue}{\mathit{xb}}_{i,j}\right)^2}{| \color{darkblue}{\mathit{xb}}_{i,j} |}\] </div><div>I often use a slightly different objective:\[\min \sum_{i,j|\color{darkblue}{\mathit{xb}}\ne 0} \left(\frac{\color{darkred}x_{i,j}-\color{darkblue}{\mathit{xb}}_{i,j}}{\color{darkblue}{\mathit{xb}}_{i,j}}\right)^2=\sum_{i,j|xb_{i,j}\ne 0} \left(\frac{\color{darkred}x_{i,j}}{\color{darkblue}{\mathit{xb}}_{i,j}}-1\right)^2\] This works correctly if there are negative entries. Note that SAMs (Social Accounting Matrices) usually have non-negative entries.</div><div><br /></div><div> </div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Model </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">bal</span></span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> / all <span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">x.l</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) = <span class="SpellE">xb</span>(<span class="SpellE">i,j</span>)$<span class="SpellE">xw</span>(<span class="SpellE">i,j</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">t.l</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>) = tb(<span class="SpellE">i</span>)$<span class="SpellE">tw</span>(<span class="SpellE">i</span><span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">solve</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">bal</span> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">using</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">nlp</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> dev;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p></td></tr></tbody></table><div><span face="Calibri, sans-serif" style="font-size: 11pt;"> </span> </div></div><div>I can write the initial value assignments a bit more succinctly:</div><div><br /></div><div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #787878;"><em>* initial values</em></span><span style="color: black;"></span></div><div><span style="color: black;">x.l(ij) = xb(ij)</span><span style="color: black;">;</span><span style="color: black;"></span></div><div><span style="color: black;">t.l(ii) = tb(ii)</span><span style="color: black;">;</span><span style="color: black;"></span></div><div></div></div></div><div><br /></div><div>Finally, it may be better to use a quadratic model type QCP (Quadratically Constrained Programming) instead of a general-purpose NLP. That will allow us to quadratic solvers like Cplex. The initial values are only useful for general-purpose NLP solvers (they will use them). Quadratic solvers typically don't benefit that much from initial values.</div><div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><br /></div><div><span style="color: #0000b3;"><strong>solve</strong></span><span style="color: black;"> bal </span><span style="color: #0000b3;"><strong>using</strong></span><span style="color: black;"> </span><span style="color: #0000b3;"><strong>qcp</strong></span><span style="color: black;"> </span><span style="color: #0000b3;"><strong>minimizing</strong></span><span style="color: black;"> dev</span><span style="color: black;">;</span></div><div><br /></div></div></div><div style="text-align: left;">This is the end of the model. I have talked a lot about this model. Here, you see that models from the GAMS model library do not always follow best practices, and editing an existing model is a good way to walk your way through. Obviously, many edits can be a matter of taste, but here, I also made more substantial changes, and provided some rationale for that.</div><div style="text-align: left;"><br /></div><h3 style="text-align: left;">Conclusions</h3><div style="text-align: left;"><br /></div><div style="text-align: left;"><b>sambal.gms</b> is a small model in the GAMS model library. Still, there are lots of things we can say about it. Obviously, some are more about taste and personal preferences, but some other concerns can be backed up with solid arguments.</div><div style="text-align: left;"><br /></div><h3 style="text-align: left;">References</h3><div><ol style="text-align: left;"><li>sambal.gms : Social Accounting Matrix Balancing Problem, <a href="https://www.gams.com/latest/gamslib_ml/libhtml/gamslib_sambal.html">https://www.gams.com/latest/gamslib_ml/libhtml/gamslib_sambal.html</a></li><li>Zenios, S.A., Drud, A. and Mulvey, J.M. (1989), Balancing large social accounting matrices with nonlinear network programming. Networks, 19: 569-585. </li></ol></div><div><br /></div><h3 style="text-align: left;">Appendix A: original sambal.gms</h3><div></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$title</span><i><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> Social Accounting Matrix Balancing Problem (<span class="GramE">SAMBAL,SEQ</span>=77)</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$<span class="SpellE">onText</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">A Social Accounting Matrix captures all the circular flows in an</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">economy and is called balanced if the row total equal the <span class="GramE">column</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">totals. A sample problem illustrates the use of Nonlinear Programming</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">to balance such matrices.</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">Zenios</span></i></span><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">, S A, Drud, A S, and Mulvey, J, Balancing some large <span class="GramE">Social</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">Accounting Matrices with Nonlinear Programming. Tech. rep.,</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">Department of Civil Engineering, Princeton University, 1986.</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">Keywords: nonlinear programming, social accounting matrix, statistics</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$<span class="SpellE">offText</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Set </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">i</span></span><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'accounts'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> / lab, h1, h2, p1, p2 <span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Alias</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> (<span class="SpellE"><span class="GramE">i,j</span></span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Table </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">xb</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'original estimate'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> </span></b><span class="GramE"><b><span lang="NL" style="color: #005b00; font-family: Consolas; font-size: 10.5pt;">lab h</span></b></span><b><span lang="NL" style="color: #005b00; font-family: Consolas; font-size: 10.5pt;">1 h2 p1 p2</span></b><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span lang="NL" style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">lab</span> </span></b><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> 15 3 130 80</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span lang="NL" style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">h</span>1 </span></b><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> na</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span lang="NL" style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> </span></b><b><span style="color: #005b00; font-family: Consolas; font-size: 10.5pt;">h2 </span></b><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">na</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> p1 </span></b><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">15 130</span> 20</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> p2 </span></b><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> 25 40 55 <span class="GramE"> <span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Parameter</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">tb(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'original totals'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> / lab </span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">220</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">, (h<span class="GramE">1,h</span>2) </span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">na</span></span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">, p1 </span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">190</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">, p2 </span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">105 </span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">tw</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'wights for totals'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">xw</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'weights for cells'</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">tw</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>) = <span class="GramE">1;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">xw</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) = 1$xb(<span class="SpellE">i,j</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">tw</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>)$(</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">mapval</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(tb(<span class="SpellE">i</span><span class="GramE">)) </span> = </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">mapval</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">na</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">)) = 0;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">xw</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>)$(</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">mapval</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">xb</span>(<span class="SpellE">i,j</span>)) = </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">mapval</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">na</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">)) = 0;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">tw</span>, <span class="SpellE"><span class="GramE">xw</span></span><span class="GramE">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Variable</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">x(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'estimated cells'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">t(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'estimated totals'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">dev </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'deviations<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Equation</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">rbal</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'row balance'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">cbal</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(j) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'column balance'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">devsqr</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'</span></span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">definition of square deviations'</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">rbal</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">i</span></span><span style="font-family: Consolas; font-size: 10.5pt;">).. t(<span class="SpellE">i</span>) =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">j$xb</span>(<span class="SpellE"><span class="GramE">i,j</span></span>), x(<span class="SpellE">i,j</span>));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">cbal</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span style="font-family: Consolas; font-size: 10.5pt;">j).. t(j) =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i$xb</span>(<span class="SpellE"><span class="GramE">i,j</span></span>), x(<span class="SpellE">i,j</span>));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">devsqr</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">..</span></span><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">dev =</span>e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">((<span class="SpellE">i,j</span>)$<span class="SpellE">xw</span>(<span class="SpellE">i,j</span>), <span class="SpellE">xw</span>(<span class="SpellE">i,j</span>)*</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sqr</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">xb</span>(<span class="SpellE">i,j</span>) - x(<span class="SpellE">i,j</span>))/<span class="SpellE">xb</span>(<span class="SpellE">i,j</span>))</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;"> + </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i$tw</span>(<span class="SpellE">i</span>), <span class="SpellE">tw</span>(<span class="SpellE">i</span>)*</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sqr</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(tb(<span class="SpellE">i</span>) - t(<span class="SpellE">i</span>))/tb(<span class="SpellE">i</span>)<span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Model </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">bal</span></span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> / all <span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">x.l</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) = <span class="SpellE">xb</span>(<span class="SpellE">i,j</span>)$<span class="SpellE">xw</span>(<span class="SpellE">i,j</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">t.l</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>) = tb(<span class="SpellE">i</span>)$<span class="SpellE">tw</span>(<span class="SpellE">i</span><span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">solve</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">bal</span> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">using</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">nlp</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> dev;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p></td></tr></tbody></table><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.4px; margin: 0in 0in 8pt;"><br /></p><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.4px; margin: 0in 0in 8pt;"> </p><h3>Appendix B: proposed model</h3></div><div><br /></div><div><br /></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$<span class="SpellE">onText</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> Matrix Balancing Problem</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> Find a nearby matrix such that row and column totals are correct.</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> Additional condition: preserve zeros, positive values.</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> Slightly different <span class="SpellE">relative</span> quadratic objective</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$<span class="SpellE">offText</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">data</span> entry</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Sets</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">iext</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'</span></span><span class="SpellE"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">accounts+totals</span></span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> / lab, h1, h2, p1, p2, total /</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">i</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">iext</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'accounts'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> / lab, h1, h2, p1, p2 / </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Alias</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> (<span class="SpellE"><span class="GramE">iext,jext</span></span>),(<span class="SpellE">i,j</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Table </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">xb</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">iext,jext</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'original estimate'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">lab h</span>1 h2 p1 p2 total</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> </span></b><span class="GramE"><b><span lang="NL" style="color: #005b00; font-family: Consolas; font-size: 10.5pt;">lab</span></b></span><b><span lang="NL" style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> </span></b><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> 15 3 130 80 220</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span lang="NL" style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">h</span>1 </span></b><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> na <span class="SpellE">na</span></span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span lang="NL" style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">h</span>2 </span></b><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> na <span class="SpellE">na</span></span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span lang="NL" style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">p</span>1 </span></b><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> 15 130 20 190</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span lang="NL" style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">p</span>2 </span></b><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> 25 40 55 105</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span lang="NL" style="color: #005b00; font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE"><span class="GramE">total</span></span></span></b><span lang="NL" style="color: #005078; font-family: Consolas; font-size: 10.5pt;"> 220 na <span class="SpellE">na</span> 190 105 </span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">totals</span> should be symmetric</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">abort</span></b><span style="font-family: Consolas; font-size: 10.5pt;">$sum</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>$(<span class="SpellE">xb</span>(<span class="SpellE">i</span>,"total<span class="GramE">")<</span>><span class="SpellE">xb</span>("total",<span class="SpellE">i</span>)),1) "totals in XB not symmetric";</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">derived</span> data</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Parameter </span></b><span style="font-family: Consolas; font-size: 10.5pt;">tb(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'totals<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">tb(<span class="SpellE">i</span>) = <span class="SpellE">xb</span>(<span class="SpellE">i</span>,</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">'total'</span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Sets</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">ii(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'indicates if <span class="SpellE">i</span> is included in <span class="GramE">obj</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">ij</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'indicates if (<span class="SpellE">i,j</span>) is included in obj'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">nz</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'(<span class="SpellE">i,j</span>) is nonzero: include in constraints'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">ii(<span class="SpellE">i</span>) = tb(<span class="SpellE">i</span>)<></span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">na</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">ij</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) = <span class="SpellE">xb</span>(<span class="SpellE">i,j</span>)<>0 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">and</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">xb</span>(<span class="SpellE">i,j</span>)<></span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">na</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">nz</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) = <span class="SpellE">xb</span>(<span class="SpellE">i,j</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> ii, <span class="SpellE">ij</span>, <span class="SpellE"><span class="GramE">nz</span></span><span class="GramE">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">assumption</span>: non-negative values</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">abort</span></b><span style="font-family: Consolas; font-size: 10.5pt;">$sum</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">ij</span>$(<span class="SpellE">xb</span>(<span class="SpellE">ij</span>)<0),1) "negative values in XB<span class="GramE">";</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">abort</span></b><span style="font-family: Consolas; font-size: 10.5pt;">$sum</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(ii$(tb(ii)<0),1) "negative values in TB<span class="GramE">";</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">model</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Positive variable</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">x(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'estimated cells'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">t(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'estimated totals<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Variable</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">dev </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'deviations<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Equation</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">rbal</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'row balance'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">cbal</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(j) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'column balance'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">devsqr</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'</span></span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">definition of squared deviations'</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">rbal</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">i</span></span><span style="font-family: Consolas; font-size: 10.5pt;">).. t(<span class="SpellE">i</span>) =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">nz</span>(<span class="SpellE"><span class="GramE">i,j</span></span>), x(<span class="SpellE">i,j</span>));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">cbal</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span style="font-family: Consolas; font-size: 10.5pt;">j).. t(j) =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">nz</span>(<span class="SpellE"><span class="GramE">i,j</span></span>), x(<span class="SpellE">i,j</span>));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">this</span> is a little bit different from the original model</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* I tend to use this form</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">devsqr</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">..</span></span><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">dev =</span>e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">ij</span>, </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sqr</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(x(<span class="SpellE">ij</span>)/<span class="SpellE">xb</span>(<span class="SpellE">ij</span>)-1))</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;"> + </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span style="font-family: Consolas; font-size: 10.5pt;">ii, </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sqr</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(t(ii)/tb(ii)-1));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Model </span></b><span style="font-family: Consolas; font-size: 10.5pt;">sambal</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /all<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">solve</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">initial</span> values</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">x.l</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">ij</span>) = <span class="SpellE">xb</span>(<span class="SpellE">ij</span><span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">t.l</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(ii) = tb(ii<span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">solve</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> sambal </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">using</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">qcp</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">dev;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">reporting</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">parameter </span></b><span style="font-family: Consolas; font-size: 10.5pt;">sol(<span class="SpellE"><span class="GramE">iext,jext</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'final estimate'</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">sol(<span class="SpellE"><span class="GramE">i,j</span></span>) = <span class="SpellE">x.l</span>(<span class="SpellE">i,j</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">sol(<span class="SpellE">i</span>,</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">'total'</span><span style="font-family: Consolas; font-size: 10.5pt;">) = <span class="SpellE">t.l</span>(<span class="SpellE">i</span><span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">sol(</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">'total<span class="GramE">'<span style="color: black;">,<span class="SpellE">i</span></span></span></span><span style="font-family: Consolas; font-size: 10.5pt;">) = <span class="SpellE">t.l</span>(<span class="SpellE">i</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE"><span class="GramE">xb,sol</span></span>;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p></td></tr></tbody></table><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.4px; margin: 0in 0in 8pt;"><o:p> </o:p></p></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com0tag:blogger.com,1999:blog-593563533834706486.post-72556869276448887782023-08-29T18:51:00.011-04:002023-09-08T04:34:14.014-04:00Three-level Matrix Balancing <script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style>
<h3 style="text-align: left;">Matrix balancing: introduction</h3><p>Matrix Balancing Models are often used in economic modeling exercises: they create consistent data sets from data originating from different, conflicting data sources. A standard example is updating a matrix subject to given row and column sums. An example can look like:</p><p></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhXLWAuaMSI69VuldhgMqVcWpKPfUR3L0OqoHz0xjZ1oU_M5FEYF7hS2yZc6j8XhC1IOSyrv9i0auiNdXTL7D2lAjv7mb0IoXfGoweTQQT9M8hVTf5SRw0FriPQziRgCyThqoh6DP9WFXgI26UzeD6XtIMphyhVbgzPd_nnNkWHQBKEq8vV5PcozgK3l94s" style="margin-left: auto; margin-right: auto;"><img data-original-height="240" data-original-width="426" src="https://blogger.googleusercontent.com/img/a/AVvXsEhXLWAuaMSI69VuldhgMqVcWpKPfUR3L0OqoHz0xjZ1oU_M5FEYF7hS2yZc6j8XhC1IOSyrv9i0auiNdXTL7D2lAjv7mb0IoXfGoweTQQT9M8hVTf5SRw0FriPQziRgCyThqoh6DP9WFXgI26UzeD6XtIMphyhVbgzPd_nnNkWHQBKEq8vV5PcozgK3l94s=s16000" title="Update orange cells subject to row and column sums" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Update orange cells subject to row/column sums</td></tr></tbody></table><br /><br /><p></p><p>The empty cells are zero, and they should remain zero. In other words, we need to <b>preserve sparsity</b>. Often, we have non-negativity restrictions on the values. The mathematical model can look like this:</p><span><a name='more'></a></span><p><br /></p>
<table class="blueTable">
<thead><tr><th>Matrix Balancing Problem</th></tr></thead>
<tbody><tr><td>\[\begin{align}\min_{\color{darkred}A}\>&{\bf{dist}}(\color{darkred}A,\color{darkblue}A^0)\\ & \sum_i \color{darkred}A_{i,j} = \color{darkblue}c_j && \forall j\\ & \sum_j \color{darkred}A_{i,j} = \color{darkblue}r_i && \forall i \\&\color{darkred}A_{i,j}=0 &&\forall i,j|\color{darkblue}A^0_{i,j}=0\\ &\color{darkred}A_{i,j}\ge 0 \end{align} \]</td></tr></tbody>
</table><br /><br /><div>In this model, we have high confidence in the data for \(\color{darkblue}c_j\) and \(\color{darkblue}r_i\), but less confidence in \(\color{darkblue}A^0_{i,j}\). The exogenous values \(\color{darkblue}A^0\) are sometimes called <b>priors</b>. Some popular functional forms for the objective are:</div><div><br /></div>
<ul style="text-align: left;"><li><b>Cross-entropy:<br /></b> \(\displaystyle{\min \sum_{i,j} \color{darkred}A_{i,j} \ln \frac{\color{darkred}A_{i,j}}{\color{darkblue}A^0_{i,j}}}\),</li><li><b>Quadratic:<br /></b> \(\displaystyle{\min \sum_{i,j} \left(\color{darkred}A_{i,j}-\color{darkblue}A^0_{i,j}\right)^2}\),</li><li><b>Relative Quadratic</b>: <br /> \(\displaystyle{\min \sum_{i,j} \left(\frac{\color{darkred}A_{i,j}}{\color{darkblue}A^0_{i,j}}-1\right)^2}\)</li></ul><div><br /></div><h3 style="text-align: left;">Spatial data</h3><div><br /></div><div>In our application, we deal with spatial data. Basically, I am talking about acres planted for a given crop (a bit simplified; we make further distinctions such as irrigation regime). The regions we are talking about are HUCs: <b>Hydrologic Unit Codes</b>. This is a regional structure from USGS (United States Geological Survey). We have 6-digit, 4-digit and 2-digit levels. Huc-6 regions are the most disaggregated. </div><div><br /></div><div><blockquote>Huc-2 codes can be just 1 digit if the leading 0 is dropped. This depends a bit on the representation: as string or as integer. Integers lose leading zeros. These little details can cause problems when dealing with actual data sets. E.g. the huc-2 codes can look like:</blockquote><blockquote><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEh4zO-HdRPBhJyNDPaf1xFGOYJrZNPv4nbd4R8D956f_V0JPrhd-yQ3qiUNhemwL-A7Cgo0luXn0zVcxd7dAeDXb2UY5wYntvsiSYjgtmmRXlN5nFNNlFhx_WbWpgqnXuDDFXKjVVEjT1w4Vg0QWj1BOaKMWXWMhAiNkcN6QGA2s2K9e37ztBVGoncdGLL-" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="125" data-original-width="612" height="65" src="https://blogger.googleusercontent.com/img/a/AVvXsEh4zO-HdRPBhJyNDPaf1xFGOYJrZNPv4nbd4R8D956f_V0JPrhd-yQ3qiUNhemwL-A7Cgo0luXn0zVcxd7dAeDXb2UY5wYntvsiSYjgtmmRXlN5nFNNlFhx_WbWpgqnXuDDFXKjVVEjT1w4Vg0QWj1BOaKMWXWMhAiNkcN6QGA2s2K9e37ztBVGoncdGLL-=w320-h65" width="320" /></a></div>or<br /><p></p></blockquote><blockquote><p></p><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjOO-8V_Ssp73VpvBEUuf6WxGleaLvlHt_o95_D1BTD-md96dwr5ZleYohlAz08EeU49bnsdvgnjYUW2k3JuUMeonnmbTXH5E8UbpKlHaWtPycABicbrPhHrShfH2mdHj-ffY6VyYwvSWFkkauM01sKqfIBILuyG-Q17eebS3l96gNjZNvBMTLUFU_kHG04" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="129" data-original-width="721" height="57" src="https://blogger.googleusercontent.com/img/a/AVvXsEjOO-8V_Ssp73VpvBEUuf6WxGleaLvlHt_o95_D1BTD-md96dwr5ZleYohlAz08EeU49bnsdvgnjYUW2k3JuUMeonnmbTXH5E8UbpKlHaWtPycABicbrPhHrShfH2mdHj-ffY6VyYwvSWFkkauM01sKqfIBILuyG-Q17eebS3l96gNjZNvBMTLUFU_kHG04=w320-h57" width="320" /></a></div><br /></div>It is good to define once and for all how they should look like. <br /> <p></p></blockquote><p>The huc-6 regions are embedded in a huc-4 region, which is again part of a huc-2 region. This forms a hierarchical structure. At the top, we have national data. Often, the national data is considered the bible: we trust those numbers. One reason is that those national numbers are well-known: agricultural economists are very familiar with these statistics.</p><p>A beautiful, old-fashioned, retro-style map [1] is:</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgOssDEQJiy-y4AxJnmgwVd1DrQx4Uc7749kReg_tpSy3gOp1UuC-RjcM_e5eIuNbOhUKSaoRdXDfUE7Ocjq0cv0ua_e4OcadAW1-B8JF7Hd87I0EOMjt5yNC-pcYwTxsB0udF0C4sqnw8jwNE1UDytP0lfTzSThKGj2eePUCYFt6ZgNROI5Cxn6Aa1fGrf" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="1090" data-original-width="1619" height="430" src="https://blogger.googleusercontent.com/img/a/AVvXsEgOssDEQJiy-y4AxJnmgwVd1DrQx4Uc7749kReg_tpSy3gOp1UuC-RjcM_e5eIuNbOhUKSaoRdXDfUE7Ocjq0cv0ua_e4OcadAW1-B8JF7Hd87I0EOMjt5yNC-pcYwTxsB0udF0C4sqnw8jwNE1UDytP0lfTzSThKGj2eePUCYFt6ZgNROI5Cxn6Aa1fGrf=w640-h430" width="640" /></a></div><br />A more modern, d3-based [2] interactive choropleth map can look like:</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjbGnjMcI9NjymYPFeoOpsfiTexs-1D0fXL6uO-viovUeFbWbacSa786-3bVD-aFO3s263tg2uJLC7xjk8bVbc_3DS8JeLcDrAl-xT4tbtVu9_4pZfHhsuU_xdfKNERLFCs0152I80XD2kQS70coYddyO4UB7WsdH_gGklvL1VZswva3Yxg1XbrfWjWHKSU" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="807" data-original-width="1098" height="470" src="https://blogger.googleusercontent.com/img/a/AVvXsEjbGnjMcI9NjymYPFeoOpsfiTexs-1D0fXL6uO-viovUeFbWbacSa786-3bVD-aFO3s263tg2uJLC7xjk8bVbc_3DS8JeLcDrAl-xT4tbtVu9_4pZfHhsuU_xdfKNERLFCs0152I80XD2kQS70coYddyO4UB7WsdH_gGklvL1VZswva3Yxg1XbrfWjWHKSU=w640-h470" width="640" /></a></div>This mapping tool was designed to be called directly from GAMS. The square-root color scale is used to make all these small regions more distinct. </div><div><br /></div><div><br /></div><div>Here is a small example of huc 2, huc 4, and huc 6 codes:<p></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgMVzBG7aGJSLni6lmmVnkbDU_bBDJ1dXGcu-7_sv84PZHdHIDVydXxKkR66ZLMYCnnZ9OS7l_Ntav6EdETYAqHfdYDHMoNMsuuwqBXra7ZOAht_aeNcFRW-SNMeM3Xvujc2-WOf2zLgKvQ1YI0tKfE2h1bF3MKZ8PMkueTJh61fe-tuTZfd5W-tSfPkK8w" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="620" data-original-width="716" height="346" src="https://blogger.googleusercontent.com/img/a/AVvXsEgMVzBG7aGJSLni6lmmVnkbDU_bBDJ1dXGcu-7_sv84PZHdHIDVydXxKkR66ZLMYCnnZ9OS7l_Ntav6EdETYAqHfdYDHMoNMsuuwqBXra7ZOAht_aeNcFRW-SNMeM3Xvujc2-WOf2zLgKvQ1YI0tKfE2h1bF3MKZ8PMkueTJh61fe-tuTZfd5W-tSfPkK8w=w400-h346" width="400" /></a></div><br /><br /><p></p><h3 style="text-align: left;">Multi-level matrix balancing</h3><p><br /></p><p>The data points (or priors) for each region \(\color{darkblue}a^0_r\) are imprecise. We have a margin of error \(\color{darkblue}E_r\) for each of them. We can use a multi-level matrix balancing model to create a consistent data set. Such a model can look like:</p><p><br /></p>
<table class="blueTable">
<thead><tr><th>Multi-level Matrix Balancing Problem</th></tr></thead>
<tbody><tr><td>\[\begin{align}\min\>&\sum_{r \in h2\cup h4\cup h6}\color{darkblue}w_r\left(\color{darkred}a_r-\color{darkblue}a^0_r\right)^2\\ & \color{darkred}a_{h4} = \sum_{h6 \in h4} \color{darkred}a_{h6} && \forall h4\\ &\color{darkred}a_{h2} = \sum_{h4 \in h2} \color{darkred}a_{h4} && \forall h2 \\& \color{darkblue}a^0_{\mathit{US}} = \sum_{h2} \color{darkred}a_{h2} \\ &\color{darkred}a_{r}=0 &&\forall r|\color{darkblue}a^0_{r}=0 \\ & \color{darkred}a_{r}\in [\color{darkblue}\ell_r,\color{darkblue}u_r] \\ &\color{darkblue}\ell_r = \max\{\color{darkblue}a^0_r - \color{darkblue}E_r, 0\} \\ & \color{darkblue}u_r = \color{darkblue}a^0_r + \color{darkblue}E_r \\ & \color{darkblue}w_r = \frac{1}{\color{darkblue}u_r-\color{darkblue}\ell_r} \end{align} \]</td></tr></tbody>
</table><br /><br /></div><div>Notes:</div><div><ul style="text-align: left;"><li>Identifiers colored red are endogenous (decision variables), while the blue symbols are exogenous (parameters).</li><li>The \(r\) index refers to all regions (huc 2, 4, and 6).</li><li>The huc-2 data has to add up to the national level. </li><li>Some variations are possible here, e.g. in how we specify the weights \(\color{darkblue}w_r\) and the functional form of the objective function. In our case, we could use hard bounds based on the margin of error. If that is problematic (too tight), we can use some elastic formulation.</li><li>The real problem is rather large (with many more data for each region). We can solve this in one big model or as a series of smaller models.</li><li>The convex quadratic objective allows us to use a general purpose NLP solver (such as CONOPT), or a more specialized algorithm (such as the conic solver in Cplex).</li></ul></div><div><br /></div><div>The output of the model: optimal levels of \(\color{darkred}a_r\) form a consistent data set. The huc 6 levels add up to huc 4, the huc 4 levels add up to huc 2, and the huc 2 levels add up to national data. We model this hierarchy with simultaneous equations.</div><div><br /></div><div>
<h3 style="text-align: left;">Conclusions</h3><div><br /></div><div>Some models require additional math programming models just to create consistent data sets. This is a nice example of that.</div><div><br /></div><div>Earlier in discussions about this problem, there were ideas to implement an algorithm for this. I would not know how to do that. Instead, using a formal optimization model, is quite straightforward and rather elegant, I think.</div><div><br /></div><h3 style="text-align: left;">References</h3><p><br /></p><p></p><ol style="text-align: left;"><li>USGS, Hydrologic Unit Maps, <a href="https://water.usgs.gov/GIS/huc.html">https://water.usgs.gov/GIS/huc.html</a> </li><li>The JavaScript library for bespoke data visualization, <a href="https://d3js.org/">https://d3js.org/</a></li></ol><div><br /></div><h3 style="text-align: left;">Appendix: GAMS code<span> </span></h3><div><span><br /></span></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$<span class="SpellE">onText</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">3-level matrix balancing demo</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$<span class="SpellE">offText</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">read</span> sets from huc.inc</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">the</span> readme part is shown below</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* Regions extracted from c:\tmp\huc\huc6main.geojson</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* Contents:</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">set huc</span>0: superset, all <span class="SpellE">huc</span> regions</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">set huc</span>6: 6 digit <span class="SpellE">huc</span> regions</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">set huc</span>4: 4 digit <span class="SpellE">huc</span> regions</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">set huc</span>2: 2 digit <span class="SpellE">huc</span> regions</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">set <span class="SpellE">hucisin</span></span>: region 1 is inside region 2</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">parameter</span> <span class="SpellE">hucacres</span>: size of region in acres</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* Generated: 2023-08-26</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$include</span><i><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">c:\tmp\huc\huc.inc</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">generate</span> some dummy data</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">shorter</span> names for sets</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">alias</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="GramE">r,huc</span>0);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">alias</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(h<span class="GramE">6,huc</span>6),(h4,huc4),(h2,huc2);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">parameter</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">a0(r) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'prior estimates'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">e(r) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'margin of error'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">a0<span class="GramE">us <span style="color: #0000da;">'</span></span></span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">national data'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">a0(h6) = </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">uniform</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span style="font-family: Consolas; font-size: 10.5pt;">0,100);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">e(h6) = </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">uniform</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span style="font-family: Consolas; font-size: 10.5pt;">0,100);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">a0(h4) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">hucisin</span>(h<span class="GramE">6,h</span>4),a0(h6));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">e(h4) = </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">uniform</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span style="font-family: Consolas; font-size: 10.5pt;">0,50);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">a0(h2) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">hucisin</span>(h<span class="GramE">4,h</span>2),a0(h4));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">e(h2) = </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">uniform</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span style="font-family: Consolas; font-size: 10.5pt;">0,20);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">a0us = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(h<span class="GramE">2,a</span>0(h2)) + 100;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">matrix</span> balancing model</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*---------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">parameters</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">lo(r) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'d-r'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">up(r) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'<span class="SpellE">d+e</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">w(<span class="GramE">r) <span style="color: #0000da;">'</span></span></span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">weights'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">lo(r) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">max</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(a0(r)-e(r),0<span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">up(r) = a0(r)+e(r<span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">w(r)$(up(r)>lo(r)) = 1/(up(r)-lo(r)<span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">variable </span></b><span style="font-family: Consolas; font-size: 10.5pt;">a(r<span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">a.lo</span></span></span><span style="font-family: Consolas; font-size: 10.5pt;">(r) = lo(r);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">a.up</span></span></span><span style="font-family: Consolas; font-size: 10.5pt;">(r) = up(r);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">variable </span></b><span style="font-family: Consolas; font-size: 10.5pt;">z </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'objective<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">equations</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">obj </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'minimize squared <span class="SpellE">weighted</span> <span class="GramE">deviations</span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">sum6(h4) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'h4 = sum h6'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">sum4(h2) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'h2 = sum h4'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">sum2 </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'US = sum h2'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">obj..</span></span><span style="font-family: Consolas; font-size: 10.5pt;"> z =e= </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span style="font-family: Consolas; font-size: 10.5pt;">r, w(r)*</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sqr</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(a(r)-a0(r)));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">sum6(h4<span class="GramE">)..</span> a(h4) =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">hucisin</span>(h<span class="GramE">6,h</span>4),a(h6));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">sum4(h2<span class="GramE">)..</span> a(h2) =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">hucisin</span>(h<span class="GramE">4,h</span>2),a(h4));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">sum<span class="GramE">2..</span> a0us =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(h<span class="GramE">2,a</span>(h2));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">model </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">matbal</span></span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /all<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">solve</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">matbal</span> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">using</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">qcp</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> z;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p></td></tr></tbody></table><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.6933px; margin: 0in 0in 8pt;"><o:p> </o:p></p></div><p></p></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com0tag:blogger.com,1999:blog-593563533834706486.post-37171378733459280682023-08-04T01:32:00.034-04:002023-08-30T14:08:26.027-04:00Some TSP MTZ experiments<script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style><p>In [1], a question was posed about a TSP model using the MTZ (Miller-Tucker-Zemlin) subtour elimination constraints. The results with Julia/glpk were disappointing. With \(n=58\) cities, things were taken so long that the solver seemed to hang. Here I want to see how a precise formulation with a good MIP solver can do better. As <i>seeing is believing</i>, let's do some experiments. </p><p>The standard MTZ formulation[1] can be derived easily. We use the binary variables \[\color{darkred}x_{i,j}=\begin{cases}1 & \text{if city $j$ is visited directly after going to city $i$}\\ 0 & \text{otherwise}\end{cases}\] </p><p><span></span></p><a name='more'></a>The building blocks of this TSP model are<p></p><p></p><ul style="text-align: left;"><li>a set of assignment constraints that implement "each city \(i\) has exactly one follower \(j\) and each city \(j\) has exactly one predecessor \(i\)", This yields \[\begin{align}&\sum_{j|i\ne j} \color{darkred}x_{i,j}=1&&\forall i\\ & \sum_{i|i\ne j} \color{darkred}x_{i,j}=1&&\forall j\end{align}\]</li><li>a set of subtour elimination constraints that impose a sequence of cities to visit. This can be modeled as using extra sequencing variables \(\color{darkred}u_i\in\{0,n-1\}\), and the constraint: \[\color{darkred}x_{i,j}=1\implies \color{darkred}u_j=\color{darkred}u_i+1\>\>\forall i\ne j, j \gt 1\] We can fix in advance \(\color{darkred}u_1 = 0\). We can reformulate this constraint as a big-M constraint: \[\color{darkred}u_j \ge \color{darkred}u_i + 1 - \color{darkblue}n\cdot(1-\color{darkred}x_{i,j})\>\>\forall i\ne j, j \gt 1\]</li></ul><div>A complete MTZ model can look like:</div><div><br /></div>
<table class="blueTable">
<thead><tr><th>TSP/MTZ model</th></tr></thead>
<tbody><tr><td>\[\begin{align}\min&\sum_{i,j|i\ne j}\color{darkblue}{\mathit{dist}}_{i,j}\cdot\color{darkred}x_{i,j}\\ & \sum_{j|i\ne j} \color{darkred}x_{i,j}=1 && \forall i \\ & \sum_{i|i\ne j} \color{darkred}x_{i,j}=1&&\forall j\\ & \color{darkred}u_j \ge \color{darkred}u_i + 1 - \color{darkblue}n\cdot(1-\color{darkred}x_{i,j}) && \forall i\ne j, j \gt 1 \\ & \color{darkred}u_1 = 0 \\ & \color{darkred}x_{i,j}\in\{0,1\}\\ & \color{darkred}u_i \in \{0,\dots,\color{darkblue}n-1\}\end{align}\]</td></tr></tbody>
</table>
<p><br /></p><p>We can add: \[\begin{align}& \color{darkred}u_i \ge 1 &&\forall i\gt 1\\ &\sum_i \color{darkred}u_i = \frac{\color{darkblue}n(\color{darkblue}n-1)}{2} \end{align}\] These are not in the standard MTZ model, and I left them out.</p><p>
We can relax the \(\color{darkred}u_i\) variables to be continuous. It is not obvious to me, how this affects the computation time. One could argue that the use of continuous variables lead to fewer discrete variables, and this can mean fewer branches, while integer variables convey more information for the presolvers and possibly better cut generation. This is an obvious question which I hardly see discussed. So let's do some experiments. </p><p><br /></p><h3 style="text-align: left;">Lifted MTZ Constraints</h3><p><br /></p><p>In [3], a somewhat tighter formulation is proposed, called "<b>lifted MTZ constraints</b>". The subtour elimination constraint is replaced by:\[\color{darkred}u_i-\color{darkred}u_j + (\color{darkblue}n-1)\cdot \color{darkred}x_{i,j} + (\color{darkred}n-3)\cdot \color{darkred}x_{j,i} \le \color{darkblue}n-2\>\>\forall i\ne j, j \gt 1\] </p><p><br /></p><h3 style="text-align: left;">Valid Inequalities</h3><p><br /></p><p>There are some <b>valid inequalities</b> (extra constraints that tighten the formulation) for this model [3]. They look like \[\begin{align}&\color{darkred}u_j\ge 1+(1-\color{darkred}x_{1,j})+(\color{darkblue}n-3)\cdot \color{darkred}x_{j,1} && \forall j \ge 2 \\ &\color{darkred}u_j \le (\color{darkblue}n-1)- (\color{darkblue}n-3)\cdot \color{darkred}x_{1,j} - (1-\color{darkred}x_{j,1}) && \forall j \ge 2\end{align}\]</p><p><br /></p><h3 style="text-align: left;">Results</h3><p><br /></p><p>When I try this on a data set with \(n=58\) cities and random coordinates and Euclidean distances, I get the following results:</p><p><br /></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">180</span> PARAMETER <b>stats </b><i>collected statistics</i>
obj iterations nodes seconds
MTZ(int u) <span style="color: #6600ee; font-weight: bold;">569.089</span> <span style="color: #6600ee; font-weight: bold;">1061905.000</span> <span style="color: #6600ee; font-weight: bold;">83982.000</span> <span style="color: #6600ee; font-weight: bold;">27.578</span>
MTZ(relaxed u) <span style="color: #6600ee; font-weight: bold;">569.089</span> <span style="color: #6600ee; font-weight: bold;">1153378.000</span> <span style="color: #6600ee; font-weight: bold;">77797.000</span> <span style="color: #6600ee; font-weight: bold;">22.953</span>
lifted(int u) <span style="color: #6600ee; font-weight: bold;">569.089</span> <span style="color: #6600ee; font-weight: bold;">1623901.000</span> <span style="color: #6600ee; font-weight: bold;">105898.000</span> <span style="color: #6600ee; font-weight: bold;">20.094</span>
lifted(relaxed u) <span style="color: #6600ee; font-weight: bold;">569.089</span> <span style="color: #6600ee; font-weight: bold;">1287205.000</span> <span style="color: #6600ee; font-weight: bold;">73390.000</span> <span style="color: #6600ee; font-weight: bold;">18.610</span>
lift<span style="color: #333333;">+</span>vi(int u) <span style="color: #6600ee; font-weight: bold;">569.089</span> <span style="color: #6600ee; font-weight: bold;">365546.000</span> <span style="color: #6600ee; font-weight: bold;">27155.000</span> <span style="color: #6600ee; font-weight: bold;">4.735</span>
lift<span style="color: #333333;">+</span>vi(relaxed u) <span style="color: #6600ee; font-weight: bold;">569.089</span> <span style="color: #6600ee; font-weight: bold;">887140.000</span> <span style="color: #6600ee; font-weight: bold;">60696.000</span> <span style="color: #6600ee; font-weight: bold;">14.406</span>
</pre></div>
<p> </p><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px;"><p style="text-align: left;"> <b>Update</b>.This is just one run. In the comments, Riley notes that it is much better to create a bunch of performance observations (either by different problem sets or by changing the seed -- forcing the solver to use a different path). This is because the variability in the timing of MIP solvers is very large, and can dominate single observations. Here is his picture (using Gurobi):</p></blockquote><p><br /></p><p style="text-align: left;"></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgkAR5nh3NqU6WOZIxA7ko9xHynVWf-IPmjrFpHJPLzk0KCxPb50buKkOiOY-Lhn4mZBi5SKmcj3X_7Hc7kgeKTbGjUI5QhAx8r4MX9SFoiaRXXbXLc05fuUKWTH-LZI3Z-l6-lkYOUP9qeJWvdKpC6yzO8QVR3tojUCBz8rJZzxLkV0yHYU5n2lbQD5ePA" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="432" data-original-width="636" src="https://blogger.googleusercontent.com/img/a/AVvXsEgkAR5nh3NqU6WOZIxA7ko9xHynVWf-IPmjrFpHJPLzk0KCxPb50buKkOiOY-Lhn4mZBi5SKmcj3X_7Hc7kgeKTbGjUI5QhAx8r4MX9SFoiaRXXbXLc05fuUKWTH-LZI3Z-l6-lkYOUP9qeJWvdKpC6yzO8QVR3tojUCBz8rJZzxLkV0yHYU5n2lbQD5ePA=s16000" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Runtimes with 50 replications (using a different seed) using Gurobi</td></tr></tbody></table><p></p><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px;"><p><br /></p><p>Interestingly to see how integer \(\color{darkred}u_i\) is much better for the lifted case, but not the others. Not sure if I can explain this. May need more replications with different data sets to make sure this difference persists.</p></blockquote><p></p><p><br /></p><p>These results (with the Cplex MIP solver) indicate that all versions solve within half a minute. The version with the lifted subtour elimination constraint and added valid inequalities using integer \(\color{darkred}u_i\) is surprisingly fast at less than 5 seconds. However, I am not convinced that this particular model is systematically faster than the other ones. I have seen no article that suggests to use integer \(\color{darkred}u_i\). (I have not seen papers even discussing this.) For sure, we can say: there are instances that benefit from using integer variables. It is noted that solvers like Cplex and Gurobi sometimes replace continuous variables with discrete ones. That is not always obvious and requires careful inspection of the log file.</p><p><br /></p><p></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhnDwomLUQhzrVyu7UeTS22CH2KaDD9gIGYc-J8bznAFLpYAyv7mr4rjIA81-Qb9hMa83bSlCP1uyq69I8biQg7BrqgP9TD8bM2ycJxEzSqoHoQ5Jg_cqv7YiH0b_D39bLO0s9tyjh5_RL4enlikazXZkPWRgDPdBvkEHZv7MFm4NNlZQ_uJqKtR4CmtVB4" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="776" data-original-width="837" height="594" src="https://blogger.googleusercontent.com/img/a/AVvXsEhnDwomLUQhzrVyu7UeTS22CH2KaDD9gIGYc-J8bznAFLpYAyv7mr4rjIA81-Qb9hMa83bSlCP1uyq69I8biQg7BrqgP9TD8bM2ycJxEzSqoHoQ5Jg_cqv7YiH0b_D39bLO0s9tyjh5_RL4enlikazXZkPWRgDPdBvkEHZv7MFm4NNlZQ_uJqKtR4CmtVB4=w640-h594" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Plot of the results</td></tr></tbody></table><br />If you look at the plot of the results, the optimal tour seems somewhat obvious. Almost like you could do this by hand. However, if we just view the points, the problem looks much more difficult.<div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhki1rATBdQC0RL1qpGXpZ65Wi0N4xseLWYZ2oRrRDb44F1qcVMkvoXFGU_oi590hYle0BFW9QyGUOLclax_Kq83xIjhXIisH9iJZyd0TegXuS0a7Tb64HTnQdxAnrqTH00WgvPHY-UK-c4sh0QU0A3lma2zU-EEpfeG-wagaFj08ScbzCkXL1MXoWlxY4i" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="792" data-original-width="864" height="586" src="https://blogger.googleusercontent.com/img/a/AVvXsEhki1rATBdQC0RL1qpGXpZ65Wi0N4xseLWYZ2oRrRDb44F1qcVMkvoXFGU_oi590hYle0BFW9QyGUOLclax_Kq83xIjhXIisH9iJZyd0TegXuS0a7Tb64HTnQdxAnrqTH00WgvPHY-UK-c4sh0QU0A3lma2zU-EEpfeG-wagaFj08ScbzCkXL1MXoWlxY4i=w640-h586" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Only the points</td></tr></tbody></table><br /><br />It is interesting how I perceive the difficulty of the problem when looking at these two plots. The plot with the optimal tour makes the problem like almost trivial. The plot with just the points makes the problem look quite difficult. This is an example of optical illusion.</div><div><br /></div><div><br /></div><h3 style="text-align: left;">Conclusion</h3><div><br /></div><div>The MTZ subtour elimination constraints are known to be slow. A TSP with \(n=58\) points, however, is well within the reach of a good MIP solver. Lifting the MTZ constraints helps a bit, but we are still in the same ballpark. Adding valid inequalities can help further. </div><div><br /></div><div>Note that we used an Asymmetric TSP formulation. We <b>don't</b> assume the distances are symmetric, i.e. \(\color{darkblue}{\mathit{dist}}_{i,j}=\color{darkblue}{\mathit{dist}}_{j,i}\). The random dataset, however, has symmetric distances. </div><div><br /></div><div>The models don't use callbacks. I stay (somewhat) close to the original MTZ version of the model. I.e., just a straight linear MIP model.</div><div><br /></div><div>For people using heuristics for this problem: the reported timings are for obtaining proven optimal solutions, not just a good solution.</div><div><br /></div><div>The GAMS code below also demonstrates a simple way to plot TSP tours. I generate some simple HTML/SVG code for this.</div><div><br /></div><div><h3 style="text-align: left;">References</h3><div><br /></div><div><ol style="text-align: left;"><li>Julia JuMP slowdown/hang while solving TSP, <a href="https://stackoverflow.com/questions/76750379/julia-jump-slowdown-hang-while-solving-tsp">https://stackoverflow.com/questions/76750379/julia-jump-slowdown-hang-while-solving-tsp</a></li><li>Miller, C., A. Tucker, R. Zemlin. 1960, Integer programming formulation of traveling salesman problems. J. ACM 7 326-329</li><li>Desrochers, M., Laporte, G., Improvements and extensions to the Miller-Tucker-Zemlin subtour elimination constraints, Operations Research Letters, 10 (1991) 27-36.</li><li>Hanif D. Sherali and Patrick J. Driscoll, On Tightening the Relaxations of Miller-Tucker-Zemlin Formulations for Asymmetric Traveling Salesman Problems, Operations Research, Vol. 50, No. 4 (Jul. - Aug., 2002), pp. 656-669</li></ol><div><br /></div></div><h3 style="text-align: left;">Appendix 1: GAMS Script</h3><div><br /></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$<span class="SpellE">onText</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> Simple demo of lifted MTZ</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> References:</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> Miller, C., A. Tucker, R. <span class="SpellE">Zemlin</span>. 1960.</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> Integer programming formulation of traveling</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> salesman problems. J. ACM 7 326-329</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> Desrochers, M., Laporte, G.,</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> Improvements and extensions to the Miller-Tucker-<span class="SpellE">Zemlin</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> subtour elimination constraints,</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> Operations Research Letters, 10 (1991) 27-36.</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$<span class="SpellE">offText</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">use</span> all cores</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">option</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">threads</span></b><span style="font-family: Consolas; font-size: 9pt;"> = <span class="GramE">0;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">data</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sets</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'cities'</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /city1*city58/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">xy</span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /<span class="SpellE"><span class="GramE">x,y</span></span>/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">alias</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">scalar </span></b><span style="font-family: Consolas; font-size: 9pt;">n </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'number of cities<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">n = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">card</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span><span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">parameter </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">coord</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">i,xy</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'random coordinates'</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">coord</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">i,xy</span></span>) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">uniform</span></b><span style="font-family: Consolas; font-size: 9pt;">(0,100);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">parameter </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">dist</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'distance matrix'</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">dist</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sqrt</span></b><span style="font-family: Consolas; font-size: 9pt;">(</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">xy,<b><span style="color: #0000b3;">sqr</span></b></span>(<span class="SpellE">coord</span>(<span class="SpellE">i,xy</span>)-<span class="SpellE">coord</span>(<span class="SpellE">j,xy</span>))));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">set </span></b><span style="font-family: Consolas; font-size: 9pt;">arcs(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'travel allowed between cities'</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">arcs(<span class="SpellE"><span class="GramE">i,j</span></span>) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">not</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">sameas</span>(<span class="SpellE">i,j</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE"><span class="GramE">n,i</span>,coord,dist,arcs</span>;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">reporting</span> macro</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">parameter </span></b><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">stats(</span></span><span style="font-family: Consolas; font-size: 9pt;">*,*) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'collected statistics'</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$macro</span><i><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> statistics(<span class="SpellE"><span class="GramE">label,model</span></span>_) \</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> stats(<span class="SpellE">label,<span style="color: #007400;">'obj</span></span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'</span><span style="font-family: Consolas; font-size: 9pt;">) = model<span class="GramE">_.<span class="SpellE">objval</span></span>; \</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> stats(<span class="SpellE">label,<span style="color: #007400;">'iterations</span></span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'</span><span style="font-family: Consolas; font-size: 9pt;">) = model<span class="GramE">_.<span class="SpellE">iterusd</span></span>; \</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> stats(<span class="SpellE">label,<span style="color: #007400;">'nodes</span></span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'</span><span style="font-family: Consolas; font-size: 9pt;">) = model<span class="GramE">_.<span class="SpellE">nodusd</span></span>; \</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> stats(<span class="SpellE">label,<span style="color: #007400;">'seconds</span></span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'</span><span style="font-family: Consolas; font-size: 9pt;">) = model<span class="GramE">_.<span class="SpellE">resusd</span></span>; \</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="GramE">stats;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* Original MTZ formulation</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* Integer ordering variables</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">variable </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">totdist</span></span><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'total distance<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">binary variable </span></b><span style="font-family: Consolas; font-size: 9pt;">x(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'assignment variables: if 1 we travel <span class="SpellE">i</span>->j'</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">integer variable </span></b><span style="font-family: Consolas; font-size: 9pt;">u(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'ordering<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">u.up</span></span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">card</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>)-1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">start</span> in city 1</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">u.fx</span></span><span style="font-family: Consolas; font-size: 9pt;">(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'city1'</span><span style="font-family: Consolas; font-size: 9pt;">) = <span class="GramE">0;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">equations</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">objective </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'</span></span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">sum of distances traveled'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">assign1(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'assignment constraint'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">assign2(j) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'assignment constraint'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">sequence(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'ordering constraint'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">objective..</span></span><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">totdist</span> =e= </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(</span></span><span style="font-family: Consolas; font-size: 9pt;">arcs, <span class="SpellE">dist</span>(arcs)*x(arcs));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* I am being a bit cute here:</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">first</span> one sums over j, second one sums over <span class="SpellE">i</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">although</span> the equations look the same, they are different</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* because of the </span></i><i><span style="color: #787878; font-family: "Cambria Math", serif; font-size: 9pt;">∀</span></i><span class="SpellE"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">i</span></i></span><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> vs </span></i><i><span style="color: #787878; font-family: "Cambria Math", serif; font-size: 9pt;">∀</span></i><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">j (for all <span class="SpellE">i</span> vs for all j)</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">assign1(<span class="SpellE">i</span><span class="GramE">)..</span> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(arcs(<span class="SpellE"><span class="GramE">i,j</span></span>), x(arcs)) =e= 1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">assign2(j<span class="GramE">)..</span> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(arcs(<span class="SpellE"><span class="GramE">i,j</span></span>), x(arcs)) =e= 1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* MTZ ordering constraint</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* x(<span class="SpellE"><span class="GramE">i,j</span></span>)=1 => u(j) = u(<span class="SpellE">i</span>) + 1</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">we</span> implement this as a big-M constraint</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">sequence(arcs(<span class="SpellE"><span class="GramE">i,j</span></span>))$(</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">not</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">sameas</span>(j,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'city1'</span><span style="font-family: Consolas; font-size: 9pt;">))..</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> u(j) =g= u(<span class="SpellE">i</span>) + 1 - n*(1-x(<span class="SpellE"><span class="GramE">i,j</span></span>));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">this</span> is also often written as</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* u(<span class="SpellE">i</span>) - u(j) + n*x(<span class="SpellE"><span class="GramE">i,j</span></span>) <- n-1 </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">model </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">mtz</span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /all<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">mtz</span> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">mip</span></b></span><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE"><span class="GramE">totdist</span></span><span class="GramE">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">"%%% original MTZ formulation, integer u %%%<span class="GramE">"<span style="color: black;">,<span class="SpellE">totdist</span></span></span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">.l,x.l,u.l</span></span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">statistics(</span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'MTZ(int u)'</span><span style="font-family: Consolas; font-size: 9pt;">,<span class="SpellE">mtz</span>)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* Original MTZ formulation</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">relaxed</span> ordering variables</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">relax</span> u</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">u.prior</span></span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">inf</span></b><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">mtz</span> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">mip</span></b></span><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE"><span class="GramE">totdist</span></span><span class="GramE">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">"%%% original MTZ formulation, relaxed u %%%<span class="GramE">"<span style="color: black;">,<span class="SpellE">totdist</span></span></span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">.l,x.l,u.l</span></span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">statistics(</span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'MTZ(relaxed u)'</span><span style="font-family: Consolas; font-size: 9pt;">,<span class="SpellE">mtz</span>)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* Lifted MTZ formulation</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">make</span> u integer again</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">u.prior</span></span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>) = 1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">equation </span></b><span style="font-family: Consolas; font-size: 9pt;">lifted(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'lifted version of sequence constraint'</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">lifted(arcs(<span class="SpellE"><span class="GramE">i,j</span></span>))$(</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">not</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">sameas</span>(j,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'city1'</span><span style="font-family: Consolas; font-size: 9pt;">))..</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> u(<span class="SpellE">i</span>)-u(j) + (n-<span class="GramE">1)*</span>x(<span class="SpellE">i,j</span>) + (n-3)*x(<span class="SpellE">j,i</span>) =l= n-2;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">model </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">liftedmtz</span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /<span class="SpellE">mtz-sequence+lifted</span>/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">solve </span><span class="SpellE"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">liftedmtz</span></span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> using <span class="SpellE">mip</span> minimizing <span class="SpellE"><span class="GramE">totdist</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">statistics(</span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'lifted(int u)'</span><span style="font-family: Consolas; font-size: 9pt;">,<span class="SpellE">liftedmtz</span>)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">relax</span> u</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">u.prior</span></span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">inf</span></b><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">liftedmtz</span> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">mip</span></b></span><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE"><span class="GramE">totdist</span></span><span class="GramE">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">statistics(</span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'lifted(int u)'</span><span style="font-family: Consolas; font-size: 9pt;">,<span class="SpellE">liftedmtz</span>)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* Add valid inequalities</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">make</span> u integer again</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">u.prior</span></span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>) = 1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">equations</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span style="font-family: Consolas; font-size: 9pt;">valid1(j) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'valid inequalities'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">valid2(j) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'valid inequalities'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">valid1(j)$(</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">not</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">sameas</span>(j,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'city1<span class="GramE">'<span style="color: black;">))..</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> u(j) =g= 1 + (1-x(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'city1<span class="GramE">'<span style="color: black;">,j</span></span></span><span style="font-family: Consolas; font-size: 9pt;">)) + (n-3)*x(j,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'city1'</span><span style="font-family: Consolas; font-size: 9pt;">);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">valid2(j)$(</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">not</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">sameas</span>(j,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'city1<span class="GramE">'<span style="color: black;">))..</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> u(j) =l= (n-1) - (n-<span class="GramE">3)*</span>x(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'city1'</span><span style="font-family: Consolas; font-size: 9pt;">,j) - (1-x(j,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'city1'</span><span style="font-family: Consolas; font-size: 9pt;">));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">model </span></b><span style="font-family: Consolas; font-size: 9pt;">liftedmtz2</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /<span class="GramE">liftedmtz,valid</span>1,valid2/</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> liftedmtz2 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">mip</span></b></span><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">totdist</span>;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span lang="NL" style="font-family: Consolas; font-size: 9pt;">statistics</span></span></span><span class="GramE"><span lang="NL" style="font-family: Consolas; font-size: 9pt;">(</span></span><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">lift+vi</span>(int u)'</span><span lang="NL" style="font-family: Consolas; font-size: 9pt;">,liftedmtz2)</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span lang="NL" style="color: #787878; font-family: Consolas; font-size: 9pt;">* relax u</span></i><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">u.prior</span></span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">inf</span></b><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> liftedmtz2 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">mip</span></b></span><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE"><span class="GramE">totdist</span></span><span class="GramE">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">statistics(</span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">lift+vi</span>(relaxed u)'</span><span style="font-family: Consolas; font-size: 9pt;">,liftedmtz2)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* Plot results</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">file </span></b><span style="font-family: Consolas; font-size: 9pt;">f</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /tour.html<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">put</span></b><span style="font-family: Consolas; font-size: 9pt;"> f </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<<span class="SpellE">svg</span> width="1000" height="800" <span class="SpellE">viewBox</span>="-10 -10 110 110">'</span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">/;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">loop</span></b><span style="font-family: Consolas; font-size: 9pt;">(arcs(<span class="SpellE"><span class="GramE">i,j</span></span>)$(<span class="SpellE">x.l</span>(arcs)>0.5),</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">put</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<line x1="<span class="GramE">'<span style="color: black;">,<span class="SpellE">coord</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'x'</span><span style="font-family: Consolas; font-size: 9pt;">):0,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'" y1="'</span><span style="font-family: Consolas; font-size: 9pt;">,<span class="SpellE">coord</span>(<span class="SpellE">i</span>,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'y'</span><span style="font-family: Consolas; font-size: 9pt;">):0,</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'" x2="<span class="GramE">'<span style="color: black;">,<span class="SpellE">coord</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">j,<span style="color: #007400;">'x</span></span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'</span><span style="font-family: Consolas; font-size: 9pt;">):0,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'" y2="'</span><span style="font-family: Consolas; font-size: 9pt;">,<span class="SpellE">coord</span>(<span class="SpellE">j,<span style="color: #007400;">'y</span></span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'</span><span style="font-family: Consolas; font-size: 9pt;">):0,</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'" stroke="<span class="SpellE">darkred</span>" stroke-width="0.1"/>'</span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">/;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">loop</span></b><span style="font-family: Consolas; font-size: 9pt;">(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="font-family: Consolas; font-size: 9pt;">,</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">put</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<circle cx="<span class="GramE">'<span style="color: black;">,<span class="SpellE">coord</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'x'</span><span style="font-family: Consolas; font-size: 9pt;">):0,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'" cy="'</span><span style="font-family: Consolas; font-size: 9pt;">,<span class="SpellE">coord</span>(<span class="SpellE">i</span>,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'y'</span><span style="font-family: Consolas; font-size: 9pt;">):0,</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'" r="0.5" fill="blue"/>'</span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">/;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">putclose</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'</<span class="SpellE">svg</span>>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span><span style="background-color: transparent;">/;</span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">execute </span></b><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">shellexecute</span> tour.html'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span><span style="background-color: transparent;">;</span></p><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-size: 9pt;"> </span></p></td></tr></tbody></table><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.6933px; margin: 0in 0in 8pt;"><o:p> </o:p></p></div><div><br /></div><div><h3>Appendix 2: Data Set</h3><div><br /></div></div><div>The following data was used in the above experiments.</div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">45</span> PARAMETER <b>coord </b><i>random coordinates</i>
x y
city1 <span style="color: #6600ee; font-weight: bold;">17.1747132</span> <span style="color: #6600ee; font-weight: bold;">84.3266708</span>
city2 <span style="color: #6600ee; font-weight: bold;">55.0375356</span> <span style="color: #6600ee; font-weight: bold;">30.1137904</span>
city3 <span style="color: #6600ee; font-weight: bold;">29.2212117</span> <span style="color: #6600ee; font-weight: bold;">22.4052867</span>
city4 <span style="color: #6600ee; font-weight: bold;">34.9830504</span> <span style="color: #6600ee; font-weight: bold;">85.6270347</span>
city5 <span style="color: #6600ee; font-weight: bold;">6.7113723</span> <span style="color: #6600ee; font-weight: bold;">50.0210669</span>
city6 <span style="color: #6600ee; font-weight: bold;">99.8117627</span> <span style="color: #6600ee; font-weight: bold;">57.8733378</span>
city7 <span style="color: #6600ee; font-weight: bold;">99.1133039</span> <span style="color: #6600ee; font-weight: bold;">76.2250467</span>
city8 <span style="color: #6600ee; font-weight: bold;">13.0692483</span> <span style="color: #6600ee; font-weight: bold;">63.9718759</span>
city9 <span style="color: #6600ee; font-weight: bold;">15.9517864</span> <span style="color: #6600ee; font-weight: bold;">25.0080533</span>
city10 <span style="color: #6600ee; font-weight: bold;">66.8928609</span> <span style="color: #6600ee; font-weight: bold;">43.5356381</span>
city11 <span style="color: #6600ee; font-weight: bold;">35.9700266</span> <span style="color: #6600ee; font-weight: bold;">35.1441368</span>
city12 <span style="color: #6600ee; font-weight: bold;">13.1491590</span> <span style="color: #6600ee; font-weight: bold;">15.0101788</span>
city13 <span style="color: #6600ee; font-weight: bold;">58.9113650</span> <span style="color: #6600ee; font-weight: bold;">83.0892812</span>
city14 <span style="color: #6600ee; font-weight: bold;">23.0815738</span> <span style="color: #6600ee; font-weight: bold;">66.5734460</span>
city15 <span style="color: #6600ee; font-weight: bold;">77.5857606</span> <span style="color: #6600ee; font-weight: bold;">30.3658477</span>
city16 <span style="color: #6600ee; font-weight: bold;">11.0492291</span> <span style="color: #6600ee; font-weight: bold;">50.2384866</span>
city17 <span style="color: #6600ee; font-weight: bold;">16.0172762</span> <span style="color: #6600ee; font-weight: bold;">87.2462311</span>
city18 <span style="color: #6600ee; font-weight: bold;">26.5114545</span> <span style="color: #6600ee; font-weight: bold;">28.5814322</span>
city19 <span style="color: #6600ee; font-weight: bold;">59.3955922</span> <span style="color: #6600ee; font-weight: bold;">72.2719071</span>
city20 <span style="color: #6600ee; font-weight: bold;">62.8248677</span> <span style="color: #6600ee; font-weight: bold;">46.3797865</span>
city21 <span style="color: #6600ee; font-weight: bold;">41.3306994</span> <span style="color: #6600ee; font-weight: bold;">11.7695357</span>
city22 <span style="color: #6600ee; font-weight: bold;">31.4212267</span> <span style="color: #6600ee; font-weight: bold;">4.6551514</span>
city23 <span style="color: #6600ee; font-weight: bold;">33.8550272</span> <span style="color: #6600ee; font-weight: bold;">18.2099593</span>
city24 <span style="color: #6600ee; font-weight: bold;">64.5727127</span> <span style="color: #6600ee; font-weight: bold;">56.0745547</span>
city25 <span style="color: #6600ee; font-weight: bold;">76.9961720</span> <span style="color: #6600ee; font-weight: bold;">29.7805864</span>
city26 <span style="color: #6600ee; font-weight: bold;">66.1106261</span> <span style="color: #6600ee; font-weight: bold;">75.5821674</span>
city27 <span style="color: #6600ee; font-weight: bold;">62.7447499</span> <span style="color: #6600ee; font-weight: bold;">28.3864198</span>
city28 <span style="color: #6600ee; font-weight: bold;">8.6424624</span> <span style="color: #6600ee; font-weight: bold;">10.2514669</span>
city29 <span style="color: #6600ee; font-weight: bold;">64.1251151</span> <span style="color: #6600ee; font-weight: bold;">54.5309498</span>
city30 <span style="color: #6600ee; font-weight: bold;">3.1524852</span> <span style="color: #6600ee; font-weight: bold;">79.2360642</span>
city31 <span style="color: #6600ee; font-weight: bold;">7.2766998</span> <span style="color: #6600ee; font-weight: bold;">17.5661049</span>
city32 <span style="color: #6600ee; font-weight: bold;">52.5632613</span> <span style="color: #6600ee; font-weight: bold;">75.0207669</span>
city33 <span style="color: #6600ee; font-weight: bold;">17.8123714</span> <span style="color: #6600ee; font-weight: bold;">3.4140986</span>
city34 <span style="color: #6600ee; font-weight: bold;">58.5131173</span> <span style="color: #6600ee; font-weight: bold;">62.1229984</span>
city35 <span style="color: #6600ee; font-weight: bold;">38.9361900</span> <span style="color: #6600ee; font-weight: bold;">35.8714153</span>
city36 <span style="color: #6600ee; font-weight: bold;">24.3034617</span> <span style="color: #6600ee; font-weight: bold;">24.6421539</span>
city37 <span style="color: #6600ee; font-weight: bold;">13.0502803</span> <span style="color: #6600ee; font-weight: bold;">93.3449720</span>
city38 <span style="color: #6600ee; font-weight: bold;">37.9937906</span> <span style="color: #6600ee; font-weight: bold;">78.3400461</span>
city39 <span style="color: #6600ee; font-weight: bold;">30.0034258</span> <span style="color: #6600ee; font-weight: bold;">12.5483222</span>
city40 <span style="color: #6600ee; font-weight: bold;">74.8874105</span> <span style="color: #6600ee; font-weight: bold;">6.9232463</span>
city41 <span style="color: #6600ee; font-weight: bold;">20.2015557</span> <span style="color: #6600ee; font-weight: bold;">0.5065858</span>
city42 <span style="color: #6600ee; font-weight: bold;">26.9613052</span> <span style="color: #6600ee; font-weight: bold;">49.9851475</span>
city43 <span style="color: #6600ee; font-weight: bold;">15.1285869</span> <span style="color: #6600ee; font-weight: bold;">17.4169455</span>
city44 <span style="color: #6600ee; font-weight: bold;">33.0637734</span> <span style="color: #6600ee; font-weight: bold;">31.6906054</span>
city45 <span style="color: #6600ee; font-weight: bold;">32.2086955</span> <span style="color: #6600ee; font-weight: bold;">96.3976641</span>
city46 <span style="color: #6600ee; font-weight: bold;">99.3602205</span> <span style="color: #6600ee; font-weight: bold;">36.9903055</span>
city47 <span style="color: #6600ee; font-weight: bold;">37.2888567</span> <span style="color: #6600ee; font-weight: bold;">77.1978330</span>
city48 <span style="color: #6600ee; font-weight: bold;">39.6684142</span> <span style="color: #6600ee; font-weight: bold;">91.3096325</span>
city49 <span style="color: #6600ee; font-weight: bold;">11.9577730</span> <span style="color: #6600ee; font-weight: bold;">73.5478889</span>
city50 <span style="color: #6600ee; font-weight: bold;">5.5418475</span> <span style="color: #6600ee; font-weight: bold;">57.6299805</span>
city51 <span style="color: #6600ee; font-weight: bold;">5.1407110</span> <span style="color: #6600ee; font-weight: bold;">0.6008368</span>
city52 <span style="color: #6600ee; font-weight: bold;">40.1227683</span> <span style="color: #6600ee; font-weight: bold;">51.9881187</span>
city53 <span style="color: #6600ee; font-weight: bold;">62.8877255</span> <span style="color: #6600ee; font-weight: bold;">22.5749880</span>
city54 <span style="color: #6600ee; font-weight: bold;">39.6121408</span> <span style="color: #6600ee; font-weight: bold;">27.6006131</span>
city55 <span style="color: #6600ee; font-weight: bold;">15.2372608</span> <span style="color: #6600ee; font-weight: bold;">93.6322836</span>
city56 <span style="color: #6600ee; font-weight: bold;">42.2660590</span> <span style="color: #6600ee; font-weight: bold;">13.4663129</span>
city57 <span style="color: #6600ee; font-weight: bold;">38.6055614</span> <span style="color: #6600ee; font-weight: bold;">37.4632747</span>
city58 <span style="color: #6600ee; font-weight: bold;">26.8481040</span> <span style="color: #6600ee; font-weight: bold;">94.8370515</span>
</pre></div>
<div><br /></div><div>The Euclidean distances are directly calculated from these coordinates.</div><div> </div><div><br /></div><p></p></div><h3 style="text-align: left;">
Appendix 3: Assignment Solution</h3><div><br /></div><div>You may be wondering what the solution without subtour elimination constraints looks like. The resulting model is a simple assignment problem. Here is a picture. We see a ton of subtours.</div><div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhuFisS18ySc1CyuMzpLvVU0U9RuEPyR9I-DEl6CSsr08KTV2DeyPFHpK592wRDpWPmoqXBq5M4Qci3TE8brLGVyv-kziqcFEh7o_id8jj_mx1ALUEVPlBLcPvYzDux0MQzX3svE9ua5dSorZEEo_Vcey2hhkl4T1tMyeHUsb2G4OtrmuNPhs2ZURTuI2UR" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="757" data-original-width="795" height="610" src="https://blogger.googleusercontent.com/img/a/AVvXsEhuFisS18ySc1CyuMzpLvVU0U9RuEPyR9I-DEl6CSsr08KTV2DeyPFHpK592wRDpWPmoqXBq5M4Qci3TE8brLGVyv-kziqcFEh7o_id8jj_mx1ALUEVPlBLcPvYzDux0MQzX3svE9ua5dSorZEEo_Vcey2hhkl4T1tMyeHUsb2G4OtrmuNPhs2ZURTuI2UR=w640-h610" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Solution without subtour elimination constraints</td></tr></tbody></table><br /><br /></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com6tag:blogger.com,1999:blog-593563533834706486.post-78207691092742763712023-07-12T14:44:00.025-04:002023-08-30T14:08:10.903-04:00Coloring edges of a grid<script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style>This is a little coloring problem from [1]:
<div><br /></div><div><p style="--_pr-img-mb: 0; background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #232629; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI Adjusted", "Segoe UI", "Liberation Sans", sans-serif; font-feature-settings: inherit; font-kerning: inherit; font-optical-sizing: inherit; font-size: 15px; font-stretch: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; font-variation-settings: inherit; line-height: inherit; margin: 0px 0px 1.1em; padding: 0px; vertical-align: baseline;"></p></div><blockquote><div><p style="--_pr-img-mb: 0; background-color: white; border: 0px; box-sizing: inherit; clear: both; color: #232629; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI Adjusted", "Segoe UI", "Liberation Sans", sans-serif; font-feature-settings: inherit; font-kerning: inherit; font-optical-sizing: inherit; font-size: 15px; font-stretch: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; font-variation-settings: inherit; line-height: inherit; margin: 0px 0px 1.1em; padding: 0px; vertical-align: baseline;">Given an m * n grid, each edge must be colored. However, there are 2 constraints:</p><ol style="background-color: white; border: 0px; box-sizing: inherit; color: #232629; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI Adjusted", "Segoe UI", "Liberation Sans", sans-serif; font-feature-settings: inherit; font-kerning: inherit; font-optical-sizing: inherit; font-size: 15px; font-stretch: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; font-variation-settings: inherit; line-height: inherit; list-style-image: initial; list-style-position: initial; margin: 0px 0px 1.1em 30px; padding: 0px; vertical-align: baseline;"><li style="--_pr-blockquote-mt: calc(1.1em / 2); --_pr-img-mb: 0; border: 0px; box-sizing: inherit; font-family: inherit; font-feature-settings: inherit; font-kerning: inherit; font-optical-sizing: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-variation-settings: inherit; font-weight: inherit; line-height: inherit; margin-left: 0px; margin-right: 0px; margin-top: 0px; margin: 0px 0px calc(0.55em); overflow-wrap: break-word; padding: 0px; vertical-align: baseline;">Entire grid must use only 3 unique colors</li><li style="--_pr-blockquote-mt: calc(1.1em / 2); --_pr-img-mb: 0; border: 0px; box-sizing: inherit; font-family: inherit; font-feature-settings: inherit; font-kerning: inherit; font-optical-sizing: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-variation-settings: inherit; font-weight: inherit; line-height: inherit; margin: 0px; overflow-wrap: break-word; padding: 0px; vertical-align: baseline;">Each square in the grid must be colored using exactly 2 colors (2 edges per color)</li></ol></div><div></div></blockquote><div><br /></div><div><br /></div><div>Let's try to build a GAMS model for this. The question itself is not so interesting, but the modeling for setting up these grids is.</div><span><a name='more'></a></span><div><br /></div><h3 style="text-align: left;">Data structures</h3><div><br /></div><div>First, we need to represent the grid. </div><div><br /></div><div> </div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0in 5.4pt 0in 5.4pt; mso-yfti-tbllook: 1184;">
<tbody><tr>
<td style="border: 1pt solid windowtext; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623">
<p class="MsoNormal" style="background: white; line-height: 12pt; margin-bottom: 0in; mso-line-height-rule: exactly;"><span style="font-family: Consolas; font-size: 10.5pt;"><span style="color: #787878;"><i>*-------------------------------------------------</i></span><span style="color: #d4d4d4;"><br /></span></span><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">* sets to represent
grid and edges.<br /></span></i><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">* representation of
squares is by left-lower point<br /></span></i><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">*-------------------------------------------------</span></i></p>
<p class="MsoNormal" style="background: white; line-height: 12pt; margin-bottom: 0in; mso-line-height-rule: exactly;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">set<br /></span></b><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">i </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'grid x-coordinate'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /i1*i10/<br /></span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">j </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'grid y-coordinate'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /j1*j10/<br /></span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">edges(i,j,i,j)
</span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'connects two points'<br /></span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">squares(i,j)
</span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'numbering of squares'<br /></span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">semap(i,j,i,j,i,j)
</span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'map between squares and edges'<br /></span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">c </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'colors'</span><span style="font-family: Consolas; font-size: 10.5pt;"><span style="color: #007400;"> /red,green,blue/<br /></span></span><span style="font-family: Consolas; font-size: 10.5pt;">;<br /></span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;"><br />alias</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> (i,ii),(j,jj);<br /></span><span style="font-family: Consolas; font-size: 10.5pt;"><span style="color: #d4d4d4;"> <br /></span></span><span style="font-family: Consolas; font-size: 10.5pt;">edges(i,j,i+1,j) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">yes</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;<br /></span><span style="font-family: Consolas; font-size: 10.5pt;">edges(i,j,i,j+1) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">yes</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;<br /></span><span style="font-family: Consolas; font-size: 10.5pt;"><span style="color: #d4d4d4;"> <br /></span></span><span style="font-family: Consolas; font-size: 10.5pt;">squares(i-1,j-1) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">yes</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;<br /></span><span style="font-family: Consolas; font-size: 10.5pt;"><br />semap(squares(i,j),edges(i,j,ii,jj))
= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">yes</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;<br /></span><span style="font-family: Consolas; font-size: 10.5pt;">semap(squares(i,j),edges(ii,jj,i+1,j+1))
= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">yes</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="font-family: Consolas; font-size: 10.5pt;"><span style="color: #d4d4d4;"> <br /></span></span><span style="font-family: Consolas; font-size: 10.5pt;"><span style="color: #d4d4d4;"><br /></span><span style="color: #0000b3;"><b>option</b></span></span><span style="font-family: Consolas; font-size: 10.5pt;"> edges:0:0:8,semap:0:0:6;<br /></span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> i,j,edges,squares,semap;</span></p>
</td>
</tr>
</tbody></table><br /><div><br /></div><div>There are many ways to do this. Here is one. Each grid point is resented by its \(x\) and \(y\) coordinate, here denoted by \((i,j)\). Edges connect two points, so we get \((i,j,i',j')\) to represent \((i,j) \rightarrow (i',j')\). We only need two edges leaving for each point: one to the right and one to above. This is done by:</div><div><br /></div><div><span style="font-family: Consolas; font-size: 10.5pt;"></span></div><blockquote><div><span style="font-family: Consolas; font-size: 10.5pt;">edges(i,j,i+1,j) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">yes</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;</span></div><span style="font-family: Consolas; font-size: 10.5pt;">edges(i,j,i,j+1) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">yes</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;</span></blockquote><p>When we display this (for a smaller example) we see:</p><p><br /></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">31</span> SET <span style="color: #007020;"><b>i</b></span> <i>grid x<span style="color: #333333;">-</span>coordinate</i>
i1, i2, i3
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">31</span> SET <span style="color: #007020;"><b>j</b></span> <i>grid y<span style="color: #333333;">-</span>coordinate</i>
j1, j2, j3
<span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">31</span> SET <b>edges</b> <i>connects two points</i>
i1.j1.i1.j2, i1.j1.i2.j1, i1.j2.i1.j3, i1.j2.i2.j2, i1.j3.i2.j3, i2.j1.i2.j2, i2.j1.i3.j1, i2.j2.i2.j3
i2.j2.i3.j2, i2.j3.i3.j3, i3.j1.i3.j2, i3.j2.i3.j3
</pre></div>
<p><br /></p><p>I don't use a different numbering scheme for the squares but instead use the coordinates of the left-lower point. We drop the points on the right and upper edge of the grid. This is done by:</p><p><span style="font-family: Consolas; font-size: 10.5pt;"></span></p><blockquote><p><span style="font-family: Consolas; font-size: 10.5pt;">squares(i-1,j-1) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">yes</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;</span></p><p></p></blockquote><p>The tricky indexing removes the last row and column. The display confirms this:</p><p><br /></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">31</span> SET <b>squares </b><i>numbering of squares</i>
j1 j2
i1 YES YES
i2 YES YES
</pre></div>
<p><br /></p><p>I also want to map between squares \((i,j)\) and the corresponding four edges \((i',j')\rightarrow (i'',j'')\). So I generate this crazy 6-dimensional structure <b>semap </b>(for squares-edge map). A square \((i,j)\) has two edges leaving from \((i,j\)) and two edges arriving at \((i+1,j+1)\). That is what I use here:</p><p><span style="font-family: Consolas; font-size: 10.5pt;"></span></p><blockquote><span style="font-family: Consolas; font-size: 10.5pt;">semap(squares(i,j),edges(i,j,ii,jj)) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">yes</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;<br /></span><span style="font-family: Consolas; font-size: 10.5pt;">semap(squares(i,j),edges(ii,jj,i+1,j+1)) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">yes</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;</span></blockquote><p>I could have dropped the word <b>edges</b> here, as they don't filter anything out. I left it for clarity. </p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">31</span> SET <b>semap </b><i>map between squares and edges</i>
i1.j1.i1.j1.i1.j2, i1.j1.i1.j1.i2.j1, i1.j1.i1.j2.i2.j2, i1.j1.i2.j1.i2.j2, i1.j2.i1.j2.i1.j3, i1.j2.i1.j2.i2.j2
i1.j2.i1.j3.i2.j3, i1.j2.i2.j2.i2.j3, i2.j1.i2.j1.i2.j2, i2.j1.i2.j1.i3.j1, i2.j1.i2.j2.i3.j2, i2.j1.i3.j1.i3.j2
i2.j2.i2.j2.i2.j3, i2.j2.i2.j2.i3.j2, i2.j2.i2.j3.i3.j3, i2.j2.i3.j2.i3.j3
</pre></div>
<br /><br />Of course, this is just one possible approach. Another would be to use a one-dimensional numbering scheme for edges and squares. You still need to specify which edges are used by a square. <div><br /><h3 style="text-align: left;">Model</h3><br /><div>
The model itself is not super complicated. <div><br /></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0in 5.4pt 0in 5.4pt; mso-yfti-tbllook: 1184;">
<tbody><tr>
<td style="border: 1pt solid windowtext; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt; width: 535.1pt;" valign="top" width="713">
<p class="MsoNormal" style="background: white; line-height: 14.25pt; margin-bottom: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">*-------------------------------------------------<br /></span></i><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">* MIP model<br /></span></i><i><span style="font-family: Consolas; font-size: 10.5pt;"><span style="color: #787878;">*-------------------------------------------------<br /></span></span></i><span style="font-family: Consolas; font-size: 10.5pt;"><span style="color: #d4d4d4;"> <br /></span></span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">variables<br /></span></b><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">z </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'dummy objective'<br /></span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">x(i,j,i,j,c) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'edge
colors'<br /></span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">sqcol(i,j,c) </span><span style="font-family: Consolas; font-size: 10.5pt;"><span style="color: #0000da;">'square
colors'<br /></span></span><span style="font-family: Consolas; font-size: 10.5pt;">;<br /></span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">binary variable </span></b><span style="font-family: Consolas; font-size: 10.5pt;">x,sqcol;<br /></span><span style="font-family: Consolas; font-size: 10.5pt;"><span style="color: #d4d4d4;"> <br /></span></span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">Equations<br /></span></b><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">dummyobj<br /></span><span style="font-family: Consolas; font-size: 10.5pt;"> onecolor(i,j,i,j) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'an edge has exactly one color'<br /></span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">implication1(i,j,i,j,i,j,c) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'ecol(edge,c)=1 for any edge => sqcol(square,c)=1'<br /></span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">implication2(i,j,c) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'ecol(edge,c)=0 for all edges => sqcol(square,c)=0'<br /></span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">squarecolors(i,j) </span><span style="font-family: Consolas; font-size: 10.5pt;"><span style="color: #0000da;">'exactly
2 colors per square'<br /></span></span><span style="font-family: Consolas; font-size: 10.5pt;">;<br /></span><span style="font-family: Consolas; font-size: 10.5pt;"><span style="color: #d4d4d4;"> <br /></span></span><span style="font-family: Consolas; font-size: 10.5pt;">dummyobj.. z =e= 0;<br /></span><span style="font-family: Consolas; font-size: 10.5pt;"><span style="color: #d4d4d4;"> <br /></span></span><span style="font-family: Consolas; font-size: 10.5pt;">onecolor(edges).. </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(c, x(edges,c)) =e= 1;<br /></span><span style="font-family: Consolas; font-size: 10.5pt;">implication1(squares,edges,c)$semap(squares,edges)..
sqcol(squares,c) =g= x(edges,c);<br /></span><span style="font-family: Consolas; font-size: 10.5pt;">implication2(squares,c)..
sqcol(squares,c) =l= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(semap(squares,edges), x(edges,c));<br /></span><span style="font-family: Consolas; font-size: 10.5pt;">squarecolors(squares).. </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(c, sqcol(squares,c))
=e= 2;<br /></span><span style="font-family: Consolas; font-size: 10.5pt;"><span style="color: #d4d4d4;"> <br /></span></span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">model </span></b><span style="font-family: Consolas; font-size: 10.5pt;">coloring</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /all/</span><span style="font-family: Consolas; font-size: 10.5pt;">;<br /></span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">solve</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> coloring </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">using</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">mip</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">minimizing</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> z;</span></p>
</td>
</tr>
</tbody></table></div></div><br />We don't have an objective: we only need to find a feasible solution. In GAMS that means that we use a dummy objective.<div><br /></div><div>In the equations, I heavily use the sets <b>squares </b>and <b>edges</b>. This makes the equations simpler, but a little bit misleading. It looks like we have two-dimensional variables and equations, while, in fact, these are multi-dimensional structures. That can be seen in the declarations. Counting the colors in a square is done by two sets of implications:</div><div><ol style="text-align: left;"><li>If any of the edges has color \(c\), then the square includes color \(c\)</li><li>If all of the edges don't have color \(c\), then the square does not include color \(c\) </li></ol><div><br /></div></div><div>I ignore here the requirement "2 edges per color". </div><h3 style="text-align: left;"><br /></h3><h3 style="text-align: left;">Solution printing</h3><div><br /></div><div>A quick and dirty solution printout shows:</div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: #333333;">----</span> <span style="color: #0000dd; font-weight: bold;">77</span> PARAMETER <b>solution </b>
i1.j1.i1.j2 GREEN, i1.j1.i2.j1 GREEN, i1.j2.i1.j3 RED, i1.j2.i2.j2 RED, i1.j3.i2.j3 BLUE, i2.j1.i2.j2 RED
i2.j1.i3.j1 BLUE, i2.j2.i2.j3 BLUE, i2.j2.i3.j2 RED, i2.j3.i3.j3 RED, i3.j1.i3.j2 RED, i3.j2.i3.j3 RED
</pre></div>
<div><br /></div><div>This is only slightly better than just displaying variable <b>ecol</b>. It may be better to draw a picture. We can write some HTML and SVG to draw the grid and color the edges. For a 25x25 example, this can look like:</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEirBSI3X7MIKX1FTGJv-58K349nLHX5-o3dBFlPlypwumfWZebuNOdKMNRvQ8mkBKLWGW2H5NDUxjS4A_byxWZ6F2-_CPkt93IJ6Q0nIVNtU0mXaT3CjkVA2i7T_Z0cZ9t1NdHluHsFsMf1Xt5byXWJmBiRNsS1nVGiUZNGx-rOguShbAV-5Fk9DW71iozQ" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="765" data-original-width="762" src="https://blogger.googleusercontent.com/img/a/AVvXsEirBSI3X7MIKX1FTGJv-58K349nLHX5-o3dBFlPlypwumfWZebuNOdKMNRvQ8mkBKLWGW2H5NDUxjS4A_byxWZ6F2-_CPkt93IJ6Q0nIVNtU0mXaT3CjkVA2i7T_Z0cZ9t1NdHluHsFsMf1Xt5byXWJmBiRNsS1nVGiUZNGx-rOguShbAV-5Fk9DW71iozQ=s16000" /></a></div><br />A little bit of a low-tech solution: just write out the HTML using the PUT statement. However, it is difficult to beat the simplicity of this approach.</div><div><br /></div><div>We can solve even a 100x100 grid very quickly (0.89 seconds to find a feasible integer solution). The picture becomes a bit difficult to grasp.</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjIsL5oqhffh04aAt8gq2fNPVHW4VdX4bIqmSx_PkpvVIH-q4gAyoLYJt_SBatW0gJKrIGMeF_OtZhRoLbzI1cAhw1XEQLev4YybrZy84WomDOrE8ttnV5NloGpzMbtANODn1C9vAMEG2xfN6WMl87tyl_vQy4Swai0LzdeqGicKeOPszg6rToNkniNAHSM" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="1265" data-original-width="1605" height="504" src="https://blogger.googleusercontent.com/img/a/AVvXsEjIsL5oqhffh04aAt8gq2fNPVHW4VdX4bIqmSx_PkpvVIH-q4gAyoLYJt_SBatW0gJKrIGMeF_OtZhRoLbzI1cAhw1XEQLev4YybrZy84WomDOrE8ttnV5NloGpzMbtANODn1C9vAMEG2xfN6WMl87tyl_vQy4Swai0LzdeqGicKeOPszg6rToNkniNAHSM=w640-h504" width="640" /></a></div><br /><br /><h3 style="text-align: left;">2-edges per color</h3></div><div><br /></div><div>If you want to use 2 edges per color we need to say actually </div><div><br /></div><div><span> </span>the number of edges in a square with color \(c\) is 0 or 2.</div><div><br /></div><div>This can be modeled with a binary variable multiplied by 2. I.e.:</div><div><br /></div><div><br /></div><div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #0000b3;"><strong>binary </strong></span><span style="color: #0000b3;"><strong>variables </strong></span><span style="color: black;">ZeroOrTwo</span><span style="color: black;">(i,j,c</span><span style="color: black;">) </span><span style="color: #0000da;">'zero or two edges per color'</span><span style="color: black;">;</span><span style="color: black;"></span></div><div><span style="color: #0000b3;"><strong>equation </strong></span><span style="color: black;">squareColors2</span><span style="color: black;">(i,j,c</span><span style="color: black;">) </span><span style="color: #0000da;">'exactly 2 colors per square, and two edges per color'</span><span style="color: black;">;</span></div><div><span style="color: black;"></span></div><div><span style="color: black;">squareColors2(squares,c)</span><span style="color: black;">..</span><span style="color: black;"> </span><span style="color: #0000b3;"><strong>sum</strong></span><span style="color: black;">(semap(squares,edges),x(edges,c)) =e= 2*ZeroOrTwo(squares,c)</span><span style="color: black;">;</span></div><div><span style="color: black;"></span></div><div></div></div><div style="text-align: left;"><br /></div><div style="text-align: left;">This constraint implies that only 2 colors are used for the four edges for each square. So this replaces the three constraints <b>implication1</b>, <b>implication2</b>, <b>SquareColors </b>in the previous model. I.e. we added extra binary variables, but the number of constraints and their complexity decreases. </div><div style="text-align: left;"><br /></div><div style="text-align: left;">This is called Model 2 in the GAMS code.</div><div style="text-align: left;"><br /></div><div style="text-align: left;">When I run this, we see for the 25x25 problem:</div><div style="text-align: left;"><br /></div><div style="text-align: left;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjMibj_0dG4yvqT_mhXJzX0oprqFyJveHhXYdIDlTq3A2KEvxsoOj2Hl85mFVKUtQzbAM4vd4M4sntBRhnVoN_6c14fmq7-oVyBkrgkuQl9zaGs-GGbQ4WUoupX2dVEdM67yg0krJjY3mwQx8yRO2FGMi5ttgDW-9g-gu0FwOXSdDqM7yFXn1qFHWIa7oLn" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="966" data-original-width="963" src="https://blogger.googleusercontent.com/img/a/AVvXsEjMibj_0dG4yvqT_mhXJzX0oprqFyJveHhXYdIDlTq3A2KEvxsoOj2Hl85mFVKUtQzbAM4vd4M4sntBRhnVoN_6c14fmq7-oVyBkrgkuQl9zaGs-GGbQ4WUoupX2dVEdM67yg0krJjY3mwQx8yRO2FGMi5ttgDW-9g-gu0FwOXSdDqM7yFXn1qFHWIa7oLn=s16000" /></a></div><div style="text-align: left;"><br /></div>This model is more difficult. The 25x25 case solves fast, but the 100x100 case takes a while (I never finished it).<br /><br /></div><h3 style="text-align: left;">A faster 100x100 model</h3><div><br /></div><div>One rule in MIP modeling is: never give up. The previous attempt at solving the 100x100 problem with the 2 edges per color constraint was not very successful. A variant of the model uses the constraints of model 1 and model 2. We just say:</div><div><br /></div><div><div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><div><span style="color: #0000b3;"><strong>model </strong></span><span style="color: black;">coloring3</span><span style="color: #007400;"> /</span><span style="color: #007400;">all</span><span style="color: #007400;">/</span><span style="color: black;">;</span><span style="color: black;"></span></div><div><span style="color: #0000b3;"><strong>solve</strong></span><span style="color: black;"> coloring3 </span><span style="color: #0000b3;"><strong>using</strong></span><span style="color: black;"> </span><span style="color: #0000b3;"><strong>mip</strong></span><span style="color: black;"> </span><span style="color: #0000b3;"><strong>minimizing</strong></span><span style="color: black;"> z</span><span style="color: black;">;</span><span style="color: black;"></span></div><div></div></div></div><div style="text-align: left;"><br /></div><div style="text-align: left;">Somehow this is very fast.</div><div style="text-align: left;"><br /></div><div style="text-align: left;">This model produces a rather regular picture:</div><div style="text-align: left;"><br /></div><div style="text-align: left;"><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEh05V3iOnQOl_bKG9ug88zaZlN-Hf_QdJnAO76Nfw_7htwgQafYXSyzAsETV-g1enjCQUDlwCR_dPSu9_-NSWJCOrCOhjA8FHpmWK2v88i5l3bpz5oYGjQ1vovnvdxP-utSgd95FHVrArR9rYG88Mo7rsyx4_RQxdHxmh13_IFtYD6zYSqeWRpHeeLWHzPM" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="761" data-original-width="762" src="https://blogger.googleusercontent.com/img/a/AVvXsEh05V3iOnQOl_bKG9ug88zaZlN-Hf_QdJnAO76Nfw_7htwgQafYXSyzAsETV-g1enjCQUDlwCR_dPSu9_-NSWJCOrCOhjA8FHpmWK2v88i5l3bpz5oYGjQ1vovnvdxP-utSgd95FHVrArR9rYG88Mo7rsyx4_RQxdHxmh13_IFtYD6zYSqeWRpHeeLWHzPM=s16000" /></a></div><div style="text-align: left;"><br /></div>This picture is for the 25x25 case, but it is similar for the 100x100 case.<br /><br />It is interesting that combining models 1 and 2 produces faster results than just model 2.<br /><br /></div><h3 style="text-align: left;">Counting solutions</h3><div style="text-align: left;"><br /></div><div style="text-align: left;">The original post asked for the total number of solutions. When throwing this model (just 4x4 grid) at the solution pool I see:</div><div style="text-align: left;"><br /></div><div></div><blockquote><div>--- Cplex Time: 5.94sec (det. 4774.48 ticks)</div><div>--- Dumping 373248 solutions from the solution pool...</div><div style="text-align: left;"> </div></blockquote><p>For a 4x5 grid this becomes:</p><p><br /></p><p></p><blockquote><p>--- Cplex Time: 440.67sec (det. 167328.64 ticks)<br />--- Dumping 8957952 solutions from the solution pool... </p><p></p></blockquote><p><br /></p><div style="text-align: left;"></div><div style="text-align: left;">Obviously, there are way too many solutions to answer this question by a numerical algorithm for a larger grid. This may not be such an interesting question.</div><div style="text-align: left;"> </div><h3 style="text-align: left;">Conclusion</h3></div><div><br /></div><div>The model is interesting because of its data structures and indexing techniques. Using sparse multi-dimensional sets, we can populate somewhat complex sets in just a few lines while still being understandable. This would be done very differently in, say, a Python environment. This is a good example where a line-by-line translation does not really work.</div><div><br /></div><div>A second feature is that I use multi-dimensional sets to simplify the constraints. Constraints are often the most difficult to debug, so making them as simple as possible is beneficial. </div><div><br /></div><div>Finally, I used some HTML to visualize the solution. Clearly, that is useful up to a point.</div><div><br /></div><h3 style="text-align: left;">References</h3><div><br /></div><div><ol style="text-align: left;"><li>Given an m * n grid, each edge must be colored. However, there are constraints, <a href="https://stackoverflow.com/questions/76645751/given-an-m-n-grid-each-edge-must-be-colored-however-there-are-constraints">https://stackoverflow.com/questions/76645751/given-an-m-n-grid-each-edge-must-be-colored-however-there-are-constraints</a></li></ol><div><br /></div></div><h3 style="text-align: left;">Appendix: complete GAMS model </h3><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 823.1pt;" valign="top" width="1097"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$<span class="SpellE">ontext</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> Color edges of a grid.</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> From https://stackoverflow.com/questions/76645751/given-an-m-n-grid-each-edge-must-be-colored-however-there-are-constraints</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> Given an m * n grid, each edge must be colored. However, there are 2 constraints:</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> 1. Entire grid must use only 3 unique colors</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> 2. Each square in the grid must be colored using exactly 2 colors (2 edges per color)</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">Model 1: forget 2 edges per <span class="GramE">color</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">Model 2: <span class="GramE">add 2</span> edges per color</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">Model 3: combine models 1 and <span class="GramE">2</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;"> </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$<span class="SpellE">offText</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*-------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">sets</span> to represent grid and edges.</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">representation</span> of squares is by left-lower point</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*-------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">set</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">i</span></span><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'grid x-coordinate<span class="GramE">'<span style="color: #007400;"> /</span></span></span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">i1*i10/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">j </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'grid y-coordinate<span class="GramE">'<span style="color: #007400;"> /</span></span></span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">j1*j10/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">edges(<span class="SpellE"><span class="GramE">i,j</span>,i,j</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'connects two points'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">squares(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'numbering of squares'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">semap</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span>,i,j,i,j</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'map between squares and edges'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">c </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'colors'</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /<span class="SpellE"><span class="GramE">red,green</span>,blue</span>/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">alias</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> (<span class="SpellE"><span class="GramE">i,ii</span></span>),(<span class="SpellE">j,jj</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">edges(<span class="GramE">i,j</span>,i+1,j) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">yes</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">edges(<span class="GramE">i,j</span>,i,j+1) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">yes</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">squares(i-<span class="GramE">1,j</span>-1) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">yes</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">semap</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(squares(<span class="SpellE"><span class="GramE">i,j</span></span>),edges(<span class="SpellE">i,j,ii,jj</span>)) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">yes</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">semap</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(squares(<span class="SpellE"><span class="GramE">i,j</span></span>),edges(ii,jj,i+1,j+1)) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">yes</span></b><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">option</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">edges:0:0:8</span>,semap:0:0:6;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE"><span class="GramE">i,j</span>,edges,squares,semap</span>;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*-------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* MIP model 1</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">ignore</span> two edges per color in a square</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*-------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">variables</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">z </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'dummy objective'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">x(<span class="SpellE"><span class="GramE">i,j</span>,i,j,c</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'edge colors'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">sqCol</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span>,c</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'square colors'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">binary variable </span></b><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">x,sqCol</span></span></span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">Equations</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">dummyObj</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="SpellE">oneColor</span>(<span class="SpellE"><span class="GramE">i,j</span>,i,j</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'an edge has exactly one color'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">implication1(<span class="SpellE"><span class="GramE">i,j</span>,i,j,i,j,c</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'<span class="SpellE">ecol</span>(<span class="SpellE">edge,c</span>)=1 for any edge => <span class="SpellE">sqcol</span>(<span class="SpellE">square,c</span>)=1'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">implication2(<span class="SpellE"><span class="GramE">i,j</span>,c</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'<span class="SpellE">ecol</span>(<span class="SpellE">edge,c</span>)=0 for all edges => <span class="SpellE">sqcol</span>(<span class="SpellE">square,c</span>)=0'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">squareColors</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'exactly 2 colors per square'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">dummyobj</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">..</span></span><span style="font-family: Consolas; font-size: 10.5pt;"> z =e= <span class="GramE">0;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">onecolor</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span style="font-family: Consolas; font-size: 10.5pt;">edges).. </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span style="font-family: Consolas; font-size: 10.5pt;">c, x(<span class="SpellE">edges,c</span>)) =e= 1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">implication1(<span class="SpellE"><span class="GramE">squares,edges</span>,c</span>)$<span class="SpellE">semap</span>(<span class="SpellE">squares,edges</span>).. <span class="SpellE">sqcol</span>(<span class="SpellE"><span class="GramE">squares,c</span></span>) =g= x(<span class="SpellE">edges,c</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">implication2(<span class="SpellE"><span class="GramE">squares,c</span></span>).. <span class="SpellE">sqcol</span>(<span class="SpellE"><span class="GramE">squares,c</span></span>) =l= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">semap</span>(<span class="SpellE">squares,edges</span>), x(<span class="SpellE">edges,c</span>));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">squarecolors</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span style="font-family: Consolas; font-size: 10.5pt;">squares).. </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span style="font-family: Consolas; font-size: 10.5pt;">c, <span class="SpellE">sqcol</span>(<span class="SpellE">squares,c</span>)) =e= 2;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">model </span></b><span style="font-family: Consolas; font-size: 10.5pt;">coloring1</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /all<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">solve</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> coloring1 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">using</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">mip</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">z;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*-------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* MIP model 2</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">add</span> two edges per color in a square</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*-------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">binary variables </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 10.5pt;">ZeroOrTwo</span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE"><span class="GramE">i,j</span>,c</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'zero or two edges per color'</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">equation </span></b><span style="font-family: Consolas; font-size: 10.5pt;">squareColors2(<span class="SpellE"><span class="GramE">i,j</span>,c</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt;">'exactly 2 colors per square, and two edges per color'</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">squareColors2(<span class="SpellE"><span class="GramE">squares,c</span></span>).. </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">sum</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">semap</span>(<span class="SpellE"><span class="GramE">squares,edges</span></span>),x(<span class="SpellE">edges,c</span>)) =e= 2*<span class="SpellE">ZeroOrTwo</span>(<span class="SpellE">squares,c</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">model </span></b><span style="font-family: Consolas; font-size: 10.5pt;">coloring2</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /<span class="GramE">dummyObj,oneColor</span>,squareColors2/</span><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">option</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">threads</span></b><span style="font-family: Consolas; font-size: 10.5pt;">=<span class="GramE">0;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*<span class="GramE">solve</span> coloring2 using <span class="SpellE">mip</span> minimizing z;</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*-------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* MIP model 3</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">add</span> two edges per color in a square</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*-------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">model </span></b><span style="font-family: Consolas; font-size: 10.5pt;">coloring3</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /all<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*<span class="GramE">solve</span> coloring3 using <span class="SpellE">mip</span> minimizing z;</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*-------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">print</span> solution</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*-------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">acronym</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">RED,GREEN</span>,BLUE;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">parameter</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;"> </span></b><span style="font-family: Consolas; font-size: 10.5pt;">col(c)</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> / <span class="GramE">red <span class="SpellE"><span style="color: #005078;">RED</span></span></span>, green </span><span class="SpellE"><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">GREEN</span></span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">, blue </span><span style="color: #005078; font-family: Consolas; font-size: 10.5pt;">BLUE</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> </span><span style="font-family: Consolas; font-size: 10.5pt;">solution(<span class="SpellE"><span class="GramE">i,j</span>,i,j</span>)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">loop</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(</span></span><span style="font-family: Consolas; font-size: 10.5pt;">c,</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;"> solution(edges)$(<span class="SpellE">x.l</span>(<span class="SpellE"><span class="GramE">edges,c</span></span>)>0.5) = col(c);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">option</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">solution:0:0:8</span>;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">display</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">solution;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*-------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">* <span class="GramE">draw</span> solution</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 10.5pt;">*-------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">file </span></b><span style="font-family: Consolas; font-size: 10.5pt;">f</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;"> /solution.html<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">put</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> <span class="GramE">f;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">put</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">'<<span class="SpellE">svg</span> width=800 height=800 <span class="SpellE">viewbox</span> = "0 0 <span class="GramE">'<span style="color: black;">,(</span></span></span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">card</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>)+1):0:0,</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">' '</span><span style="font-family: Consolas; font-size: 10.5pt;">,(</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">card</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(j)+1):0:0,</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">'">'</span><span style="font-family: Consolas; font-size: 10.5pt;">/;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">loop</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(edges(<span class="SpellE"><span class="GramE">i,j</span>,ii,jj</span>),</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">loop</span></b><span style="font-family: Consolas; font-size: 10.5pt;">(c$(<span class="SpellE">x.l</span>(<span class="SpellE"><span class="GramE">edges,c</span></span>)>0.5),</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">put</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">'<line x1=<span class="GramE">'<span style="color: black;">,</span><span class="SpellE"><b><span style="color: #0000b3;">ord</span></b></span></span></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">i</span>):0:0,</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">' x2='</span><span style="font-family: Consolas; font-size: 10.5pt;">,</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">ord</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(ii):0:0,</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">' y1='</span><span style="font-family: Consolas; font-size: 10.5pt;">,</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">ord</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(j):0:0,</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">' y2='</span><span style="font-family: Consolas; font-size: 10.5pt;">,</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">ord</span></b></span><span style="font-family: Consolas; font-size: 10.5pt;">(<span class="SpellE">jj</span>):0:0,</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">' stroke="'</span><span style="font-family: Consolas; font-size: 10.5pt;">,c.tl:0,</span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">'" stroke-width="0.07"/>'</span><span style="font-family: Consolas; font-size: 10.5pt;">/;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;"> )</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 10.5pt;">)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">put</span></b><span style="font-family: Consolas; font-size: 10.5pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">'</<span class="SpellE">svg</span>>'</span><span class="GramE"><span style="font-family: Consolas; font-size: 10.5pt;">/;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 10.5pt;">execute </span></b><span style="color: #007400; font-family: Consolas; font-size: 10.5pt;">"<span class="SpellE">shellexecute</span> solution.html<span class="GramE">"<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt;"><o:p></o:p></span></p><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><o:p> </o:p></p></td></tr></tbody></table><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.4px; margin: 0in 0in 8pt;"><o:p> </o:p></p></div></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com3tag:blogger.com,1999:blog-593563533834706486.post-28959860810816058822023-07-06T12:21:00.002-04:002023-08-30T14:07:32.750-04:00A Julia thingy<p> In Julia, we can write 2x instead of 2*x. Not the most earth-shattering. But a bit special nonetheless.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgn8pT4agc8J7pZbq0dSCAalEaJWwSQYVatkE9ibBlbZ2KQenRbEb2w_iQNLkQBdWAThpt1gf2TjwP8ewtv3gdA39xj0tgnFsNU7_c7kmjzkg39r2z-qwmKV0bprCw77F_FcN7ISLMRJl8bOVe0nKTgj2ZVOW9oOZIyy7IJ-B0SiUQ-31KnEa-3BzKaQZVb" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="1085" data-original-width="996" src="https://blogger.googleusercontent.com/img/a/AVvXsEgn8pT4agc8J7pZbq0dSCAalEaJWwSQYVatkE9ibBlbZ2KQenRbEb2w_iQNLkQBdWAThpt1gf2TjwP8ewtv3gdA39xj0tgnFsNU7_c7kmjzkg39r2z-qwmKV0bprCw77F_FcN7ISLMRJl8bOVe0nKTgj2ZVOW9oOZIyy7IJ-B0SiUQ-31KnEa-3BzKaQZVb=s16000" /></a></div><br /><br /><p></p><p>The expression in the last cell is interpreted as a function call.</p>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com0tag:blogger.com,1999:blog-593563533834706486.post-80457680663333618362023-07-02T17:59:00.003-04:002023-08-04T02:37:52.561-04:00Some confusion here<p>Sometimes you end up visiting strange sites. This is a question & answer site. The question is:</p><p><br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjVreb7TqrT0Uve7p9AWoOziV_FV9bZwRaIr1jcyjHv8-w9EmuYgc7bF7bOwnqLcoVlEQ1EcXD3xlgcAtwIB3EBEAZGTA3c1ZQa2TIxOs7sVRl4CmaEu3_ogvD3NWa6Fxay4Sr3hajx4aENiweuLlT67ElcqGA2dW_gbu_RZaRGAP9chhHTWcvc9Pn2n-HH" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="298" data-original-width="687" src="https://blogger.googleusercontent.com/img/a/AVvXsEjVreb7TqrT0Uve7p9AWoOziV_FV9bZwRaIr1jcyjHv8-w9EmuYgc7bF7bOwnqLcoVlEQ1EcXD3xlgcAtwIB3EBEAZGTA3c1ZQa2TIxOs7sVRl4CmaEu3_ogvD3NWa6Fxay4Sr3hajx4aENiweuLlT67ElcqGA2dW_gbu_RZaRGAP9chhHTWcvc9Pn2n-HH=s16000" /></a></div><br />Obviously, this is not a good question. It is something like "<i>what is the difference between a ham sandwich and butter?</i>".<p></p><p>The answers are not so good either. </p><span><a name='more'></a></span><p><br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEgAj9KLJjb2LeUdq_oDcQtAE02eka6E_t8bNiT8sXV3WlD9HcP92nj8Rj4wY-d8aOUu5BqWEomlIZYLBERgrVy8p40mvOxri61_LIHGLNroads_Q5xFXmkBxE5VHrN1mbF8_JUnXkgIMnb-KvNyx_1Cx16lJp_lmYpadOgp89Y4G5a0u0QPCD8SbAYqj1ef" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="568" data-original-width="675" src="https://blogger.googleusercontent.com/img/a/AVvXsEgAj9KLJjb2LeUdq_oDcQtAE02eka6E_t8bNiT8sXV3WlD9HcP92nj8Rj4wY-d8aOUu5BqWEomlIZYLBERgrVy8p40mvOxri61_LIHGLNroads_Q5xFXmkBxE5VHrN1mbF8_JUnXkgIMnb-KvNyx_1Cx16lJp_lmYpadOgp89Y4G5a0u0QPCD8SbAYqj1ef=s16000" /></a></div><br /><br /><p></p><p>"Simple X"? Spelled like this, one would suspect that any method is more advanced. However, big-M is not a replacement for the Simplex method. It is just a simple modeling trick to handle models with an infeasible starting basis. Big-M methods are not used in practice. (Note that there is also a big-M concept in integer programming. There it is used to model implications with binary variables.)</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEghQ9iqDq9T-b5nEojq9EsrwfThb2GZXHdYnnVDg3GyGNzxS-1obUynUVWxj8RYDA-Pn4wxBgPfPaqMxmRJJiJtdiRTjhXH0yUPH3ihU9dD4sLLSdYy22suy2UK8qyGpX0CWPRC2DeHDFbhOewrnpTwRz9YW2xktenJrCwO3cXMD1gGt8aofFtD8WYbedZv" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="643" data-original-width="694" src="https://blogger.googleusercontent.com/img/a/AVvXsEghQ9iqDq9T-b5nEojq9EsrwfThb2GZXHdYnnVDg3GyGNzxS-1obUynUVWxj8RYDA-Pn4wxBgPfPaqMxmRJJiJtdiRTjhXH0yUPH3ihU9dD4sLLSdYy22suy2UK8qyGpX0CWPRC2DeHDFbhOewrnpTwRz9YW2xktenJrCwO3cXMD1gGt8aofFtD8WYbedZv=s16000" /></a></div><br />Here is the "expert-verified answer." Basically, the same answer. "Big m" is usually spelled big-M (the M is big).<p></p><p>When I paste the question into ChatGPT, I get a better answer: <a href="https://chat.openai.com/share/f4baca78-f1d7-476f-8cf5-a5ad278ff036">https://chat.openai.com/share/f4baca78-f1d7-476f-8cf5-a5ad278ff036</a>. Not perfect by any means. E.g. the sentence:</p><p><span face="Söhne, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"" style="background-color: #f7f7f8; color: #374151; font-size: 16px; white-space-collapse: preserve;">While the Big M method is a viable approach, the simplex method is typically preferred due to its efficiency and robustness.</span></p><p>is not correct. This sentence is about the Simplex Method + Big-M vs the Simplex Method + two-phase approach.</p>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com2tag:blogger.com,1999:blog-593563533834706486.post-52964865375598019422023-06-27T04:27:00.012-04:002023-08-30T14:06:57.261-04:00CVXPY DCP errors<script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 80%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style>CVXPY is a popular tool to model and solve convex optimization problems. Sometimes, it throws a "DCP" error, even for convex problems. DCP stands for Disciplined Convex Programming, the underlying framework for working with guaranteed convex models. The error says: I can not verify this is convex. <div><br /></div><div>Here are some small examples of convex objectives (under minimization) one would expect to work.</div><div><br /></div><div><br /></div>
<table class="blueTable">
<thead><tr><th>Objective</th><th>CVXPY code</th><th>Result</th><th>Notes</th></tr></thead>
<tbody>
<tr><td>\[\color{darkred}x^T \color{darkred}x\]</td><td style="text-align: center;"><span style="font-family: courier;">x.T@x</span></td><td>DCP error</td><td>print shows <span style="font-family: courier;">minimize x@x</span><span style="font-family: inherit;">, i.e. transpose is dropped</span></td></tr>
<tr><td>\[\color{darkred}x^T \color{darkred}x\]</td><td style="text-align: center;"><span style="font-family: courier;">x@x</span></td><td>DCP error</td><td></td></tr>
<tr><td>\[\color{darkred}x^T \color{darkred}x\]</td><td style="text-align: center;"><span style="font-family: courier;">cp.sum_squares(x)</span></td><td></td><td>transformed into <span style="font-family: courier;">quad_over_lin(x, 1.0)</span></td></tr>
<tr><td>\[\color{darkred}x^T \color{darkblue}Q \color{darkred}x\]</td><td style="text-align: center;"><span style="font-family: courier;">x.T@Q@x</span></td><td></td><td>transformed into <span style="font-family: courier;">QuadForm(x,Q)</span></td></tr>
<tr><td>\[\color{darkred}y:=\color{darkred}x-\color{darkblue}p\]\[\color{darkred}x^T \color{darkblue}Q \color{darkred}y\]</td><td style="text-align: center;"><span style="font-family: courier;">y=x-p<br />x.T@Q@y</span></td><td>DCP error</td><td></td></tr>
<tr><td>\[\color{darkred}x^T \color{darkblue}Q \color{darkred}x - \color{darkred}x^T \color{darkblue}Q \color{darkblue}p\]</td><td style="text-align: center;"><span style="font-family: courier;">x.T@Q@x - x.T@Q@p</span></td><td></td><td>first term transformed into <span style="font-family: courier;">QuadForm(x,Q)</span> </td></tr>
</tbody>
</table><br />
<div>Not everything makes sense to me. I am not sure why <span style="font-family: courier; text-align: center;">x.T@x</span> is not properly recognized, but <span style="font-family: courier; text-align: center;">x.T@Q@x</span> is.</div><div><br /></div><div><span><a name='more'></a></span>Here is the code I used for experimentation:</div><div><br /></div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="background-color: white; color: #008800; font-weight: bold;">import</span><span style="background-color: white;"> </span><span style="background-color: white; color: #0e84b5; font-weight: bold;">cvxpy</span><span style="background-color: white;"> </span><span style="background-color: white; color: #008800; font-weight: bold;">as</span><span style="background-color: white;"> </span><span style="background-color: white; color: #0e84b5; font-weight: bold;">cp</span><span style="background-color: white;">
</span><span style="background-color: white; color: #008800; font-weight: bold;">import</span><span style="background-color: white;"> </span><span style="background-color: white; color: #0e84b5; font-weight: bold;">numpy</span><span style="background-color: white;"> </span><span style="background-color: white; color: #008800; font-weight: bold;">as</span><span style="background-color: white;"> </span><span style="background-color: white; color: #0e84b5; font-weight: bold;">np</span><span style="background-color: white;">
n </span><span style="background-color: white; color: #333333;">=</span><span style="background-color: white;"> </span><span style="background-color: white; color: #0000dd; font-weight: bold;">5</span><span style="background-color: white;">
x </span><span style="background-color: white; color: #333333;">=</span><span style="background-color: white;"> cp</span><span style="background-color: white; color: #333333;">.</span><span style="background-color: white;">Variable(n, </span><span style="background-color: #fff0f0;">"x"</span><span style="background-color: white;">, nonneg</span><span style="background-color: white; color: #333333;">=</span><span style="background-color: white; color: #008800; font-weight: bold;">True</span><span style="background-color: white;">)
Q </span><span style="background-color: white; color: #333333;">=</span><span style="background-color: white;"> np</span><span style="background-color: white; color: #333333;">.</span><span style="background-color: white;">eye(n)
p </span><span style="background-color: white; color: #333333;">=</span><span style="background-color: white;"> np</span><span style="background-color: white; color: #333333;">.</span><span style="background-color: white;">ones(n)
obj </span><span style="background-color: white; color: #333333;">=</span><span style="background-color: white;"> x</span><span style="background-color: white; color: #333333;">.</span><span style="background-color: white;">T @ </span><span style="background-color: white;">x </span><span style="background-color: white; color: #888888;"># not DCP ??? Print says x @ x</span><span style="background-color: white;">
</span><span style="background-color: white; color: #888888;">#obj = x @ x # not DCP</span><span style="background-color: white;">
</span><span style="background-color: white; color: #888888;">#obj = cp.sum_squares(x) # transformed into quad_over_lin(x, 1.0)</span><span style="background-color: white;">
</span><span style="background-color: white; color: #888888;">#obj = x.T @ Q @ x # transformed into QuadForm(x,Q)</span><span style="background-color: white;">
y </span><span style="background-color: white; color: #333333;">=</span><span style="background-color: white;"> x</span><span style="background-color: white; color: #333333;">-</span><span style="background-color: white;">p
</span><span style="background-color: white; color: #888888;">#obj = x.T @ Q @ y # not DCP</span><span style="background-color: white;">
</span><span style="background-color: white; color: #888888;">#obj = x.T @ Q @ x - x.T @ Q @ p # accepted</span><span style="background-color: white;">
prob </span><span style="background-color: white; color: #333333;">=</span><span style="background-color: white;"> cp</span><span style="background-color: white; color: #333333;">.</span><span style="background-color: white;">Problem(cp</span><span style="background-color: white; color: #333333;">.</span><span style="background-color: white;">Minimize(obj), [</span><span style="background-color: white; color: #007020;">sum</span><span style="background-color: white;">(x)</span><span style="background-color: white; color: #333333;">==</span><span style="background-color: white; color: #0000dd; font-weight: bold;">1</span><span style="background-color: white;">])
</span><span style="background-color: white; color: #007020;">print</span><span style="background-color: white;">(prob)
result </span><span style="background-color: white; color: #333333;">=</span><span style="background-color: white;"> prob</span><span style="background-color: white; color: #333333;">.</span><span style="background-color: white;">solve(verbose</span><span style="background-color: white; color: #333333;">=</span><span style="background-color: white; color: #008800; font-weight: bold;">True</span><span style="background-color: white;">)
</span></pre></div>
<br />We can use: <span style="font-family: courier;">x = cp.Variable((n,1), "x", nonneg=True)</span>. This would generate an \((n\times 1)\) matrix. The printed model now shows the correct objective (with the transpose): <span style="font-family: courier;">minimize x.T @ x</span>. But still, we are getting:<div><br /></div><div></div><blockquote><div>DCPError: Problem does not follow DCP rules. Specifically:</div><div>The objective is not DCP. Its following subexpressions are not:</div><div>x.T @ x </div></blockquote><p>I suspect this is interpreted as \(\color{darkred}x^T\color{darkred}y\), i.e., as two possibly different vectors. Just a guess. Of course, the workarounds are obvious: use <span style="font-family: courier;">cp.sum_squares(x)</span>, or use \(\color{darkred}x^T \color{darkblue}I \color{darkred}x\). I think, not being able to recognize \(\color{darkred}x^T\color{darkred}x\) as convex, can be classified as a bug.</p><div></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com0tag:blogger.com,1999:blog-593563533834706486.post-64219726610364525012023-05-10T13:56:00.009-04:002023-05-11T14:29:14.957-04:00Generate all solutions that sum up to one <script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style><p>In a post, the following question was posed:</p><blockquote><p>We can select unique values \(\displaystyle\frac{1}{i}\) for \(i=1,\dots,n\). Find all combinations that add up to 1.</p></blockquote><p>A complete enumeration scheme was slow even for \(n=10\). Can we use a MIP model for this or something related?</p><p>A single solution is easily found using the model:</p><p><br /></p>
<table class="blueTable">
<thead><tr><th>Mathematical Model</th></tr></thead>
<tbody><tr><td>\[
\begin{align}
& \sum_{i=1}^n \frac{1}{i} \cdot \color{darkred}x_i = 1 \\
& \color{darkred}x_i \in \{0,1\}
\end{align}\]</td></tr></tbody>
</table><br />
<span><a name='more'></a></span><div><br /></div><div>As MIP solvers use all kinds of tolerances, we can only increase \(n\) to some reasonable number (maybe 100, or 1000). After that, the coefficients \(1/i\) become likely too small. </div><div><br /></div><div>This model in itself is not so interesting, but the task of generating all feasible solutions makes it worth some attention.</div><div><br /></div><div>There are basically three approaches for generating all feasible solutions:</div><div><ul style="text-align: left;"><li>Use a <b>Constraint Programming </b>(CP) tool. Most CP solvers have built-in facilities to return more than just a single solution. However, they also typically work with integer data. Few CP solvers allow fractional data. Here, we have fractional data by design. Converting to an integer problem can be done by scaling the constraint.</li><li>Use a <b>no-good constraint</b>. Solve, add a constraint (cut) to the model that forbids the current solution, and repeat until things become infeasible.</li><li>Some MIP solvers have what is called a <b>solution pool</b> which can enumerate solutions. These methods are often very fast.</li></ul><div>We will experiment with two datasets:</div></div><div><ul style="text-align: left;"><li>\(n=12\). This has three solutions.</li><li>\(n=25\). This gives us 41 solutions.</li></ul><div><br /></div></div><div><br /></div><div><br /></div><h3 style="text-align: left;"><b>Constraint programming</b></h3><div><b><br /></b></div><div>Constraint programming solvers often work with discrete variables only. Furthermore, coefficients of the model are also often restricted to be integers. I am trying the small CP solver <b>python-constraint </b>[1]. From the documentation, it is not clear to me whether floating-point coefficients are allowed. When, I run the constraint as is, with coefficients \(1.0/i\), I see:</div><div><br /></div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">n=<span style="color: blue;">12</span>
coefficients:[<span style="color: blue;">1.0</span>, <span style="color: blue;">0.5</span>, <span style="color: blue;">0.3333333333333333</span>, <span style="color: blue;">0.25</span>, <span style="color: blue;">0.2</span>, <span style="color: blue;">0.16666666666666666</span>, <span style="color: blue;">0.14285714285714285</span>, <span style="color: blue;">0.125</span>, <span style="color: blue;">0.1111111111111111</span>, <span style="color: blue;">0.1</span>, <span style="color: blue;">0.09090909090909091</span>, <span style="color: blue;">0.08333333333333333</span>]
number of solutions: <span style="color: blue;">2</span>
[<span style="color: blue;">'1/1'</span>]
[<span style="color: blue;">'1/2'</span>, <span style="color: blue;">'1/3'</span>, <span style="color: blue;">'1/6'</span>]
</pre></div>
<div><br /></div><div><br /></div><div>This is not the correct answer. These are certainly feasible solutions (the rows add up to one), but there is one more solution. So let's try to scale the constraint such that it has integer data. We can do this by writing: \[\sum_{i=1}^n \frac{\color{darkblue}{\mathit{LCM}}}{i} \cdot \color{darkred}x_i = \color{darkblue}{\mathit{LCM}}\] where \(\color{darkblue}{\mathit{LCM}}\) is the Least Common Multiple of \(\{1,\dots,n\}\). The coefficients \(\frac{\color{darkblue}{\mathit{LCM}}}{i}\) are now integers. When I solve it this way, I see:</div><div><br /></div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">n=<span style="color: blue;">12</span>, lcm=<span style="color: blue;">27720</span>
coefficients:[<span style="color: blue;">27720</span>, <span style="color: blue;">13860</span>, <span style="color: blue;">9240</span>, <span style="color: blue;">6930</span>, <span style="color: blue;">5544</span>, <span style="color: blue;">4620</span>, <span style="color: blue;">3960</span>, <span style="color: blue;">3465</span>, <span style="color: blue;">3080</span>, <span style="color: blue;">2772</span>, <span style="color: blue;">2520</span>, <span style="color: blue;">2310</span>]
number of solutions: <span style="color: blue;">3</span>
[<span style="color: blue;">'1/1'</span>]
[<span style="color: blue;">'1/2'</span>, <span style="color: blue;">'1/3'</span>, <span style="color: blue;">'1/6'</span>]
[<span style="color: blue;">'1/2'</span>, <span style="color: blue;">'1/4'</span>, <span style="color: blue;">'1/6'</span>, <span style="color: blue;">'1/12'</span>]
</pre></div>
<div><br /></div><div>The coefficients are now integers. And we see all three solutions. The larger problem shows:</div><div><br /></div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="background-color: white;">n=</span><span style="background-color: white; color: blue;">25</span><span style="background-color: white;">, lcm=</span><span style="background-color: white; color: blue;">26771144400</span><span style="background-color: white;">
</span><span style="background-color: #fff2cc;">number of solutions: <span style="color: blue;">41</span></span><span style="background-color: white;">
[</span><span style="background-color: white; color: blue;">'1/1'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/3'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/6'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/3'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/8'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/24'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/3'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/9'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/18'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/3'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/10'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/15'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/4'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/5'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/20'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/4'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/6'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/12'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/4'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/8'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/12'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/24'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/4'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/9'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/12'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/18'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/4'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/10'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/12'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/15'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/5'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/6'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/12'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/20'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/5'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/8'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/12'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/20'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/24'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/5'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/9'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/12'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/18'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/20'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/5'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/10'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/12'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/15'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/20'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/6'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/8'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/9'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/18'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/24'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/6'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/8'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/10'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/15'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/24'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/6'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/9'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/10'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/15'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/18'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/2'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/8'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/9'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/10'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/15'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/18'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/24'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/3'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/4'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/5'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/6'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/20'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/3'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/4'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/5'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/8'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/20'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/24'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/3'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/4'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/5'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/9'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/18'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/20'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/3'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/4'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/5'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/10'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/15'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/20'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/3'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/4'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/6'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/8'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/12'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/24'</span><span style="background-color: white;">]
...
[</span><span style="background-color: white; color: blue;">'1/4'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/5'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/6'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/9'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/10'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/15'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/18'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/20'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/4'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/5'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/8'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/9'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/10'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/15'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/18'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/20'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/24'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/4'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/6'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/8'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/9'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/10'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/12'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/15'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/18'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/24'</span><span style="background-color: white;">]
[</span><span style="background-color: white; color: blue;">'1/5'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/6'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/8'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/9'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/10'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/12'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/15'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/18'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/20'</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">'1/24'</span><span style="background-color: white;">]
</span></pre></div>
<div><br /></div><div>The \(\color{darkblue}{\mathit{LCM}}\) is growing to a very large number. This second model took about 33 seconds. I believe this is using Python integer arithmetic (i.e., big ints), so this should be exact. I suspect that a solver like<b> or-tools</b> will have trouble with this, as it probably uses fixed-size integers. (The lcm number exceeds what fits in a 32-bit integer).</div><div><br /></div><div>If a solver cannot handle floating-point coefficients, it really should refuse them with a proper message. I can understand why this solver does not like floating-point arithmetic: it requires that you need thinking this through and use appropriate tolerances. That makes things much more complicated.</div><div><br /></div><h3 style="text-align: left;">No-good cuts</h3><div><br /></div><div>A no-good cut is a constraint that forbids a previously found integer solution, but nothing else. If we denote this integer solution by \(\color{darkblue}x^*_i\) then such constraint can look like: \[\sum_{i|\color{darkblue}x^*_i=1} \color{darkred}x_i - \sum_{i|\color{darkblue}x^*_i=0}\color{darkred}x_i \le \sum_{i|\color{darkblue}x^*_i=1}1 - 1 \] This can also be written as \[\sum_i (2 \color{darkblue}x^*_i -1) \color{darkred}x_i \le \sum_i \color{darkblue}x^*_i - 1 \] The algorithm can look like:</div><div><br /></div><div><ol style="text-align: left;"><li>Solve the model</li><li>If infeasible: STOP</li><li>Record the solution</li><li>Add the no-good cut to the model</li><li>Go to step 1</li></ol><div><br /></div></div><div>The output for the \(n=12\) case is:</div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">---- <span style="color: blue;">75</span> PARAMETER <b>trace </b><i>results for each iteration</i>
<span style="color: blue;">1</span>/<span style="color: blue;">1</span> <span style="color: blue;">1</span>/<span style="color: blue;">2</span> <span style="color: blue;">1</span>/<span style="color: blue;">3</span> <span style="color: blue;">1</span>/<span style="color: blue;">4</span> <span style="color: blue;">1</span>/<span style="color: blue;">6</span> <span style="color: blue;">1</span>/<span style="color: blue;">12</span> sum
coeff <span style="color: blue;">1.000</span> <span style="color: blue;">0.500</span> <span style="color: blue;">0.333</span> <span style="color: blue;">0.250</span> <span style="color: blue;">0.167</span> <span style="color: blue;">0.083</span>
iter1 <span style="color: blue;">1.000</span> <span style="color: blue;">1.000</span>
iter2 <span style="color: blue;">1.000</span> <span style="color: blue;">1.000</span> <span style="color: blue;">1.000</span> <span style="color: blue;">1.000</span>
iter3 <span style="color: blue;">1.000</span> <span style="color: blue;">1.000</span> <span style="color: blue;">1.000</span> <span style="color: blue;">1.000</span> <span style="color: blue;">1.000</span>
</pre></div>
<div><br /></div><div><br /></div><div>The larger problem with \(n=25\) has the following solution:</div><div><br /></div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhfdf2Pf_AqZBMygWVCXAR6GYUwKyTbHI8C-Z2KdkMg0zAn0eYvI_B-kGCi9inuovNb7w3vVfG8eMEAeD0QNR4QBizI9jPNOKtJjO-945ZjFYQV45d6jOpf5aqz6mjA-9ivS-xfGxD1QTmo4vbDHkpcial7NYat0EEm5XDIL6pQV8iBF3WmQnG_oJY9Pw" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="796" data-original-width="782" height="640" src="https://blogger.googleusercontent.com/img/a/AVvXsEhfdf2Pf_AqZBMygWVCXAR6GYUwKyTbHI8C-Z2KdkMg0zAn0eYvI_B-kGCi9inuovNb7w3vVfG8eMEAeD0QNR4QBizI9jPNOKtJjO-945ZjFYQV45d6jOpf5aqz6mjA-9ivS-xfGxD1QTmo4vbDHkpcial7NYat0EEm5XDIL6pQV8iBF3WmQnG_oJY9Pw=w629-h640" width="629" /></a></div><br /><br /></div><div>The solve loop for this problem took 11 seconds. We solved 43 MIP problems, i.e. 42 solutions (the last solve is infeasible). <i>We have here one solution too many. </i>This is likely a tolerance issue. We can tinker a bit with feasibility tolerances, something I loathe to do, but a model-based approach would be to form the following constraint: \[\sum_{i=1}^n \frac{1000}{i} \cdot \color{darkred}x_i = 1000 \] This is a DIY scaling approach. This hopefully will prevent some very small coefficients (I am hedging here, as I don't know how the Cplex scaling algorithm interferes with this). Using this constraint, this algorithm generates 41 solutions. So, I am happy that this approach worked.</div><div><br /></div><div>The corrected output looks like:</div><div> </div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEg4UDYt-VnA96CpOkofnkZWNBzM4wSOdyd0MG5Fa_u-IlN_zzoaPL4pZJ_fGazTlwPumX0aU098ECVdFpWk5uIQUywQjbqZgZXsGCxlJmK6ooiDnxBFS2l5AFYsGMZBK9cVdsYviBvgyfEObhWsZI0RSKSPaTeHSrqfoY4iXBWROH7HMWj5y_sxmXHceA" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="862" data-original-width="665" height="640" src="https://blogger.googleusercontent.com/img/a/AVvXsEg4UDYt-VnA96CpOkofnkZWNBzM4wSOdyd0MG5Fa_u-IlN_zzoaPL4pZJ_fGazTlwPumX0aU098ECVdFpWk5uIQUywQjbqZgZXsGCxlJmK6ooiDnxBFS2l5AFYsGMZBK9cVdsYviBvgyfEObhWsZI0RSKSPaTeHSrqfoY4iXBWROH7HMWj5y_sxmXHceA=w493-h640" width="493" /></a></div><br /><br /></div><div>We basically dropped the <i>iter35</i> solution from the previous picture, and as a result, some columns also got whacked.</div><div><br /></div><h3 style="text-align: left;">Cplex solution pool</h3><div><br /></div><div>Again we used the scaled equation (with scale=1000). With default settings, but with the constraint scaled by 1,000, I saw</div><div><br /></div><blockquote><div><span style="font-family: courier;">--- Dumping 42 solutions from the solution pool...</span></div></blockquote><div><br /></div><div>This gives us one solution too many. (See [2] for a case where the Cplex solution pool also has problems.) The fix is to tighten the integer feasibility tolerance a bit (I surrendered; as I really don't want to do that). Cplex allows me to set this to zero (unlike most other solvers), so that is what I did. The solution pool now returns the same set of solutions as the solve loop. The solution time is less than a second.</div><div><br /></div><h3 style="text-align: left;">Conclusion</h3><div><br /></div><div>I used three methods to find all feasible integer solutions for this problem. There are a few small issues to resolve to make this work: </div><div><ul style="text-align: left;"><li>The constraint solver wants integer data, so I scaled the constraint by the LCM.</li><li>The solve-loop with no-good constraints requires some attention. After scaling the constraint by 1000, I get the correct set of solutions</li><li>The Cplex solution pool required me to change the integer feasibility tolerance.</li></ul></div><div>For a small, almost trivial model, lots of little things go wrong. It is interesting that none of these approaches worked correctly just right out of the box. Solvers have become very powerful and are used more than ever before, but there is still lots of room for improvement.</div><div><br /></div><h3 style="text-align: left;">References</h3><div><br /></div><div><ol style="text-align: left;"><li>Python-constraint, <a href="https://pypi.org/project/python-constraint/">https://pypi.org/project/python-constraint/</a></li><li>Chess and Solution Pool, <a href="https://yetanothermathprogrammingconsultant.blogspot.com/2018/11/chess-and-solution-pool.html">https://yetanothermathprogrammingconsultant.blogspot.com/2018/11/chess-and-solution-pool.html</a></li></ol><div><br /></div></div><div><br /></div><h3 style="text-align: left;">Appendix: Python constraint code</h3><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: navy; font-weight: bold;">import</span> constraint <span style="color: navy; font-weight: bold;">as</span> cp
<span style="color: navy; font-weight: bold;">import</span> math
n = 25
r = range(<span style="color: blue;">1</span>,<span style="color: blue;">1</span>+n)
lcm = math.lcm(*list(r))
print(f<span style="color: blue;">'n={n}, lcm={lcm}'</span>)
<span style="color: #008800; font-style: italic;"># coefficients </span>
p = [lcm // i <span style="color: navy; font-weight: bold;">for</span> i <span style="font-weight: bold;">in</span> r]
<span style="color: navy; font-weight: bold;">if</span> n <= <span style="color: blue;">15</span>: print(f<span style="color: blue;">'coefficients:{p}'</span>)
problem = cp.Problem()
problem.addVariables(r, [<span style="color: blue;">0</span>,<span style="color: blue;">1</span>])
problem.addConstraint(cp.ExactSumConstraint(lcm,p))
sol = problem.getSolutions()
print(f<span style="color: blue;">'number of solutions: {len(sol)}'</span>)
<span style="color: navy; font-weight: bold;">for</span> k <span style="font-weight: bold;">in</span> sol:
print([f<span style="color: blue;">'1/{i}'</span> <span style="color: navy; font-weight: bold;">for</span> i <span style="font-weight: bold;">in</span> k.keys() <span style="color: navy; font-weight: bold;">if</span> k[i]==<span style="color: blue;">1</span>])
</pre></div>
<div><br /></div><h3 style="text-align: left;">Appendix: GAMS model</h3><div><br /></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$<span class="SpellE">onText</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> Enumerate feasible <span class="GramE">solutions</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> 1. using no-good constraints</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> 2. using <span class="SpellE">Cplex</span> solution pool</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$<span class="SpellE">offText</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">data</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">set</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span style="font-family: Consolas; font-size: 9pt;">dummy </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'for ordering of elements'</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /'<span class="SpellE">coeff</span>'/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'numbers 1/<span class="SpellE">i</span> to use'</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /'1/1'*'1/25'/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">k0 </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'iterations (superset)'</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /iter1*iter100/ </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">parameter </span></b><span style="font-family: Consolas; font-size: 9pt;">p(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'coefficients<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">p(<span class="SpellE">i</span>) = 1/</span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">ord</span></b></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span><span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">dynamic</span> set + parameters to hold cut data</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">set </span></b><span style="font-family: Consolas; font-size: 9pt;">k(k0) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'iterations performed (and cut data index)<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">k(k0) = </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">no</span></b><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">parameter </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">cutcoeff</span></span><span style="font-family: Consolas; font-size: 9pt;">(k<span class="GramE">0,*</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'coefficients for cuts'</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">cutcoeff</span></span><span style="font-family: Consolas; font-size: 9pt;">(k<span class="GramE">0,i</span>) = 0;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">model</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* no-good cuts are added after each solve</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">binary variable </span></b><span style="font-family: Consolas; font-size: 9pt;">x(<span class="SpellE">i</span><span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">variable </span></b><span style="font-family: Consolas; font-size: 9pt;">z </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'obj<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">Equations</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span style="font-family: Consolas; font-size: 9pt;">e </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'sum to one'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">cuts </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'</span></span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">no-good cuts'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">obj </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'dummy objective'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">scalar </span></b><span style="font-family: Consolas; font-size: 9pt;">scale</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /1000<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">e..</span></span><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="font-family: Consolas; font-size: 9pt;">, scale*p(<span class="SpellE">i</span>)*x(<span class="SpellE">i</span>)) =e= scale;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">cuts(</span></span><span style="font-family: Consolas; font-size: 9pt;">k).. </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">i,cutcoeff</span></span>(<span class="SpellE">k,i</span>)*x(<span class="SpellE">i</span>)) =l= <span class="SpellE">cutcoeff</span>(k,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">rhs</span>'</span><span style="font-family: Consolas; font-size: 9pt;">);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">obj..</span></span><span style="font-family: Consolas; font-size: 9pt;"> z=e=<span class="GramE">0;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">model </span></b><span style="font-family: Consolas; font-size: 9pt;">m</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /all<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">m.solprint</span></span><span style="font-family: Consolas; font-size: 9pt;"> = </span><span style="color: #c84600; font-family: Consolas; font-size: 9pt;">%<span class="SpellE"><span class="GramE">solprint.Silent</span></span>%</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">m.solvelink</span></span><span style="font-family: Consolas; font-size: 9pt;"> = </span><span style="color: #c84600; font-family: Consolas; font-size: 9pt;">%<span class="SpellE">solveLink.Load</span> Library<span class="GramE">%<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">option</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">threads</span></b><span style="font-family: Consolas; font-size: 9pt;"> = <span class="GramE">0;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">algorithm</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">parameter </span></b><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">trace(</span></span><span style="font-family: Consolas; font-size: 9pt;">*,*) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'results for each iteration'</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">loop</span></b><span style="font-family: Consolas; font-size: 9pt;">(</span></span><span style="font-family: Consolas; font-size: 9pt;">k0,</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> m </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">mip</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">break</span></b><span style="font-family: Consolas; font-size: 9pt;">$(<span class="SpellE"><span class="GramE">m.modelstat</span></span> <> 1 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">and</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">m.modelstat</span> <> 8);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">x.l</span>(<span class="SpellE">i</span>) = </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">round</span></b><span style="font-family: Consolas; font-size: 9pt;">(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">x.l</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>)); </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> trace(k<span class="GramE">0,i</span>) = <span class="SpellE">x.l</span>(<span class="SpellE">i</span>); </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">cutcoeff</span>(k<span class="GramE">0,i</span>) = 2*<span class="SpellE">x.l</span>(<span class="SpellE">i</span>)-1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">cutcoeff</span>(k0,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'rhs'</span><span style="font-family: Consolas; font-size: 9pt;">) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">i,x</span>.l</span>(<span class="SpellE">i</span>))-1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> k(k0) = </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">yes</span></b><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">trace(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">coeff</span><span class="GramE">'<span style="color: black;">,<span class="SpellE">i</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">)$</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">k,trace</span>(<span class="SpellE">k,i</span>)) = p(<span class="SpellE">i</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">trace(<span class="SpellE">k,<span style="color: #007400;">'sum</span></span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'</span><span style="font-family: Consolas; font-size: 9pt;">) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">i,p</span></span>(<span class="SpellE">i</span>)*trace(<span class="SpellE">k,i</span>));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="GramE">trace;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">solution</span> pool approach</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">model </span></b><span style="font-family: Consolas; font-size: 9pt;">m2</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /<span class="SpellE"><span class="GramE">obj,e</span></span>/</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">m<span class="GramE">2.optfile</span>=1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> m2 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">mip</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$<span class="SpellE">onecho</span></span><i><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> > <span class="SpellE">cplex.opt</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">* <span class="GramE">solution</span> pool options</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">solnpoolintensity</span></span><span style="font-family: Consolas; font-size: 9pt;"> 4</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">solnpoolpop</span></span><span style="font-family: Consolas; font-size: 9pt;"> 2</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">populatelim</span></span><span style="font-family: Consolas; font-size: 9pt;"> 10000</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">solnpoolmerge</span></span><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">solutions.gdx</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">* <span class="GramE">tighten</span> tolerances</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">epint</span></span><span style="font-family: Consolas; font-size: 9pt;"> 0</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$<span class="SpellE">offecho</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">load</span> the <span class="SpellE">gdx</span> file with all solutions</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">set </span></b><span style="font-family: Consolas; font-size: 9pt;">id</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /soln_m2_p1*soln_m2_p1000<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">parameter </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">xsol</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">id,i</span></span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">execute_load</span></b></span><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">"solutions.<span class="SpellE">gdx</span><span class="GramE">"<span style="color: black;">,<span class="SpellE">xsol</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">=x;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE"><span class="GramE">xsol</span></span><span class="GramE">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-size: 9pt;"> </span></p></td></tr></tbody></table><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.5467px; margin: 0in 0in 8pt;"><o:p> </o:p></p></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com3tag:blogger.com,1999:blog-593563533834706486.post-92216001364275424642023-05-07T03:29:00.018-04:002023-05-09T06:41:09.900-04:00Finding common patterns<script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style>
<p>In [1], the following problem is stated:</p><p></p><blockquote>Given a boolean matrix, with \(m\) rows and \(n\) columns, find the largest pattern of ones that is found in at least \(\color{darkblue}K\) rows. We can ignore cells where the pattern has a zero value: they don't count.</blockquote><p>A small example [1] is given: <br /><br /></p><p></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">row <span style="color: blue;">1</span>:[<span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>]
row <span style="color: blue;">2</span>:[<span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>]
row <span style="color: blue;">3</span>:[<span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>]
row <span style="color: blue;">4</span>:[<span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>]
row <span style="color: blue;">5</span>:[<span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>]
row <span style="color: blue;">6</span>:[<span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">0</span>, <span style="color: blue;">1</span>, <span style="color: blue;">1</span>]
</pre></div><div><br /></div><br /> With \(K=3\), we can form a pattern with 10 nonzero elements:<br /><br /><div>
<!--HTML generated using hilite.me--><div style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="background-color: white;">row </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">: [</span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">]
row </span><span style="background-color: white; color: blue;">2</span><span style="background-color: white;">: [</span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">]
row </span><span style="background-color: white; color: blue;">3</span><span style="background-color: white;">: [</span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">]
row </span><span style="background-color: white; color: blue;">4</span><span style="background-color: white;">: [</span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">]
row </span><span style="background-color: white; color: blue;">5</span><span style="background-color: white;">: [</span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">]
row </span><span style="background-color: white; color: blue;">6</span><span style="background-color: white;">: [</span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">]
pattern:[</span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">, </span><span style="background-color: #04ff00; color: blue;">1</span><span style="background-color: white;">]
</span></pre></div><div><br /></div>
The pattern is shared by rows 4, 5, and 6.
</div><div><br /></div><div>Can we formulate a MIP model for this? My first attempt is as follows.</div><span><a name='more'></a></span><div><br /></div><div><br /></div>
<table class="blueTable">
<thead><tr><th>Mathematical Model version 1</th></tr></thead>
<tbody><tr><td>\[
\begin{align}
\max & \sum_j \color{darkred}{\mathit{pattern}}_j \\
& \sum_j \color{darkblue}d_{i,j}\cdot \color{darkred}{\mathit{pattern}}_j + \color{darkred}{\mathit{diff}}_i = \sum_j \color{darkred}{\mathit{pattern}}_j && \forall i \\
& \color{darkred}{\mathit{diff}}_i \le\color{darkblue}M \cdot (1-\color{darkred}{\mathit{ok}}_i) && \forall i \\
& \sum_i \color{darkred}{\mathit{ok}}_i \ge \color{darkblue}K \\
& \color{darkred}{\mathit{pattern}}_j \in \{0,1\} \\
& \color{darkred}{\mathit{diff}}_i \in \{0,1,2,\dots\} \\
& \color{darkred}{\mathit{ok}}_i \in \{0,1\}
\end{align}\]</td></tr></tbody>
</table><br />
<div>The constraint \[ \sum_j \color{darkblue}d_{i,j}\cdot \color{darkred}{\mathit{pattern}}_j + \color{darkred}{\mathit{diff}}_i = \sum_j \color{darkred}{\mathit{pattern}}_j\] measures the difference between the pattern and row \(i\). If \(\color{darkred}{\mathit{diff}}_i=0\) we have a match. The implication \(\color{darkred}{\mathit{diff}}_i\ne 0 \implies \color{darkred}{\mathit{ok}}_i=0\) is implemented as: \(\color{darkred}{\mathit{diff}}_i \le (1-\color{darkred}{\mathit{ok}}_i)\cdot \color{darkblue}M\) where \(\color{darkblue}M\) can be chosen as \(M:={\bf{card}}(j)\) (the number of columns). If your modeling tool allows indicator constraints, you can combine these two constraints into: \[ \color{darkred}{\mathit{ok}}_i=1 \implies \sum_j \color{darkblue}d_{i,j}\cdot \color{darkred}{\mathit{pattern}}_j = \sum_j \color{darkred}{\mathit{pattern}}_j\]Finally, we make sure we have at least \(\color{darkblue}K\) rows that are ok.</div><div><br /></div><div>A different approach can be based on \[\color{darkred}{\mathit{ok}}_i=1 \implies \color{darkred}{\mathit{pattern}}_j \le \color{darkblue}d_{i,j}\>\>\forall i,j\] This can be implemented as \[\color{darkred}{\mathit{pattern}}_j \le \color{darkblue}d_{i,j} + (1-\color{darkred}{\mathit{ok}}_i) \>\> \forall i,j\] or better \[\color{darkred}{\mathit{pattern}}_j + \color{darkred}{\mathit{ok}}_i \le 1 \>\>\forall i,j|\color{darkblue}d_{i,j}=0\] Here we skip all cases where \(\color{darkblue}d_{i,j}=1\). If \(\color{darkblue}d_{i,j}=1\), we know in advance it will always obey \(\color{darkred}{\mathit{ok}}_i=1 \implies \color{darkred}{\mathit{pattern}}_j \le \color{darkblue}d_{i,j}\). Of course, this new constraint also has a direct interpretation: for any \((i,j)\) with \(\color{darkblue}d_{i,j} = 0\), we can't have both: "row \(i\) is selected" and "column \(j\) is part of the pattern".</div><div><br /></div><div><table class="blueTable"><thead><tr><th>Mathematical Model version 2</th></tr></thead><tbody><tr><td>\[ \begin{align} \max & \sum_j \color{darkred}{\mathit{pattern}}_j \\ & \color{darkred}{\mathit{pattern}}_j +\color{darkred}{\mathit{ok}}_i\le 1 && \forall i,j|\color{darkblue}d_{i,j}=0 \\ & \sum_i \color{darkred}{\mathit{ok}}_i \ge \color{darkblue}K \\ & \color{darkred}{\mathit{pattern}}_j \in \{0,1\} \\ & \color{darkred}{\mathit{ok}}_i \in \{0,1\} \end{align}\]</td></tr></tbody></table><div><br /></div></div><div><br /></div><div>A third version, proposed in the comments below, is a variant of version 2: we aggregate over \(j\). This yields:</div><div><br /></div><div><br /></div><div><div><table class="blueTable"><thead><tr><th>Mathematical Model version 3</th></tr></thead><tbody><tr><td>\[ \begin{align} \max & \sum_j \color{darkred}{\mathit{pattern}}_j \\ & \sum_{j|\color{darkblue}d_{i,j}=0}\color{darkred}{\mathit{pattern}}_j \le \color{darkblue}M_i \cdot (1-\color{darkred}{\mathit{ok}}_i) && \forall i\\ & \sum_i \color{darkred}{\mathit{ok}}_i \ge \color{darkblue}K \\ & \color{darkred}{\mathit{pattern}}_j \in \{0,1\} \\ & \color{darkred}{\mathit{ok}}_i \in \{0,1\} \end{align}\]<div style="background-color: white; color: #d4d4d4; font-family: Consolas, "Courier New", monospace; font-size: 14px; line-height: 19px; white-space: pre;"><span style="color: black;"></span></div></td></tr></tbody></table><div><br /></div></div><div>where \[\color{darkblue}M_i = \sum_j (1-\color{darkblue}d_{i,j})\]</div></div><div>To be able to run some larger problems, I generated random data sets of any size. Here is a 50x50 matrix with \(\color{darkblue}K=5\):</div><div><br /></div><div></div><div><br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEiM9EPSRiaSWRAP6NZMuPfXrRd_8MxBxbnZp4jfQApcZ87qbvAdXNyFltIV4J3kjFNfByI8oV4ONzyTgurWuefM6EIephGhKhwXePo-DyYxPQzq8O5DFmusoMWA0L2SNGY_9WCQ4ywO3Ggc768-P8zIowYILu00EceKoK3Tu38IW3JlUjxrnSa0Y8WDzg" style="margin-left: auto; margin-right: auto;"><img alt="" data-original-height="835" data-original-width="1288" height="414" src="https://blogger.googleusercontent.com/img/a/AVvXsEiM9EPSRiaSWRAP6NZMuPfXrRd_8MxBxbnZp4jfQApcZ87qbvAdXNyFltIV4J3kjFNfByI8oV4ONzyTgurWuefM6EIephGhKhwXePo-DyYxPQzq8O5DFmusoMWA0L2SNGY_9WCQ4ywO3Ggc768-P8zIowYILu00EceKoK3Tu38IW3JlUjxrnSa0Y8WDzg=w640-h414" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">random 50x50 matrix, K=5 (click to enlarge)</td></tr></tbody></table><br /><br />Both versions are very fast.<span> For the random 50x50 data set, we have:</span></div><div><span><br /></span></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">---- <span style="color: blue;">117</span> PARAMETER <b>report</b> <i>performance statistics</i>
model <span style="color: blue;">1</span> model <span style="color: blue;">2</span> model <span style="color: blue;">3</span>
Variables <span style="color: blue;">151.000</span> <span style="color: blue;">101.000</span> <span style="color: blue;">101.000</span>
Equations <span style="color: blue;">102.000</span> <span style="color: blue;">1288.000</span> <span style="color: blue;">52.000</span>
Objective <span style="color: blue;">9.000</span> <span style="color: blue;">9.000</span> <span style="color: blue;">9.000</span>
Time <span style="color: blue;">0.516</span> <span style="color: blue;">0.547</span> <span style="color: blue;">0.625</span>
Nodes <span style="color: blue;">25126.000</span> <span style="color: blue;">6355.000</span> <span style="color: blue;">28903.000</span>
Iterations <span style="color: blue;">61866.000</span> <span style="color: blue;">40431.000</span> <span style="color: blue;">77324.000</span>
</pre></div>
<div><br /></div><div><br /></div><div>All variants solve this quite fast. Let's also try a 100x100 matrix:</div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">---- <span style="color: blue;">117</span> PARAMETER <b>report </b><i>performance statistics</i>
model <span style="color: blue;">1</span> model <span style="color: blue;">2</span> model <span style="color: blue;">3</span>
Variables <span style="color: blue;">301.000</span> <span style="color: blue;">201.000</span> <span style="color: blue;">201.000</span>
Equations <span style="color: blue;">202.000</span> <span style="color: blue;">5004.000</span> <span style="color: blue;">102.000</span>
Objective <span style="color: blue;">16.000</span> <span style="color: blue;">16.000</span> <span style="color: blue;">16.000</span>
Time <span style="color: blue;">5.296</span> <span style="color: blue;">44.078</span> <span style="color: blue;">5.266</span>
Nodes <span style="color: blue;">390382.000</span> <span style="color: blue;">389739.000</span> <span style="color: blue;">390382.000</span>
Iterations <span style="color: blue;">675128.000</span> <span style="color: blue;">3414636.000</span> <span style="color: blue;">675128.000</span>
</pre></div>
<div><br /></div><div>Model 1 and 3 are basically the same: the same node and iteration counts! But only for the 100x100 data. The reason could be that the presolver generates almost the same presolved model for these two cases. Model 2 is slower, although it uses fewer nodes (but more simplex iterations). </div><div><br /></div><div>Often we want to prevent big-M formulations. However, in this case the big-M models (model 1 and 3) are outperforming model 2.</div><div><br /></div><div>For some of these problems, we could have used complete enumeration. The small data set has \[{6 \choose 3} = 20\] possible combinations of three rows we need to check. For our 50x50 and 100x100 problems with \(K=5\), this number increases to 2,118,760 and 75,287,520.</div><div> </div><h3 style="text-align: left;">Conclusion</h3><div><br /></div><div>Three different MIP models for the same problem are presented. Many practical problems can be described using different mathematical models, sometimes very different ones. Version 1 vs. version 2 is a good example: they don't have much in common. It is not always easy to flip a switch in your mind and come up with totally different models. You need to take a different point of view, which can be difficult when in the thick of it.</div><div><br /></div><h3 style="text-align: left;">References</h3><div><br /></div><div><ol style="text-align: left;"><li>Linear programming problem, searching for a group that has the most in common, <a href="https://stackoverflow.com/questions/76157767/linear-programming-problem-searching-for-a-group-that-has-the-most-in-common">https://stackoverflow.com/questions/76157767/linear-programming-problem-searching-for-a-group-that-has-the-most-in-common</a></li></ol><div><br /></div></div><h3 style="text-align: left;">Appendix: GAMS model</h3><div><br /></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$<span class="SpellE">onText</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> search for K rows with the most ones in common</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$<span class="SpellE">offText</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$set</span><i><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> dataset <span class="GramE">2</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">dataset</span> 1</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$<span class="SpellE">ifthen</span></span><i><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span></i><span style="color: #c84600; font-family: Consolas; font-size: 9pt;">%dataset%</span><i><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">==1</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">set</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'rows'</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /r1*r6/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">j </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'columns'</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /c1*c21/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">table </span></b><span style="font-family: Consolas; font-size: 9pt;">d(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'data'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #005b00; font-family: Consolas; font-size: 9pt;"> c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #005b00; font-family: Consolas; font-size: 9pt;">r1</span></b><span style="color: #005078; font-family: Consolas; font-size: 9pt;"> <span class="GramE">0 1</span> 0 1 1 0 1 0 1 0 1 1 1 0 1 0 0 0 1 0 1</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #005b00; font-family: Consolas; font-size: 9pt;">r2</span></b><span style="color: #005078; font-family: Consolas; font-size: 9pt;"> <span class="GramE">0 1</span> 0 1 1 0 0 1 0 1 0 1 0 0 0 1 1 1 0 1 1</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #005b00; font-family: Consolas; font-size: 9pt;">r3</span></b><span style="color: #005078; font-family: Consolas; font-size: 9pt;"> <span class="GramE">0 0</span> 0 1 1 0 0 1 0 0 0 1 0 0 1 0 1 1 0 0 1</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #005b00; font-family: Consolas; font-size: 9pt;">r4</span></b><span style="color: #005078; font-family: Consolas; font-size: 9pt;"> <span class="GramE">1 1</span> 0 1 1 1 0 1 0 0 0 1 1 1 0 0 0 0 0 1 1</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #005b00; font-family: Consolas; font-size: 9pt;">r5</span></b><span style="color: #005078; font-family: Consolas; font-size: 9pt;"> <span class="GramE">1 1</span> 0 1 1 1 0 0 0 0 0 1 1 1 0 0 0 1 0 1 1</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #005b00; font-family: Consolas; font-size: 9pt;">r6</span></b><span style="color: #005078; font-family: Consolas; font-size: 9pt;"> <span class="GramE">1 1</span> 1 1 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">scalar </span></b><span style="font-family: Consolas; font-size: 9pt;">K </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'number of rows to select'</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /3<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$endif</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">dataset</span> 2</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$<span class="SpellE">ifthen</span></span><i><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span></i><span style="color: #c84600; font-family: Consolas; font-size: 9pt;">%dataset%</span><i><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">==2</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">set</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'rows'</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /r1*r50/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">j </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'columns'</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /c1*c50/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">parameter </span></b><span style="font-family: Consolas; font-size: 9pt;">d(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'data'</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">d(<span class="SpellE"><span class="GramE">i,j</span></span>) = </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">uniformint</span></b></span><span style="font-family: Consolas; font-size: 9pt;">(0,1);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">option</span></b><span style="font-family: Consolas; font-size: 9pt;"> d:0; </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="GramE">d;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">scalar </span></b><span style="font-family: Consolas; font-size: 9pt;">K </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'number of rows to select'</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /5<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$endif</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">reporting</span> macro</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">parameter </span></b><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">report(</span></span><span style="font-family: Consolas; font-size: 9pt;">*,*) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'performance statistics'</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$macro</span><i><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> statistics(<span class="SpellE"><span class="GramE">m,name</span></span>) \</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">report(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">Variables<span class="GramE">'<span style="color: black;">,name</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">) = <span class="SpellE">m.numvar</span>; \</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">report(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">Equations<span class="GramE">'<span style="color: black;">,name</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">) = <span class="SpellE">m.numequ</span>; \</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">report(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">Objective<span class="GramE">'<span style="color: black;">,name</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">) = <span class="SpellE">m.objval</span>; \</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">report(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">Time<span class="GramE">'<span style="color: black;">,name</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">) = <span class="SpellE">m.resusd</span>; \</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">report(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">Nodes<span class="GramE">'<span style="color: black;">,name</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">) = <span class="SpellE">m.nodusd</span>; \</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">report(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">Iterations<span class="GramE">'<span style="color: black;">,name</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">) = <span class="SpellE">m.iterusd</span>; \</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="GramE">report;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">option</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">threads</span></b><span style="font-family: Consolas; font-size: 9pt;">=<span class="GramE">0;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">model</span> 1</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">binary Variables</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span style="font-family: Consolas; font-size: 9pt;">pattern(<span class="GramE">j) <span style="color: #0000da;">'</span></span></span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">must be shared by k rows'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">ok(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'row contains <span class="GramE">pattern'</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">integer variable </span></b><span style="font-family: Consolas; font-size: 9pt;">diff(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'difference between pattern and row <span class="SpellE">i</span><span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">variable </span></b><span style="font-family: Consolas; font-size: 9pt;">z </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'objective<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">equations</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span style="font-family: Consolas; font-size: 9pt;">obj </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'objective'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">difference(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'calculate difference between pattern and row <span class="SpellE"><span class="GramE">i</span></span>'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">isdiff</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'ok(<span class="SpellE">i</span>)=1 => diff(<span class="SpellE">i</span>)=0'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">krows</span></span><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'match at least K rows'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">obj..</span></span><span style="font-family: Consolas; font-size: 9pt;"> z =e= </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(</span></span><span style="font-family: Consolas; font-size: 9pt;">j, pattern(j));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">difference(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="font-family: Consolas; font-size: 9pt;">).. </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">j,d</span></span>(<span class="SpellE">i,j</span>)*pattern(j))+diff(<span class="SpellE">i</span>) =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">j,pattern</span>(j)) ;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">isdiff</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="font-family: Consolas; font-size: 9pt;">).. diff(<span class="SpellE">i</span>) =l= (1-ok(<span class="SpellE">i</span><span class="GramE">))*</span></span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">card</span></b><span style="font-family: Consolas; font-size: 9pt;">(j);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">krows</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">..</span></span><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">i,ok</span></span>(<span class="SpellE">i</span>)) =g= k;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">model </span></b><span style="font-family: Consolas; font-size: 9pt;">m1</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /all<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> m1 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">maximizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">mip</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE"><span class="GramE">pattern.l</span>,diff.l,ok.l</span>;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">statistics(</span></span><span style="font-family: Consolas; font-size: 9pt;">m1,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'model 1'</span><span style="font-family: Consolas; font-size: 9pt;">)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">reporting</span>: form cube</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">parameter </span></b><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">cube(</span></span><span style="font-family: Consolas; font-size: 9pt;">*,*);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">cube(<span class="SpellE"><span class="GramE">i,j</span></span>) = d(<span class="SpellE">i,j</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">cube(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">pattern<span class="GramE">'<span style="color: black;">,j</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">round</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">pattern.l</span>(j));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">cube(<span class="SpellE">i</span>,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'diff'</span><span style="font-family: Consolas; font-size: 9pt;">) = <span class="SpellE"><span class="GramE">diff.l</span></span>(<span class="SpellE">i</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">cube(<span class="SpellE">i</span>,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'ok'</span><span style="font-family: Consolas; font-size: 9pt;">) = <span class="SpellE"><span class="GramE">ok.l</span></span>(<span class="SpellE">i</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">option</span></b><span style="font-family: Consolas; font-size: 9pt;"> cube:0; </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="GramE">cube;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">model</span> 2</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">equation </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">notBoth</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">for d</span>(<span class="SpellE">i,j</span>)=0: not both pattern(j)=1 and ok(<span class="SpellE">i</span>)=1'</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">notBoth</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">i,j</span></span>)$(d(<span class="SpellE">i,j</span>)=0).. ok(<span class="SpellE">i</span>) + pattern(j) =l= <span class="GramE">1;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">model </span></b><span style="font-family: Consolas; font-size: 9pt;">m2</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /<span class="SpellE"><span class="GramE">obj,notBoth</span>,krows</span>/</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> m2 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">maximizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">mip</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE"><span class="GramE">pattern.l</span>,ok.l</span>;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">statistics(</span></span><span style="font-family: Consolas; font-size: 9pt;">m2,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'model 2'</span><span style="font-family: Consolas; font-size: 9pt;">)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">model</span> 3</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*----------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">equation </span></b><span style="font-family: Consolas; font-size: 9pt;">aggregated(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'aggregated version<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">aggregated(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="font-family: Consolas; font-size: 9pt;">).. </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(j$(d(<span class="SpellE"><span class="GramE">i,j</span></span>)=0),pattern(j)) =l= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(j$(d(<span class="SpellE">i,j</span>)=0),1) * (1-ok(<span class="SpellE">i</span>));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">model </span></b><span style="font-family: Consolas; font-size: 9pt;">m3</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /<span class="SpellE"><span class="GramE">obj,aggregated</span>,krows</span>/</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> m3 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">maximizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">mip</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE"><span class="GramE">pattern.l</span>,ok.l</span>;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: 14.25pt; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">statistics(</span></span><span style="font-family: Consolas; font-size: 9pt;">m3,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'model 3'</span><span style="font-family: Consolas; font-size: 9pt;">)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p></td></tr></tbody></table><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.5467px; margin: 0in 0in 8pt;"><o:p> </o:p></p></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com2tag:blogger.com,1999:blog-593563533834706486.post-58520236465414652102023-05-02T08:41:00.024-04:002023-05-06T06:10:40.808-04:00Solving as network with lowerbounds<script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style><p>In [1], we looked at the following problem:</p><p><br /></p>
<p>
</p><table class="blueTable">
<thead><tr><th>Mathematical Model</th></tr></thead>
<tbody><tr><td>\[
\begin{align}
\min& \sum_{i,j} \color{darkblue}a_{i,j} \cdot \color{darkred}x_{i,j} \\
& \sum_j \color{darkblue}a_{i,j}\cdot \color{darkred}x_{i,j} \ge \color{darkblue}r_i && \forall i \\
& \sum_i \color{darkblue}a_{i,j}\cdot \color{darkred}x_{i,j} \ge \color{darkblue}c_j && \forall j \\
& \color{darkred}x_{i,j} \in \{0,1\}
\end{align}\]</td></tr></tbody>
</table>
<span><a name='more'></a></span><p><br /></p>
<p>This is a network problem, so instead of solving it as a MIP, we can solve it as a pure LP or as a min-cost flow network problem. </p><p>Here we try to use some open-source network codes. And thus, we need to formulate the problem as a pure network. This would be relatively straightforward if the algorithm supports lower bounds on the flows. However, most open-source network algorithms don't support these. (I think the C++ library Lemon has a code that supports lower bounds). Here is a workaround when lower bounds are not supported:</p><blockquote style="border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;"><p>Assume we have an edge \(i \rightarrow j\) with bounds \(f_{i,j} \in [\ell,u]\). We can reformulate this as:</p></blockquote><p style="text-align: left;"></p><ul style="text-align: left;"><ul><li>demand in node \(i\) is \(\ell\)</li><li>supply in node \(j\) is \(\ell\)</li><li>capacity of the edge \(i \rightarrow j\) becomes \(u-\ell\).</li></ul></ul><p></p><p>A streamlined version of this is used in my implementations below. </p><p>I will use the following network for our problem:</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjxpIUq4T106gtR_lIo5yMH83Ev5jBJQec8F6SjsxQwtq8DCkyKRdtz3qHaisvX6KQOZF8R-ghw_KVPtqYfTA_dI-W3DNUqLL8mYWpZd11WKirfpYZ4yamVdDvswPZvWLnuBLMUVMdL7Dk5UNmBb5drFCE1A-wkWORSFs9H-lSvloeNL4p_4W-p6dtLxg" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="561" data-original-width="880" height="255" src="https://blogger.googleusercontent.com/img/a/AVvXsEjxpIUq4T106gtR_lIo5yMH83Ev5jBJQec8F6SjsxQwtq8DCkyKRdtz3qHaisvX6KQOZF8R-ghw_KVPtqYfTA_dI-W3DNUqLL8mYWpZd11WKirfpYZ4yamVdDvswPZvWLnuBLMUVMdL7Dk5UNmBb5drFCE1A-wkWORSFs9H-lSvloeNL4p_4W-p6dtLxg=w400-h255" width="400" /></a></div><br />The orange nodes are supply nodes, while the blue ones are demand nodes.<br /><p></p><p></p><ul style="text-align: left;"><li>The source node <b>src</b> has a supply of \(\sum_{i,j} \color{darkblue}a_{i,j}-\sum_i \color{darkblue}r_i\). We subtract \(\sum_i \color{darkblue}r_i\) to simulate the lower bounds on the flows \(\mathit{src}\rightarrow i_k\). Part of the output of the source node flows to the assignment network; the rest is unused and goes directly to the sink node <b>snk</b>. </li><li>The nodes \(i\) have a supply of \(\color{darkblue}r_i\). This is to make sure each \(i\) receives at least \(\color{darkblue}r_i\). </li><li>The nodes \(j\) have a demand of \(\color{darkblue}c_j\). This is to make sure we obey the lower bound of \(\color{darkblue}c_j\).</li><li>Finally, the node <b>snk</b> has a demand of \(\sum_{i,j} \color{darkblue}a_{i,j}-\sum_j \color{darkblue}c_j\). </li><li>You can verify that the total supply is equal to the total demand.</li><li>The assignment arcs \(i \rightarrow j\) have a cost of 1 and a capacity of 1.</li><li>All other arcs have no cost and have unlimited capacity. I used \(\sum_{i,j} \color{darkblue}a_{i,j}\) to represent "unlimited capacity" where needed.</li></ul><div><br /></div><div>The Python package <b>networkx</b> has some network solvers. The complete implementation of the model is shown in an appendix. Here we use the same data as in [1] (an LP/MIP with 999,469 variables and 20,500 equations). Constraints correspond to nodes and variables to arcs. We added a source and sink node and some arcs, so we increased the size a little bit. The number of nodes is now 20,502, and the number of arcs is 1,019,970. The results are:</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEghv0fydWyJocCB-vguDrh98iwrSqScnhnG-9IqmfAE87ri5KmRQogKW_U8cPk6XVjZp_TQXJ7CWTDn54-jw6-uZoMtH0PvqeAukNlH1jb3a6jcxTUyAmjxt1EEy3Zyw6QTk49ywidFi50Y6xG_Jd1PmH5_Ul0REPYLF2kmGLJzIiW-8-zCCdJZ01dY_w" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="174" data-original-width="580" src="https://blogger.googleusercontent.com/img/a/AVvXsEghv0fydWyJocCB-vguDrh98iwrSqScnhnG-9IqmfAE87ri5KmRQogKW_U8cPk6XVjZp_TQXJ7CWTDn54-jw6-uZoMtH0PvqeAukNlH1jb3a6jcxTUyAmjxt1EEy3Zyw6QTk49ywidFi50Y6xG_Jd1PmH5_Ul0REPYLF2kmGLJzIiW-8-zCCdJZ01dY_w=s16000" /></a></div><br />We get the same objective function value as reported in [1]. The performance is not something to write home about. </div><div><br /></div><div>Another popular network algorithm can be found in <b>ortools</b>. This is <b>much </b>faster:</div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjiGeM5-4B0FLNPe2C59ONlwvnoUNJZBJFg7-nnOJZlTne3e4MlT8NGw-xq4R39e3KpPFVzYZw9znXp0txJXCjafUSyTVykDW3_hOrhZ3hsCV5E6lvL21YQ93-mfjTYp0vXlkpfW_3pZTK_ptjAwQUjFERdIxq_1Q8HHtsNX0OLiWfMP_obNxaQoDwFrw" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="231" data-original-width="527" src="https://blogger.googleusercontent.com/img/a/AVvXsEjiGeM5-4B0FLNPe2C59ONlwvnoUNJZBJFg7-nnOJZlTne3e4MlT8NGw-xq4R39e3KpPFVzYZw9znXp0txJXCjafUSyTVykDW3_hOrhZ3hsCV5E6lvL21YQ93-mfjTYp0vXlkpfW_3pZTK_ptjAwQUjFERdIxq_1Q8HHtsNX0OLiWfMP_obNxaQoDwFrw=s16000" /></a></div><br />Here the network setup is actually more expensive than solving it. One reason for better performance is that the <b>networkx</b> algorithm seems to be written in Python, while <b>ortools</b> uses C++. The underlying algorithms are also different (network simplex vs. scaling push-relabel method). </div><div><br /></div><h3 style="text-align: left;">Formulate a min-cost flow model and solve as LP</h3><div><br /></div><div>In this section, I do something different. I formulate the original model as a network model (a min-cost flow problem) and then solve it as an LP. This will allow us to use lower bounds on the flows. This can simplify things a bit. </div><div><br /></div><div>The min-cost flow model can look like: </div><div><br /></div>
<p>
</p><table class="blueTable">
<thead><tr><th>Min-Cost Flow Model</th></tr></thead>
<tbody><tr><td>\[
\begin{align}
\min& \sum_{E(v,w)} \color{darkblue}c_{v,w} \cdot \color{darkred}f_{v,w} \\
& \sum_{w|E(w,v)} \color{darkred}f_{w,v} + \color{darkblue}{\mathit{supply}}_v = \sum_{w|E(v,w)} \color{darkred}f_{v,w} && \forall v \\
& \color{darkred}f_{v,w} \in [\color{darkblue}\ell_{v,w},\color{darkblue}u_{v,w}] && \forall E(v,w) \end{align}\]</td></tr></tbody>
</table>
<p>
Here \(v,w\) are nodes (corresponding to constraints in the LP model), and \(E(v,w)\) are the edges. The lower bounds allow us to simply say that the <b>src </b>node has a supply \( \color{darkblue}a_{i,j}\), and the <b>snk </b>node has a demand of the same size. The edges \(\mathit{src}\rightarrow i\) and \(j \rightarrow \mathit{snk}\) have a lower bound of \(\color{darkblue}r_i\) and \(\color{darkblue}c_j\). When we solve this we see:</p><p><span style="font-family: courier;">Optimal solution found<br />Objective: 504711.000000</span></p><div style="text-align: left;">The complete model is listed in an appendix below. Here we went from an LP model to a network model to another LP model. In practice , of course, we would solve the original LP directly, rather than the network representation. However, it is a nice exercise and we show how lower bounds on the flows can simplify the network in terms of supply and demand on the nodes. I think it is an interesting model </div><div style="text-align: left;"><br /></div><h3 style="text-align: left;">Conclusions</h3><div><br /></div><div>We can solve the problem in [1] using open-source min-cost flow network solvers, such as the algorithms in <b>networkx</b> and <b>ortools</b>. As they don't support lower bounds on the flows, the modeling requires a bit of thought. </div><div><br /></div><div>I think the original LP model is more readable. It is closer to the underlying problem. The network implementation is less straightforward: it contains some non-obvious tricks. </div><div><br /></div><div>For this data set, the performance difference between the two solvers (networkx, ortools) is very large: a factor of 160!</div><div><br /></div><div>To demonstrate a formulation with lower bounds on the flows, I added a min-cost flow model in GAMS. This is solved as an LP. This model looks quite nice, I think.</div><div><br /></div><h3 style="text-align: left;">References</h3><div><br /></div><div><ol style="text-align: left;"><li><a href="https://yetanothermathprogrammingconsultant.blogspot.com/2023/04/a-large-mip-model-that-should-be-solved.html">https://yetanothermathprogrammingconsultant.blogspot.com/2023/04/a-large-mip-model-that-should-be-solved.html</a></li></ol><div><br /></div></div><h3 style="text-align: left;">Appendix: Min-cost flow model networkx implementation</h3><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: navy; font-weight: bold;">import</span> networkx <span style="color: navy; font-weight: bold;">as</span> nx
<span style="color: navy; font-weight: bold;">import</span> numpy <span style="color: navy; font-weight: bold;">as</span> np
<span style="color: navy; font-weight: bold;">import</span> pickle
<span style="color: #008800; font-style: italic;">#--------------------------------------------------------</span>
<span style="color: #008800; font-style: italic;"># import data</span>
<span style="color: #008800; font-style: italic;">#--------------------------------------------------------</span>
data = pickle.load(open(<span style="color: blue;">"c:/tmp/test/arc.pck"</span>,<span style="color: blue;">"rb"</span>))
a = data[<span style="color: blue;">'a'</span>] <span style="color: #008800; font-style: italic;"># 2d numpy array</span>
r = data[<span style="color: blue;">'r'</span>] <span style="color: #008800; font-style: italic;"># list of floats</span>
c = data[<span style="color: blue;">'c'</span>] <span style="color: #008800; font-style: italic;"># list of floats</span>
I = range(len(r))
J = range(len(c))
<span style="color: #008800; font-style: italic;"># these are all integers represented as double precision numbers</span>
<span style="color: #008800; font-style: italic;"># convert to integers</span>
a = a.astype(int)
r = [int(r[i]) <span style="color: navy; font-weight: bold;">for</span> i <span style="font-weight: bold;">in</span> I]
c = [int(c[j]) <span style="color: navy; font-weight: bold;">for</span> j <span style="font-weight: bold;">in</span> J]
suma = np.sum(a)
sumr = sum(r)
sumc = sum(c)
<span style="color: #008800; font-style: italic;">#--------------------------------------------------------</span>
<span style="color: #008800; font-style: italic;"># form network</span>
<span style="color: #008800; font-style: italic;">#--------------------------------------------------------</span>
G = nx.DiGraph()
<span style="color: #008800; font-style: italic;">#</span>
<span style="color: #008800; font-style: italic;"># x(i,j) form the bipartite part</span>
<span style="color: #008800; font-style: italic;">#</span>
<span style="color: navy; font-weight: bold;">for</span> i <span style="font-weight: bold;">in</span> I: G.add_node(f<span style="color: blue;">'i{i}'</span>,demand=-r[i])
<span style="color: navy; font-weight: bold;">for</span> j <span style="font-weight: bold;">in</span> J: G.add_node(f<span style="color: blue;">'j{j}'</span>,demand=c[j])
<span style="color: navy; font-weight: bold;">for</span> i <span style="font-weight: bold;">in</span> I:
<span style="color: navy; font-weight: bold;">for</span> j <span style="font-weight: bold;">in</span> J:
<span style="color: navy; font-weight: bold;">if</span> a[i,j]==<span style="color: blue;">1</span>: G.add_edge(f<span style="color: blue;">'i{i}'</span>,f<span style="color: blue;">'j{j}'</span>,weight=<span style="color: blue;">1</span>,capacity=<span style="color: blue;">1</span>)
<span style="color: #008800; font-style: italic;">#</span>
<span style="color: #008800; font-style: italic;"># add src and snk node</span>
<span style="color: #008800; font-style: italic;">#</span>
G.add_node(<span style="color: blue;">'src'</span>,demand=sumr-suma)
G.add_node(<span style="color: blue;">'snk'</span>,demand=suma-sumc)
<span style="color: navy; font-weight: bold;">for</span> i <span style="font-weight: bold;">in</span> I: G.add_edge(<span style="color: blue;">'src'</span>,f<span style="color: blue;">'i{i}'</span>)
<span style="color: navy; font-weight: bold;">for</span> j <span style="font-weight: bold;">in</span> J: G.add_edge(f<span style="color: blue;">'j{j}'</span>,<span style="color: blue;">'snk'</span>)
G.add_edge(<span style="color: blue;">'src'</span>,<span style="color: blue;">'snk'</span>)
<span style="color: #008800; font-style: italic;">#--------------------------------------------------------</span>
<span style="color: #008800; font-style: italic;"># solve</span>
<span style="color: #008800; font-style: italic;">#--------------------------------------------------------</span>
print(G)
flowCost, flowDict = nx.network_simplex(G)
print(f<span style="color: blue;">'objective:{flowCost}'</span>)
</pre></div>
<div><br /></div><div><br /></div><h3 style="text-align: left;">Appendix: min-cost flow model ortools implementation</h3><div><br /></div><p></p>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="color: navy; font-weight: bold;">import</span> pickle
<span style="color: navy; font-weight: bold;">import</span> numpy <span style="color: navy; font-weight: bold;">as</span> np
<span style="color: navy; font-weight: bold;">from</span> ortools.graph.python <span style="color: navy; font-weight: bold;">import</span> min_cost_flow
<span style="color: #008800; font-style: italic;">#--------------------------------------------------------</span>
<span style="color: #008800; font-style: italic;"># import data</span>
<span style="color: #008800; font-style: italic;">#--------------------------------------------------------</span>
data = pickle.load(open(<span style="color: blue;">"c:/tmp/test/arc.pck"</span>,<span style="color: blue;">"rb"</span>))
a = data[<span style="color: blue;">'a'</span>] <span style="color: #008800; font-style: italic;"># 2d numpy array</span>
r = data[<span style="color: blue;">'r'</span>] <span style="color: #008800; font-style: italic;"># list of floats</span>
c = data[<span style="color: blue;">'c'</span>] <span style="color: #008800; font-style: italic;"># list of floats</span>
I = range(len(r))
J = range(len(c))
<span style="color: #008800; font-style: italic;"># these are all integers represented as double precision numbers</span>
<span style="color: #008800; font-style: italic;"># convert to integers</span>
a = a.astype(int)
r = [int(r[i]) <span style="color: navy; font-weight: bold;">for</span> i <span style="font-weight: bold;">in</span> I]
c = [int(c[j]) <span style="color: navy; font-weight: bold;">for</span> j <span style="font-weight: bold;">in</span> J]
suma = np.sum(a) <span style="color: #008800; font-style: italic;"># also functions as largest possible capacity</span>
sumr = sum(r)
sumc = sum(c)
<span style="color: #008800; font-style: italic;">#--------------------------------------------------------</span>
<span style="color: #008800; font-style: italic;"># form network</span>
<span style="color: #008800; font-style: italic;">#--------------------------------------------------------</span>
mcf = min_cost_flow.SimpleMinCostFlow()
<span style="color: #008800; font-style: italic;"># numbering scheme for the nodes:</span>
<span style="color: #008800; font-style: italic;"># i = 0..len(r)-1</span>
<span style="color: #008800; font-style: italic;"># j = len(r)..len(r)+len(c)-1</span>
<span style="color: #008800; font-style: italic;"># src = len(r)+len(c)</span>
<span style="color: #008800; font-style: italic;"># snk = len(r)+len(c)+1</span>
src = len(r)+len(c)
snk = src + <span style="color: blue;">1</span>
lenr = len(r)
<span style="color: #008800; font-style: italic;"># assignment part of the graph, i->j</span>
<span style="color: navy; font-weight: bold;">for</span> i <span style="font-weight: bold;">in</span> I:
<span style="color: navy; font-weight: bold;">for</span> j <span style="font-weight: bold;">in</span> J:
<span style="color: navy; font-weight: bold;">if</span> a[i,j]==<span style="color: blue;">1</span>: mcf.add_arcs_with_capacity_and_unit_cost(i,lenr+j,<span style="color: blue;">1</span>,<span style="color: blue;">1</span>)
<span style="color: #008800; font-style: italic;"># src -> i</span>
<span style="color: navy; font-weight: bold;">for</span> i <span style="font-weight: bold;">in</span> I: mcf.add_arcs_with_capacity_and_unit_cost(src,i,suma,<span style="color: blue;">0</span>)
<span style="color: #008800; font-style: italic;"># j -> snk</span>
<span style="color: navy; font-weight: bold;">for</span> j <span style="font-weight: bold;">in</span> J: mcf.add_arcs_with_capacity_and_unit_cost(lenr+j,snk,suma,<span style="color: blue;">0</span>)
<span style="color: #008800; font-style: italic;"># src -> snk</span>
mcf.add_arcs_with_capacity_and_unit_cost(src,snk,suma,<span style="color: blue;">0</span>)
<span style="color: #008800; font-style: italic;"># supplies</span>
<span style="color: navy; font-weight: bold;">for</span> i <span style="font-weight: bold;">in</span> I: mcf.set_node_supply(i,r[i])
<span style="color: navy; font-weight: bold;">for</span> j <span style="font-weight: bold;">in</span> J: mcf.set_node_supply(lenr+j,-c[j])
mcf.set_node_supply(src,suma-sumr)
mcf.set_node_supply(snk,sumc-suma)
<span style="color: #008800; font-style: italic;">#--------------------------------------------------------</span>
<span style="color: #008800; font-style: italic;"># solve</span>
<span style="color: #008800; font-style: italic;">#--------------------------------------------------------</span>
print(f<span style="color: blue;">'nodes:{mcf.num_nodes()}, arcs:{mcf.num_arcs()}'</span>)
status=mcf.solve()
print(status)
print(f<span style="color: blue;">'objective:{mcf.optimal_cost()}'</span>)
</pre></div>
<p></p><div><br /></div><h3 style="text-align: left;">
Appendix: min-cost flow GAMS implementation</h3><div><br /></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">network</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sets</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span style="font-family: Consolas; font-size: 9pt;">v </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'nodes'</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /i1*i<span class="GramE">20000,j</span>1*j500,src,snk/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">e(<span class="SpellE"><span class="GramE">v,v</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'edges'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* e is populated below</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* Original data</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sets</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="font-family: Consolas; font-size: 9pt;">(v)</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /i1*i20000/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">j(v)</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /j1*j500/ </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">set </span></b><span style="font-family: Consolas; font-size: 9pt;">a(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'randomly filled with 10% ones'</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">a(<span class="SpellE"><span class="GramE">i,j</span></span>)$(</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">uniform</span></b><span style="font-family: Consolas; font-size: 9pt;">(0,1)<0.1) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">yes</span></b><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">calculate</span> rows and column sums</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">parameter </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">rowsum</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>), <span class="SpellE">colsum</span>(j<span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">rowsum</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(a(<span class="SpellE"><span class="GramE">i,j</span></span>),1);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">colsum</span></span><span style="font-family: Consolas; font-size: 9pt;">(j) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(a(<span class="SpellE"><span class="GramE">i,j</span></span>),1);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">parameter </span></b><span style="font-family: Consolas; font-size: 9pt;">r(<span class="SpellE">i</span><span class="GramE">),c</span>(j);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">r(<span class="SpellE">i</span>) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">ceil</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">rowsum</span>(<span class="SpellE">i</span>)/2<span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">c(j) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">ceil</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">colsum</span>(j)/2<span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">populate</span> arcs in network</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">e(a) = </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">yes</span></b><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">e(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">src</span><span class="GramE">'<span style="color: black;">,<span class="SpellE">i</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">yes</span></b><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">e(j,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">snk</span>'</span><span style="font-family: Consolas; font-size: 9pt;">) = </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">yes</span></b><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">e(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">src</span>'</span><span style="font-family: Consolas; font-size: 9pt;">,</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">snk</span>'</span><span style="font-family: Consolas; font-size: 9pt;">) = </span><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">yes</span></b><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">parameter </span></b><span style="font-family: Consolas; font-size: 9pt;">supply(v) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'supply at nodes (demand is negative supply)<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">supply(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">src</span>'</span><span style="font-family: Consolas; font-size: 9pt;">) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">card</span></b><span style="font-family: Consolas; font-size: 9pt;">(a<span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">supply(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">snk</span>'</span><span style="font-family: Consolas; font-size: 9pt;">) = -</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">card</span></b><span style="font-family: Consolas; font-size: 9pt;">(a<span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">min</span> cost flow</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">alias</span></b><span style="font-family: Consolas; font-size: 9pt;"> (<span class="SpellE"><span class="GramE">v,w</span></span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">positive variable </span></b><span style="font-family: Consolas; font-size: 9pt;">f(<span class="SpellE"><span class="GramE">v,w</span></span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* non-default bounds on arcs</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">f.up</span></span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i,j</span>) = 1;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">f.lo</span></span></span><span style="font-family: Consolas; font-size: 9pt;">(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">src</span>'</span><span style="font-family: Consolas; font-size: 9pt;">,<span class="SpellE">i</span>) = r(<span class="SpellE">i</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span class="GramE"><span lang="NL" style="font-family: Consolas; font-size: 9pt;">f.lo</span></span></span><span lang="NL" style="font-family: Consolas; font-size: 9pt;">(j,</span><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">snk</span>'</span><span lang="NL" style="font-family: Consolas; font-size: 9pt;">) = c(j);</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">variable </span></b><span style="font-family: Consolas; font-size: 9pt;">z </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'objective<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">equations</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span style="font-family: Consolas; font-size: 9pt;">obj </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'objective'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">nodebal(v)</span></span><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'node balance'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">obj..</span></span><span style="font-family: Consolas; font-size: 9pt;"> z =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">a,f</span></span>(a));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">nodebal</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">(</span></span><span style="font-family: Consolas; font-size: 9pt;">v).. </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(e(<span class="SpellE"><span class="GramE">w,v</span></span>),f(e)) + supply(v) =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(e(<span class="SpellE">v,w</span>),f(e));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">model </span></b><span style="font-family: Consolas; font-size: 9pt;">m</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /all<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">m.solprint</span></span><span style="font-family: Consolas; font-size: 9pt;"> = </span><span style="color: #c84600; font-family: Consolas; font-size: 9pt;">%<span class="SpellE"><span class="GramE">solprint.Silent</span></span>%</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">option</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">threads</span></b><span style="font-family: Consolas; font-size: 9pt;"> = <span class="GramE">0;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> m </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">lp</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;<br /><br /></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;"><b style="font-family: Calibri, sans-serif; font-size: 14.6667px;"><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-size: 9pt;"> <span class="SpellE">z.l</span>;</span></span></span><span style="background-color: transparent; font-family: Consolas; font-size: 9pt;"> </span></p></td></tr></tbody></table><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.6933px; margin: 0in 0in 8pt;"><o:p> </o:p></p></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com0tag:blogger.com,1999:blog-593563533834706486.post-63304879408131162152023-04-26T13:42:00.019-04:002023-05-05T10:55:06.508-04:00A large MIP model that should be solved as LP: the root node<script type="text/x-mathjax-config">
MathJax.Hub.Config({
CommonHTML: {
scale: 105
}
});
</script><script async="" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML" type="text/javascript">
</script><style>
table.xyz {
table-layout: fixed;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.xyz th, table.xyz td {
border: 1px solid black;
}
table.blueTable {
border: 1px solid #1C6EA4;
background-color: #EEEEEE;
width: 60%;
text-align: left;
border-collapse: collapse;
margin-left:auto;
margin-right:auto;
}
table.blueTable td, table.blueTable th {
border: 1px solid #AAAAAA;
padding: 3px 2px;
}
table.blueTable tbody td {
font-size: 14px;
}
table.blueTable tr:nth-child(even) {
background: #D0E4F5;
}
table.blueTable thead {
background: #1C6EA4;
background: -moz-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: -webkit-linear-gradient(top, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
background: linear-gradient(to bottom, #5592bb 0%, #327cad 66%, #1C6EA4 100%);
border-bottom: 2px solid #444444;
}
table.blueTable thead th {
font-size: 15px;
font-weight: bold;
color: #FFFFFF;
border-left: 2px solid #D0E4F5;
}
table.blueTable thead th:first-child {
border-left: none;
}
table.blueTable tfoot td {
font-size: 14px;
}
table.blueTable tfoot .links {
text-align: right;
}
table.blueTable tfoot .links a{
display: inline-block;
background: #1C6EA4;
color: #FFFFFF;
padding: 2px 8px;
border-radius: 5px;
}
</style><p>In this post, I want to discuss an observation about the root node when solving a MIP model.</p><h3 style="text-align: left;">Problem Description</h3><div><br /></div><div>The model I want to tackle here is from [1]:</div><div><br /></div><div></div><blockquote><div>We have a large matrix \(\color{darkblue}A=\color{darkblue}a_{i,j}\) with values 0 and 1. In addition, we have a minimum on the row and column totals. These are called \(\color{darkblue}r_i\) and \(\color{darkblue}c_j\). The goal is to remove as many 1's in the matrix \(\color{darkblue}A\) subject to these minimum row and column totals.</div><div></div></blockquote><span><a name='more'></a></span><div><br /></div><h3 style="text-align: left;">Mathematical Model</h3><div><br /></div><div>The mathematical model for this problem is not very difficult. We define:</div><div>\[\color{darkred}x_{i,j} = \begin{cases} 1 & \text{if we need to keep the corresponding value $\color{darkblue}a_{i,j}=1$} \\ 0 & \text{if we can drop the corresponding value $\color{darkblue}a_{i,j}=1$ } \end{cases} \] We don't consider the cases where \(\color{darkblue}a_{i,j}=0\).</div><p>Now, we can write:</p><p><br /></p>
<table class="blueTable">
<thead><tr><th>Mathematical Model</th></tr></thead>
<tbody><tr><td>\[
\begin{align}
\min& \sum_{i,j|\color{darkblue}a_{i,j}=1} \color{darkred}x_{i,j} \\
& \sum_{j|\color{darkblue}a_{i,j}=1} \color{darkred}x_{i,j} \ge \color{darkblue}r_i && \forall i \\
& \sum_{i|\color{darkblue}a_{i,j}=1} \color{darkred}x_{i,j} \ge \color{darkblue}c_j && \forall j \\
& \color{darkred}x_{i,j} \in \{0,1\}
\end{align}\]</td></tr></tbody>
</table>
<p>
If you prefer, we can also write this as:
</p><p>
</p><table class="blueTable">
<thead><tr><th>Mathematical Model</th></tr></thead>
<tbody><tr><td>\[
\begin{align}
\min& \sum_{i,j} \color{darkblue}a_{i,j} \cdot \color{darkred}x_{i,j} \\
& \sum_j \color{darkblue}a_{i,j}\cdot \color{darkred}x_{i,j} \ge \color{darkblue}r_i && \forall i \\
& \sum_i \color{darkblue}a_{i,j}\cdot \color{darkred}x_{i,j} \ge \color{darkblue}c_j && \forall j \\
& \color{darkred}x_{i,j} \in \{0,1\}
\end{align}\]</td></tr></tbody>
</table>
<p><br /></p><p>The post in [1] mentions that the goal is to solve this model with a matrix size of 20,000 rows and 500 columns. As I used a fraction of 10% ones in the matrix \(\color{darkblue}A\), the number of (discrete) variables in the model is close to million: 999,469 (we could have predicted this from \(20,000 \times 500 \times 0.1\)). The number of constraints is 20,500.</p><p><br /></p><h3 style="text-align: left;">Observation</h3><div><br /></div><div>Branch-and-bound algorithms start with solving a relaxed model. This is a model where all integer restrictions are ignored and thus becomes an LP. In some cases, notably when the problem is a network model, this relaxed LP automatically yields integer-valued solutions. This is such a case. A network model is characterized by:</div><div><ul style="text-align: left;"><li>All matrix coefficients are \(-1\) or \(+1\) (check),</li><li>the right-hand-side should be integer valued (check),</li><li>there are two nonzero coefficients in each column of the constraint matrix (check),</li><li>and these two nonzero coefficients have the value \(-1\) and \(+1\).</li></ul><div>The last condition is not met. But, by multiplying the last constraint by \(-1\), we achieve what we want. Cplex will do this actually automatically when invoking the network solver.</div><div><br /></div><div>If we solve such a model as an LP or as a network model, the solution will be automatically integral. If we throw this into a MIP solver, we expect the solver to start with the relaxation, and then stop quickly because the solution is integer-valued. There is no need for branching. I.e., solving the MIP and the LP should take about the same time. That is not the case here:</div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background: rgb(255, 255, 255); border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;">---- <span style="color: blue;">88</span> PARAMETER <b>results </b>
MIP LP NETWORK
status Optimal Optimal Optimal
obj <span style="color: blue;">504711.000</span> <span style="color: blue;">504711.000</span> <span style="color: blue;">504711.000</span>
time <span style="color: red;">5141.515</span> <span style="color: blue;">14.437</span> <span style="color: blue;">4.000</span>
iter <span style="color: blue;">571595.000</span> <span style="color: blue;">38276.000</span>
nodes NA NA
</pre></div><div><br /></div>
The MIP is not branching (the node count is zero), but it spends a lot of time preprocessing just after solving the root node. The number of iterations for the network solver is incorrectly reported as zero here. It actually did 1,235,117 iterations.<div><br /></div><div>This may be related to how the presolve behaves. It may do things slightly differently when it knows the variables are discrete. However, when looking at the log, the first best bound is unbelievably poor: it is zero!</div><div><br /></div>
<!--HTML generated using hilite.me--><div style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; border-color: gray; border-image: initial; border-style: solid; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;"><pre style="line-height: 125%; margin: 0px;"><span style="background-color: white;">Iteration log . . .
Iteration: </span><span style="background-color: white; color: blue;">1</span><span style="background-color: white;"> Dual objective = </span><span style="background-color: white; color: blue;">1079.000000</span><span style="background-color: white;">
Perturbation started.
Iteration: </span><span style="background-color: white; color: blue;">606</span><span style="background-color: white;"> Dual objective = </span><span style="background-color: white; color: blue;">499871.000000</span><span style="background-color: white;">
Iteration: </span><span style="background-color: white; color: blue;">2167</span><span style="background-color: white;"> Dual objective = </span><span style="background-color: white; color: blue;">499871.008110</span><span style="background-color: white;">
Iteration: </span><span style="background-color: white; color: blue;">3647</span><span style="background-color: white;"> Dual objective = </span><span style="background-color: white; color: blue;">499871.016553</span><span style="background-color: white;">
. . .
Iteration: </span><span style="background-color: white; color: blue;">33697</span><span style="background-color: white;"> Dual objective = </span><span style="background-color: white; color: blue;">504711.126635</span><span style="background-color: white;">
Iteration: </span><span style="background-color: white; color: blue;">33962</span><span style="background-color: white;"> Dual objective = </span><span style="background-color: white; color: blue;">504711.126636</span><span style="background-color: white;">
Removing perturbation.
Primal simplex solved model.
Root relaxation solution time = </span><span style="background-color: white; color: blue;">16.92</span><span style="background-color: white;"> sec. (</span><span style="background-color: white; color: blue;">4357.36</span><span style="background-color: white;"> ticks)
Nodes Cuts/
Node Left Objective IInf Best Integer Best Bound ItCnt Gap
* </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">+ </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;"> </span><span style="background-color: white; color: blue;">999469.0000</span><span style="background-color: white;"> </span> <span style="color: red;">0.0000</span> <span style="background-color: white;"> </span><span style="background-color: white; color: blue;">100.00</span><span style="background-color: white; color: #008800; font-style: italic;">%</span><span style="background-color: white;">
Found incumbent of value </span><span style="background-color: white; color: blue;">999469.000000</span><span style="background-color: white;"> after </span><span style="background-color: white; color: blue;">20.62</span><span style="background-color: white;"> sec. (</span><span style="background-color: white; color: blue;">6918.29</span><span style="background-color: white;"> ticks)
* </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;">+ </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;"> </span><span style="background-color: white; color: blue;">522140.0000</span><span style="background-color: white;"> </span> <span style="color: red;">0.0000</span> <span style="background-color: white;"> </span><span style="background-color: white; color: blue;">100.00</span><span style="background-color: white; color: #008800; font-style: italic;">%</span><span style="background-color: white;">
Found incumbent of value </span><span style="background-color: white; color: blue;">522140.000000</span><span style="background-color: white;"> after </span><span style="background-color: white; color: blue;">5140.89</span><span style="background-color: white;"> sec. (</span><span style="background-color: white; color: blue;">6925.92</span><span style="background-color: white;"> ticks)
* </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;"> </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;"> integral </span><span style="background-color: white; color: blue;">0</span><span style="background-color: white;"> </span><span style="background-color: white; color: blue;">504711.0000</span><span style="background-color: white;"> </span><span style="background-color: white; color: blue;">504711.0000</span><span style="background-color: white;"> </span><span style="background-color: white; color: blue;">571595</span><span style="background-color: white;"> </span><span style="background-color: white; color: blue;">0.00</span><span style="background-color: white; color: #008800; font-style: italic;">%</span><span style="background-color: white;">
Elapsed time = </span><span style="background-color: white; color: blue;">5140.97</span><span style="background-color: white;"> sec. (</span><span style="background-color: white; color: blue;">7024.08</span><span style="background-color: white;"> ticks, tree = </span><span style="background-color: white; color: blue;">0.00</span><span style="background-color: white;"> MB)
Found incumbent of value </span><span style="background-color: white; color: blue;">504711.000000</span><span style="background-color: white;"> after </span><span style="background-color: white; color: blue;">5140.97</span><span style="background-color: white;"> sec. (</span><span style="background-color: white; color: blue;">7024.08</span><span style="background-color: white;"> ticks)
Root node processing (before b&c):
Real time = </span><span style="background-color: white; color: blue;">5140.98</span><span style="background-color: white;"> sec. (</span><span style="background-color: white; color: blue;">7037.52</span><span style="background-color: white;"> ticks)
Parallel b&c, </span><span style="background-color: white; color: blue;">16</span><span style="background-color: white;"> threads:
Real time = </span><span style="background-color: white; color: blue;">0.00</span><span style="background-color: white;"> sec. (</span><span style="background-color: white; color: blue;">0.00</span><span style="background-color: white;"> ticks)
Sync time (average) = </span><span style="background-color: white; color: blue;">0.00</span><span style="background-color: white;"> sec.
Wait time (average) = </span><span style="background-color: white; color: blue;">0.00</span><span style="background-color: white;"> sec.
------------
Total (root+branch&cut) = </span><span style="background-color: white; color: blue;">5140.98</span><span style="background-color: white;"> sec. (</span><span style="background-color: white; color: blue;">7037.52</span><span style="background-color: white;"> ticks)
</span></pre></div>
<br /></div><div><br /></div><div>I have no idea why this is the case. This would mean the relaxed objective is zero. I don't believe that to be the case. </div><div><br /></div><div>The actual LP log for the root is not listed as Cplex solves the root using several different LP algorithms in parallel. The first one to finish seems to be primal simplex, while the log is from the dual simplex method. But still, I can't imagine that the primal simplex solves the root node with an optimal objective of 0. (<i>Update: as speculated below, the first few lines in the MIP log may be executed before the root LP was solved.</i>)</div><div><br /></div><h3 style="text-align: left;">Conclusion</h3><div><br /></div><div>One thing is clearly demonstrated here: if the relaxed LP is automatically integral, solving as a MIP can be very slow. In this case, we talk about 5000 seconds vs. 14 seconds. The network extraction and subsequent solving are even faster: 4 seconds.</div><div><br /></div><div>I am not sure why solving as a MIP is slower than solving as an LP. Sometimes the argument is that the presolve behaves differently (more reductions when it is known that the variables are integers). If that prevents the solution of the root node from being integer-valued, we certainly paid a very high price for that. Another cause could be that Cplex is just using some very expensive heuristics to find integer solutions "quickly" before it bothers to inspect the solution of the relaxed problem. <i>Heuristics need to be fast to be useful as part of a solution strategy.</i> Using a heuristic that takes more than an hour for a problem that solves in a few seconds is not the smartest thing to do.</div><div><br /></div><div>In the end, I think the MIP formulation is more precise. It conveys my intention better. The solver should really not punish me for that.</div><p><i>Update: some other solvers do not seem to have this extreme behavior. They solve the MIP and LP models in about the same time. It looks like the poor performance on the MIP model is a particularity of Cplex.</i></p><p><br /></p><h3 style="text-align: left;">References</h3><div><br /></div><div><ol style="text-align: left;"><li>Efficiently remove a maximum amount of binary elements while keeping row and column sums above a certain level, <a href="https://stackoverflow.com/questions/76105697/efficiently-remove-a-maximum-amount-of-binary-elements-while-keeping-row-and-col">https://stackoverflow.com/questions/76105697/efficiently-remove-a-maximum-amount-of-binary-elements-while-keeping-row-and-col</a></li></ol></div><div><br /></div><h3 style="text-align: left;">Appendix: GAMS model</h3><div><br /></div><div>In GAMS, we can solve a relaxed MIP model by using an RMIP model.</div><div><br /></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none; width: 672px;"><tbody><tr><td style="border: 1pt solid windowtext; padding: 0in 5.4pt; width: 503.75pt;" valign="top" width="672"><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$<span class="SpellE">onText</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> A very large MIP. It takes some time to solve.</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> <span class="GramE">However</span> the LP is actually automatically integer valued. This means the relaxation is no <span class="GramE">good?</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> <span class="GramE">Finally</span> we also <span class="GramE">solve</span> as a network model.</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> Reference:</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;"> https://stackoverflow.com/questions/76105697/efficiently-remove-a-maximum-amount-of-binary-elements-while-keeping-row-and-col </span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$<span class="SpellE">offText</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* Data</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">set</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /i1*i20000/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">j</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /j1*j500/</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">set </span></b><span style="font-family: Consolas; font-size: 9pt;">a(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'randomly filled with 10% ones'</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">a(<span class="SpellE"><span class="GramE">i,j</span></span>)$(</span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">uniform</span></b><span style="font-family: Consolas; font-size: 9pt;">(0,1)<0.1) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">YES</span></b><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">calculate</span> rows and column sums</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">parameter </span></b><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">rowsum</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>), <span class="SpellE">colsum</span>(j<span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">rowsum</span></span><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">i</span>) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(a(<span class="SpellE"><span class="GramE">i,j</span></span>),1);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">colsum</span></span><span style="font-family: Consolas; font-size: 9pt;">(j) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(a(<span class="SpellE"><span class="GramE">i,j</span></span>),1);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">parameter </span></b><span style="font-family: Consolas; font-size: 9pt;">r(<span class="SpellE">i</span><span class="GramE">),c</span>(j);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">r(<span class="SpellE">i</span>) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">ceil</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">rowsum</span>(<span class="SpellE">i</span>)/2<span class="GramE">);</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="GramE"><span lang="NL" style="font-family: Consolas; font-size: 9pt;">c</span></span><span lang="NL" style="font-family: Consolas; font-size: 9pt;">(j) = </span><span class="SpellE"><b><span lang="NL" style="color: #0000b3; font-family: Consolas; font-size: 9pt;">ceil</span></b></span><span lang="NL" style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE">colsum</span>(j)/2);</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span lang="NL" style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span lang="NL" style="color: #787878; font-family: Consolas; font-size: 9pt;">* MIP Model</span></i><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">binary variable </span></b><span style="font-family: Consolas; font-size: 9pt;">x(<span class="SpellE"><span class="GramE">i,j</span></span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'only used when a(<span class="SpellE">i,j</span>)=1'</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">variable </span></b><span style="font-family: Consolas; font-size: 9pt;">z </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'objective<span class="GramE">'<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">equations</span></b><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;"> </span></b><span style="font-family: Consolas; font-size: 9pt;">obj</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">erowsum</span>(<span class="SpellE">i</span>) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'minimum number of ones in row'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">ecolsum</span></span><span style="font-family: Consolas; font-size: 9pt;">(j) </span><span style="color: #0000da; font-family: Consolas; font-size: 9pt;">'minimum number of ones in column'</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">obj..</span></span><span style="font-family: Consolas; font-size: 9pt;"> z =e= </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(<span class="SpellE"><span class="GramE">a,x</span></span>(a));</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">erowsum</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">(</span></span><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">i</span></span><span style="font-family: Consolas; font-size: 9pt;">).. </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(a(<span class="SpellE"><span class="GramE">i,j</span></span>),x(<span class="SpellE">i,j</span>)) =g= r(<span class="SpellE">i</span>);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">ecolsum</span></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">(</span></span><span style="font-family: Consolas; font-size: 9pt;">j).. </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">(a(<span class="SpellE"><span class="GramE">i,j</span></span>),x(<span class="SpellE">i,j</span>)) =g= c(j);</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">model </span></b><span style="font-family: Consolas; font-size: 9pt;">m</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;"> /all<span class="GramE">/<span style="color: black;">;</span></span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* Reporting macro</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">acronym</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="GramE">Optimal;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">parameter </span></b><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">results;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$macro</span><i><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> report(<span class="SpellE"><span class="GramE">m,label</span></span>) \</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><span lang="NL" style="font-family: Consolas; font-size: 9pt;">results</span></span></span><span lang="NL" style="font-family: Consolas; font-size: 9pt;">(</span><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">status'<span style="color: black;">,label</span></span></span><span lang="NL" style="font-family: Consolas; font-size: 9pt;">) = <span class="SpellE">m.modelstat</span>; \</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span lang="NL" style="font-family: Consolas; font-size: 9pt;"> </span><span style="font-family: Consolas; font-size: 9pt;">results(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">status<span class="GramE">'<span style="color: black;">,label</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">)$(<span class="SpellE">m.modelstat</span>=1) = Optimal; \</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> results(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">obj<span class="GramE">'<span style="color: black;">,label</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">) = <span class="SpellE">z.l</span>; \</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> results(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">frac<span class="GramE">'<span style="color: black;">,label</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">) = </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">sum</span></b><span style="font-family: Consolas; font-size: 9pt;">((<span class="SpellE">i,j</span>)$(<span class="SpellE">x.l</span>(<span class="SpellE">i,j</span>)>0.001 </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">and</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE">x.l</span>(<span class="SpellE">i,j</span>)<0.999),1); \</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> results(</span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">time<span class="GramE">'<span style="color: black;">,label</span></span></span></span><span style="font-family: Consolas; font-size: 9pt;">) = <span class="SpellE">m.resusd</span>; \</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><span lang="NL" style="font-family: Consolas; font-size: 9pt;">results</span></span></span><span lang="NL" style="font-family: Consolas; font-size: 9pt;">(</span><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">iter</span>'</span><span lang="NL" style="font-family: Consolas; font-size: 9pt;">,label) = <span class="SpellE">m.iterusd</span>; \</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span lang="NL" style="font-family: Consolas; font-size: 9pt;"> <span class="SpellE"><span class="GramE">results</span></span>(</span><span lang="NL" style="color: #007400; font-family: Consolas; font-size: 9pt;">'<span class="SpellE">nodes</span>'</span><span lang="NL" style="font-family: Consolas; font-size: 9pt;">,label) = <span class="SpellE">m.nodusd</span>;</span><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span lang="NL" style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">solve</span> as MIP, LP and Network model</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;"> </span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">m.solprint</span></span><span style="font-family: Consolas; font-size: 9pt;"> = </span><span style="color: #c84600; font-family: Consolas; font-size: 9pt;">%<span class="SpellE"><span class="GramE">solprint.Silent</span></span>%</span><span style="font-family: Consolas; font-size: 9pt;">;</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">option</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">threads</span></b><span style="font-family: Consolas; font-size: 9pt;"> = 0, </span><span class="SpellE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">bratio</span></b></span><span style="font-family: Consolas; font-size: 9pt;"> = <span class="GramE">1;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> m </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">mip</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">report(<span class="SpellE">m,<span style="color: #007400;">'MIP</span></span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'</span><span style="font-family: Consolas; font-size: 9pt;">)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> m </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">rmip</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">report(<span class="SpellE">m,<span style="color: #007400;">'LP</span></span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'</span><span style="font-family: Consolas; font-size: 9pt;">)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">m.optfile</span></span><span style="font-family: Consolas; font-size: 9pt;">=<span class="GramE">1;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">solve</span></b><span style="font-family: Consolas; font-size: 9pt;"> m </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">minimizing</span></b><span style="font-family: Consolas; font-size: 9pt;"> z </span><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">using</span></b><span style="font-family: Consolas; font-size: 9pt;"> </span><span class="SpellE"><span class="GramE"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">rmip</span></b></span></span><span class="GramE"><span style="font-family: Consolas; font-size: 9pt;">;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-family: Consolas; font-size: 9pt;">report(<span class="SpellE">m,<span style="color: #007400;">'NETWORK</span></span></span><span style="color: #007400; font-family: Consolas; font-size: 9pt;">'</span><span style="font-family: Consolas; font-size: 9pt;">)</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><b><span style="color: #0000b3; font-family: Consolas; font-size: 9pt;">display</span></b><span style="font-family: Consolas; font-size: 9pt;"> <span class="GramE">results;</span></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">* <span class="GramE">network</span> option file, for use with third solve</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><i><span style="color: #787878; font-family: Consolas; font-size: 9pt;">*-----------------------------------------------------------------------------------</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"> </span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$<span class="SpellE">onecho</span></span><i><span style="color: #0000da; font-family: Consolas; font-size: 9pt;"> > <span class="SpellE">cplex.opt</span></span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span class="SpellE"><span style="font-family: Consolas; font-size: 9pt;">lpmethod</span></span><span style="font-family: Consolas; font-size: 9pt;"> 3</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="background: white; font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 9pt;">$<span class="SpellE">offecho</span></span><span style="font-family: Consolas; font-size: 9pt;"></span><span style="color: #d4d4d4; font-family: Consolas; font-size: 9pt;"><o:p></o:p></span></p><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: normal; margin: 0in;"><span style="font-size: 9pt;"> </span></p></td></tr></tbody></table><p class="MsoNormal" style="font-family: Calibri, sans-serif; font-size: 11pt; line-height: 15.6933px; margin: 0in 0in 8pt;"><o:p> </o:p></p></div><h3 style="text-align: left;">Appendix Highs open source solver</h3><div><br /></div><div>The open-source solver HighS seems to do a good job on this (using the interior point code):</div><div><br /></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0in 5.4pt 0in 5.4pt; mso-yfti-tbllook: 1184;">
<tbody><tr>
<td style="border: 1pt solid windowtext; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623">
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"><span style="font-family: Consolas; font-size: 8pt;">C:\tmp\HiGHS\build\RELEASE\bin>highs --parallel on --solver ipm
\tmp\test\Free.mps<br /></span><span style="font-family: Consolas; font-size: 8pt;">Running HiGHS 1.5.0 [date:
2023-04-28, git hash: d4809eae7]<br /></span><span style="font-family: Consolas; font-size: 8pt;">Copyright (c) 2022 HiGHS under
MIT licence terms<br /></span><span style="font-family: Consolas; font-size: 8pt;">LP</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Free has 20501 rows; 999470 cols; 2998408
nonzeros<br /></span><span style="font-family: Consolas; font-size: 8pt;">Presolving model20500 rows,
999469 cols, 1998938 nonzeros<br /></span><span style="font-family: Consolas; font-size: 8pt;">20500 rows, 999469 cols, 1998938
nonzeros<br /></span><span style="font-family: Consolas; font-size: 8pt;">Presolve : Reductions: rows
20500(-1); columns 999469(-1); elements 1998938(-999470)<br /></span><span style="font-family: Consolas; font-size: 8pt;">Solving the presolved LP<br /></span><span style="font-family: Consolas; font-size: 8pt;">IPX model has 20500 rows, 999469
columns and 1998938 nonzeros<br /></span><span style="font-family: Consolas; font-size: 8pt;">Input<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Number of variables:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">999469<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Number of free variables:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">0<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Number of constraints:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">20500<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Number of equality constraints:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">0<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Number of matrix entries:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">1998938<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Matrix range:</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">[1e+00, 1e+00]<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">RHS range:</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">[1e+01, 1e+03]<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Objective range:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">[1e+00, 1e+00]<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Bounds range:</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">[1e+00, 1e+00]<br /></span><span style="font-family: Consolas; font-size: 8pt;">Preprocessing<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Dualized model:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">no<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Number of dense columns:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">0<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Range of scaling factors:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">[1.00e+00,
1.00e+00]<br /></span><span style="font-family: Consolas; font-size: 8pt;">IPX version 1.0<br /></span><span style="font-family: Consolas; font-size: 8pt;">Interior Point Solve<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Iter</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">P.res</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">D.res</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">P.obj</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">D.obj</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">mu</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">Time<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">0</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">3.18e+00
1.61e+00</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">4.99746607e+05
-1.05662220e+06</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">5.73e+00</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">0s<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">1</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">1.87e-01 3.87e-01</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">5.02178430e+05 -7.59933312e+05</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">8.62e-01</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">0s<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">2</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">1.87e-07 3.87e-07</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">5.06231009e+05</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">2.51321995e+05</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">1.26e-01</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">0s<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">3</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">3.33e-08 2.08e-10</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">5.04967969e+05</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">5.04559804e+05</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">2.02e-04</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">1s<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">4</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">1.95e-09 4.44e-16</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">5.04726025e+05</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">5.04710964e+05</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">7.46e-06</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">1s<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">5</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">7.94e-11 4.44e-16</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">5.04711612e+05</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">5.04710999e+05</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">3.04e-07</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">1s<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">6</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">1.45e-11 4.44e-16</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">5.04711112e+05</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">5.04710964e+05</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">7.33e-08</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">1s<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">7*</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">4.84e-12 4.44e-16</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">5.04711002e+05</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">5.04711000e+05</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">1.08e-09</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">1s<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Constructing starting basis...<br /></span><span style="font-family: Consolas; font-size: 8pt;">Running crossover as requested<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Primal residual before push phase:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">2.43e-07<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Dual residual before push phase:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">3.62e-14<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Number of dual pushes required:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">9953<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Number of primal pushes required:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">979469<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">440683 primal pushes remaining ( 436418
pivots)<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">235353 primal pushes remaining ( 624870
pivots)<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">37258 primal pushes remaining ( 803629
pivots)<br /></span><span style="font-family: Consolas; font-size: 8pt;">Summary<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Runtime:</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">17.90s<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Status interior point solve:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">optimal<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">Status crossover:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">optimal<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">objective value:</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">5.04711002e+05<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">interior solution primal residual
(abs/rel):</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">5.00e-12 / 4.63e-15<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">interior solution dual residual
(abs/rel):</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">4.44e-16 / 2.22e-16<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">interior solution objective gap
(abs/rel):</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">2.17e-03 / 4.30e-09<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">basic solution primal infeasibility:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">0.00e+00<br /></span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">basic solution dual infeasibility:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">0.00e+00<br /></span><span style="font-family: Consolas; font-size: 8pt;">Ipx: IPM</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">optimal<br /></span><span style="font-family: Consolas; font-size: 8pt;">Ipx: Crossover optimal<br /></span><span style="font-family: Consolas; font-size: 8pt;">Solving the original LP from the
solution after postsolve<br /></span><span style="font-family: Consolas; font-size: 8pt;">Model</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">status</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">: Optimal<br /></span><span style="font-family: Consolas; font-size: 8pt;">IPM</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">iterations: 7<br /></span><span style="font-family: Consolas; font-size: 8pt;">Crossover iterations: 847053<br /></span><span style="font-family: Consolas; font-size: 8pt;">Objective value</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">:</span><span style="font-family: Consolas; font-size: 8pt;">
</span><span style="font-family: Consolas; font-size: 8pt;">5.0471100000e+05<br /></span><span style="font-family: Consolas; font-size: 8pt;">HiGHS run time</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">:</span><span style="font-family: Consolas; font-size: 8pt;"> </span><span style="font-family: Consolas; font-size: 8pt;">19.52</span></p>
</td>
</tr>
</tbody></table></div><p></p><p></p> Somehow I can't run this directly from GAMS, as it needs a license. I don't know why.Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com5tag:blogger.com,1999:blog-593563533834706486.post-57146938638067514582023-04-18T04:07:00.013-04:002023-05-02T08:54:12.936-04:00Some GAMS embedded Python notes<p>Here are two issues you may want to be aware of. The discussion below is relevant for Windows and not so much for Unix variants.</p><p><br /></p><h3 style="text-align: left;">Using Python Raw strings for directories</h3><div><br /></div><div>Here we use some Python inside an otherwise empty GAMS model:</div><div><br /></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0in 5.4pt 0in 5.4pt; mso-yfti-tbllook: 1184;">
<tbody><tr>
<td style="border: 1pt solid windowtext; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623">
<p class="MsoNormal" style="background: white; line-height: 14.25pt; margin-bottom: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">$onEmbeddedCode</span><span style="color: #c84600; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;"> Python:</span><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;"><o:p></o:p></span></p>
<p class="MsoNormal" style="background: white; line-height: 14.25pt; margin-bottom: 0in;"><span style="color: #c84600; font-family: Consolas; font-size: 10.5pt;">dir = r"%system.fp%"<br /></span><span style="color: #c84600; font-family: Consolas; font-size: 10.5pt;">print(dir)</span></p>
<p class="MsoNormal" style="background: white; line-height: 14.25pt; margin-bottom: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$offEmbeddedCode</span><span style="background-color: transparent;"> </span></p>
</td>
</tr>
</tbody></table><br /></div><div><span><a name='more'></a></span>Here I make use of the GAMS predefined compile-time variable <b>system.fp</b>, which indicates the location of the main <b>.gms</b> file of this run. The string <span style="background-color: white; color: #c84600; font-family: Consolas; font-size: 14px;">%system.fp%</span> will be replaced by the literal value of the file path. In my case this is: <b>c:\users\erwin\downloads\</b>. I use a so-called raw string because I don't want Python to view \ as an escape character. However, this gives a problem when I run this:</div><div><br /></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0in 5.4pt 0in 5.4pt; mso-yfti-tbllook: 1184;">
<tbody><tr>
<td style="border: 1pt solid windowtext; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623">
<p class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"><span style="font-family: Consolas;">--- Initialize embedded library embpycclib64.dll<br /></span><span style="font-family: Consolas;">--- Execute embedded library embpycclib64.dll<br /></span><span style="font-family: Consolas;"> </span><span style="font-family: Consolas;">File
"<string>", line 7<br /></span><span style="font-family: Consolas;"> </span><span style="font-family: Consolas;">dir =
r"C:\Users\erwin\Downloads\"<br /></span><span style="font-family: Consolas;"> </span><span style="font-family: Consolas;">^<br /></span><span style="font-family: Consolas;">SyntaxError: EOL while scanning string literal<br /></span><span style="font-family: Consolas;">Python error! Return code from Python execution:
-1*** Error executing embedded code section:<br /></span><span style="font-family: Consolas;">*** Check log above</span></p>
</td>
</tr>
</tbody></table><br /></div><div>The problem is that raw strings in Python are not really raw strings. Python wants to check for escaped quotes in raw strings, so it does not want a single \ at the end of a string literal. To be more precise, it does not want to have an uneven number of \ at the end of a literal [1].</div><div><br /></div><div>One possible fix is to add an extra \ to such paths:</div><div><blockquote><span style="background-color: white; color: #c84600; font-family: Consolas; font-size: 14px;">dir = r"%system.fp%\"</span></blockquote><p>This will generate a path: <span style="font-family: Consolas;">C:\Users\erwin\Downloads\\.</span> The double \\ is not a problem as Windows will interpret this the same as a single \. </p><p>Note: there is a reason why other languages use a more complicated raw string:</p><p></p><ul style="text-align: left;"><li>R: <span style="font-family: courier;"><span style="color: #cc0000;">r"(</span><span style="color: #0b5394;">C:\Users\erwin\Downloads\</span><span style="color: #cc0000;">)"</span></span><span style="color: #cc0000;"> </span>or even more complex versions in case your string literal contains a )". </li><li>C++: <span style="font-family: courier;"><span style="color: #cc0000;">R"(</span><span style="color: #0b5394;">C:\Users\erwin\Downloads</span>\<span style="color: #cc0000;">)"</span></span><span style="font-family: inherit;">. This again uses )" to terminate the string. We can make this more complicated to make it more difficult for the literal to contain the terminator.</span></li></ul>I guess that the Python approach for raw strings is just a bit too simplistic. <p></p></div><div><br /></div><h3 style="text-align: left;">GAMS System Directory</h3><div><br /></div><div>There are different ways to tell Windows where GAMS is located. The first is using a full path when invoking <b>gams.exe</b>. Alternatively, Windows can look along the PATH. But, there is also a registry setting that tells us where GAMS is installed. This can lead to some confusion when using embedded Python tools. Consider the following model:</div><div><br /></div><div><table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0in 5.4pt 0in 5.4pt; mso-yfti-tbllook: 1184;">
<tbody><tr>
<td style="border: 1pt solid windowtext; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt; width: 467.5pt;" valign="top" width="623">
<p class="MsoNormal" style="background: white; line-height: 14.25pt; margin-bottom: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;">$call</span><i><span style="color: #0000da; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;"> "echo #### GAMS: system
directory=[%gams.sysdir%]"</span></i><span style="color: #d4d4d4; font-family: Consolas; font-size: 10.5pt; mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman"; mso-font-kerning: 0pt; mso-ligatures: none;"><o:p></o:p></span></p>
<p class="MsoNormal" style="background: white; line-height: 14.25pt; margin-bottom: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$onEmbeddedCode</span><span style="color: #c84600; font-family: Consolas; font-size: 10.5pt;"> Python:</span></p>
<p class="MsoNormal" style="background: white; line-height: 14.25pt; margin-bottom: 0in;"><span style="color: #c84600; font-family: Consolas; font-size: 10.5pt;">ws = GamsWorkspace()<br /></span><span style="color: #c84600; font-family: Consolas; font-size: 10.5pt;">print(f"#### Embedded Python:
system directory=[{ws.system_directory}]")</span></p>
<p class="MsoNormal" style="background: white; line-height: 14.25pt; margin-bottom: 0in;"><span style="color: #6b006b; font-family: Consolas; font-size: 10.5pt;">$offEmbeddedCode</span><span style="background-color: transparent;"> </span></p>
</td>
</tr>
</tbody></table><br /></div><div>In theory, the two print statements should deliver the same system directory. However, there are a few scenarios where they are not. Here is an example. When I run:</div><div><br /></div><div> <span style="font-family: courier;"> C:\Users\erwin\Downloads><span><b>\gams\41\gams.exe testEmbedded.gms</b></span></span></div><div><b><br /></b></div><div>I see:</div><div><br /></div><div></div><blockquote><div><span style="font-family: courier;">#### GAMS: system directory=[<span style="background-color: #ffd966;">c:\gams\41\</span>]</span></div><div><span style="font-family: courier;">#### Embedded Python: system directory=[<span style="background-color: #ffd966;">C:\GAMS\42</span>]</span></div></blockquote><p><br /></p><p>Obviously, this behavior is not what we want. GAMS itself uses a different GAMS version than the embedded Python code. This is likely a very dangerous situation: lots of possibilities of mismatched libraries. In this example, GAMS itself infers the system directory (sysdir) from how it was invoked, while the Python API uses the Windows registry settings. We can make things even worse. If we just use GAMS from a network drive without local installation, we may get:</p><p><br /></p><p><span style="background-color: white; color: #222222; font-size: small;"><span style="font-family: courier;"></span></span></p><blockquote><span style="font-family: courier;">Exception from Python (line 46): Could not find a GAMS installation, must manually specify system_directory</span></blockquote> <p></p><p>(It is a bit counter-intuitive that while GAMS is running, the Python API can't figure out the correct location of this GAMS system). </p><p>One way to make these problems go away is to use:</p><p><br /></p><p></p><blockquote><span style="background-color: white; color: #c84600; font-family: Consolas; font-size: 14px;">ws = GamsWorkspace(system_directory=r"%gams.sysdir%\")</span></blockquote><p></p><p><br /></p><p>Note again the extra \ (see the discussion in the previous section). Now, I see:</p><p><br /></p><p><span style="font-family: courier;"></span></p><blockquote><p><span style="font-family: courier;">#### GAMS: system directory=[c:\gams\41\]<br />#### Embedded Python: system directory=[C:\GAMS\41]</span></p></blockquote><p> </p><p>The system directory is now the same. Except for a small inconsistency in the trailing backslash (I think they should preferably be 100% the same). </p><p>Besides <span style="font-family: courier;">GamsWorkspace</span>, this may affect a few other functions and constructors. I saw these problems occurring when using <span style="background-color: white; color: #c84600; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;">c = gt.Container() </span>from the <b>gamstransfer</b> package. Again the fix was to use: <span style="color: #c84600; font-family: Consolas, "Courier New", monospace; font-size: 14px; white-space: pre;">c = gt.Container(system_directory=r"%gams.sysdir%\")</span>. </p><p><br /></p><h3 style="text-align: left;">Conclusion</h3><p><br /></p><p>A few issues cropped up when doing some work using embedded Python in GAMS:</p><p></p><ul style="text-align: left;"><li>Trailing backslashes in directory names can be a problem when used in Python scripts.</li><li>Some parts of the GAMS Python API have problems finding the correct system directory. </li></ul><div>Some workarounds are presented here.</div><div><br /></div><div><br /></div><h3 style="text-align: left;">References</h3><div><br /></div><div><ol style="text-align: left;"><li>Python 3 documentation, Lexical Analysis, String and Bytes literals, <a href="https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals">https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals</a></li></ol></div><p></p><div></div>Erwin Kalvelagenhttp://www.blogger.com/profile/09496091402502236997noreply@blogger.com2