<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: proc optmodel - how to convert a conditional constraint into linear to be solved with milp in Mathematical Optimization, Discrete-Event Simulation, and OR</title>
    <link>https://communities.sas.com/t5/Mathematical-Optimization/proc-optmodel-how-to-convert-a-conditional-constraint-into/m-p/512958#M2486</link>
    <description>&lt;P&gt;Rob,&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks for your reply.. but I need to apply the same concept for a 3 dimension matrix&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Can you help me with this? This are the heuristics I want to apply:&lt;/P&gt;&lt;P&gt;- I need to cluster a set of points by proximity&amp;nbsp;&lt;/P&gt;&lt;P&gt;- Objective - I can do this by minimizing the sum of distances from all origins to all destinations for all the clusters created&lt;/P&gt;&lt;P&gt;- Constraint - Clusters must have more than x points (in example is 5)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;QUESTION:&lt;/STRONG&gt; How can I specify that if an origin is in one group, then it cannot be in other groups. I have implemented this, (as you recommended, but the problem is that the&amp;nbsp; limits are applied across the clusters.. I want to specify that if an origin is in one group... it cannot be in another group for any of the destinations.&amp;nbsp; See bellow an attempt to use your recommendation... problem is that the limits 0-1 AND 4 TO card apply for the origin across all the groups.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;proc optmodel;&lt;BR /&gt;set DEST = 1..&amp;amp;num_vars;&lt;BR /&gt;set GROUPS = 1..&amp;amp;num_groups;&lt;BR /&gt;set ORIG;&lt;BR /&gt;num dist {ORIG, DEST};&lt;BR /&gt;read data SFDISTANCES into ORIG=[_N_] {j in DEST} &amp;lt;dist[_N_,j]=col('x'||j)&amp;gt;;&lt;/P&gt;&lt;P&gt;/* Assign[i,g] = 1 if observation i assigned to group g, 0 otherwise */&lt;BR /&gt;var Assign {ORIG, DEST, GROUPS} binary;&lt;/P&gt;&lt;P&gt;Var IsOriginGroup{ ORIG,GROUPS} binary init 0;&lt;/P&gt;&lt;P&gt;con orig_assignment_lb1 {i in ORIG}:&lt;BR /&gt;sum {j in DEST, g in GROUPS} Assign [i,j,g] &amp;gt;= 0 * and {g in GROUPS} IsOriginGroup[i,g] + 4 * (1 - IsOriginGroup[i,g]);&lt;/P&gt;&lt;P&gt;con orig_assignment_lb2 {i in ORIG}:&lt;BR /&gt;sum {j in DEST, g in GROUPS} Assign [i,j,g] &amp;gt;= 1 * IsOriginGroup[i,g] + card(DEST) * (1 - IsOriginGroup[i,g]);&lt;/P&gt;&lt;P&gt;con Simetry {i in ORIG, j in DEST, g in GROUPS}:&lt;BR /&gt;Assign[i,j,g]=Assign[j,i,g];&lt;/P&gt;&lt;P&gt;con ASimetry {i in ORIG, g in GROUPS}:&lt;BR /&gt;Assign[i,i,g]= 0;&lt;/P&gt;&lt;P&gt;con NearlyEqual {g in GROUPS}:&lt;BR /&gt;sum {i in ORIG, j in DEST} Assign[i,j,g] &amp;gt;=4 ;&lt;/P&gt;&lt;P&gt;impvar GroupSum {g in GROUPS} = sum {i in ORIG,j in DEST} dist [i,j] * Assign[i,j,g];&lt;/P&gt;&lt;P&gt;min distance = sum {g in GROUPS} GroupSum[g];&lt;BR /&gt;&lt;BR /&gt;solve with milp / primalin allcuts=AGGRESSIVE RELOBJGAP=0.1 maxtime=50 ;&lt;/P&gt;&lt;P&gt;create data Allocated_Demand from&lt;BR /&gt;[ORIG DEST GROUPS]={i in ORIG, j in DEST, G IN GROUPS: Assign[i,j,g] = 1};&lt;BR /&gt;print Assign;&lt;BR /&gt;print GroupSum;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Wed, 14 Nov 2018 14:49:13 GMT</pubDate>
    <dc:creator>acanaveras</dc:creator>
    <dc:date>2018-11-14T14:49:13Z</dc:date>
    <item>
      <title>proc optmodel - how to convert a conditional constraint into linear to be solved with milp</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/proc-optmodel-how-to-convert-a-conditional-constraint-into/m-p/512337#M2481</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have an assignment problem that I want to solve with milp. I use a two by two binary matrix as the variable to optimize.&lt;/P&gt;&lt;P&gt;My problem is that I need to add a constraint by which the sum of the rows is either 1 or bigger than 5. See the code below.&lt;/P&gt;&lt;P&gt;How can I convert the non linear constraint into &amp;nbsp;linear ?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;　&lt;/P&gt;&lt;P&gt;&lt;FONT color="#000080" face="Courier New" size="2"&gt;&lt;STRONG&gt;proc&lt;/STRONG&gt;&lt;/FONT&gt; &lt;STRONG&gt;&lt;FONT color="#000080" face="Courier New" size="2"&gt;optmodel&lt;/FONT&gt;&lt;/STRONG&gt; &lt;FONT color="#0000ff" face="Courier New" size="2"&gt;presolver&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt;=none;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;set&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; &amp;lt;&lt;/FONT&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;str&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt;&amp;gt; BG; &lt;/FONT&gt;&lt;FONT color="#008000" face="Courier New" size="2"&gt;/*Origins */&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;set&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; &amp;lt;&lt;/FONT&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;str&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt;&amp;gt; SITES &lt;/FONT&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;init&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; {}; &lt;/FONT&gt;&lt;FONT color="#008000" face="Courier New" size="2"&gt;/*Destinations*/&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;set&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; &amp;lt;&lt;/FONT&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;str&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt;&amp;gt; SITESREDUCED1 &lt;/FONT&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;init&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; {}; &lt;/FONT&gt;&lt;FONT color="#008000" face="Courier New" size="2"&gt;/*Destinations*/&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#008000" face="Courier New" size="2"&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;num&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; distance {BG,SITES}; &lt;/FONT&gt;/*Read Distance between Origins and Destinations */&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;　&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;read&lt;/FONT&gt; &lt;FONT color="#0000ff" face="Courier New" size="2"&gt;data&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; SITES &lt;/FONT&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;into&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; SITES=[SITE] ; &lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;read&lt;/FONT&gt; &lt;FONT color="#0000ff" face="Courier New" size="2"&gt;data&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; Customers &lt;/FONT&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;into&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; BG=[SITE];&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;read&lt;/FONT&gt; &lt;FONT color="#0000ff" face="Courier New" size="2"&gt;data&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; SITESREDUCED1 &lt;/FONT&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;into&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; SITESREDUCED1=[SITE];&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;　&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;read&lt;/FONT&gt; &lt;FONT color="#0000ff" face="Courier New" size="2"&gt;data&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; SFDISTANCES&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;into&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; BG=[SITE]&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT face="Courier New" size="2"&gt;{j in SITES} &amp;lt; distance[SITE,j]=col(j) &amp;gt;; &lt;/FONT&gt;&lt;FONT color="#008000" face="Courier New" size="2"&gt;/* For all the origins read the distances to the destinations */&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;/* Declare Variables */&lt;/P&gt;&lt;P&gt;for {i in BG, j in SITES} distance[i,j] = round(distance[i,j]);&lt;/P&gt;&lt;P&gt;/*var Assign {BG, SITES} binary init 1; */&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;var&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; Assign {BG, SITES} &lt;/FONT&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;binary&lt;/FONT&gt; &lt;FONT color="#0000ff" face="Courier New" size="2"&gt;init&lt;/FONT&gt; &lt;STRONG&gt;&lt;FONT color="#008080" face="Courier New" size="2"&gt;1&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT face="Courier New" size="2"&gt;; &lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;num&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; distancias {BG}; &lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;min&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; DistanceS= SUM {i in BG, j in SITES} distance[i,j] * Assign [i,j]/SUM {i in BG, j in SITES} distance[i,j] ;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;/* Per each column the node is assigned only two times (for itself and with another node) skipping the first column where the node is assigned once*/&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;con&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; assign_rest_ll {j in SITESREDUCED1}: &lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT face="Courier New" size="2"&gt;sum {i in BG} Assign[i,j] = &lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT color="#008080" face="Courier New" size="2"&gt;2&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT face="Courier New" size="2"&gt;;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;/*Lower Matrix is Zero*/&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;con&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; simetry {i in BG, j in SITES}:&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT face="Courier New" size="2"&gt;if i&amp;gt;j then Assign[i,j] = &lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT color="#008080" face="Courier New" size="2"&gt;0&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT face="Courier New" size="2"&gt;;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;　/* Diagonal is 1*/&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;con&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; assing_diag {i in BG}: &lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT face="Courier New" size="2"&gt;Assign[i,i] = &lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT color="#008080" face="Courier New" size="2"&gt;1&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT face="Courier New" size="2"&gt;; &lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;/* This is the non linear constrain that I need to convert to linear */&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;con&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; row_assignment_lb{i in BG}:&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT face="Courier New" size="2"&gt;if sum {j in SITES} Assign [i,j] &amp;lt;=&lt;/FONT&gt;&lt;FONT color="#008080" face="Courier New" size="2"&gt;1&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; or &amp;gt;=&lt;/FONT&gt;&lt;FONT color="#008080" face="Courier New" size="2"&gt;5&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt;;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;solve&lt;/FONT&gt; &lt;FONT color="#0000ff" face="Courier New" size="2"&gt;with&lt;/FONT&gt; &lt;FONT color="#0000ff" face="Courier New" size="2"&gt;milp&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; / &lt;/FONT&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;primalin&lt;/FONT&gt; &lt;FONT color="#0000ff" face="Courier New" size="2"&gt;allcuts&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt;=AGGRESSIVE &lt;/FONT&gt;&lt;FONT color="#0000ff" face="Courier New" size="2"&gt;RELOBJGAP&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt;=&lt;/FONT&gt;&lt;FONT color="#008080" face="Courier New" size="2"&gt;0.1&lt;/FONT&gt;&lt;FONT face="Courier New" size="2"&gt; ;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 12 Nov 2018 20:34:58 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/proc-optmodel-how-to-convert-a-conditional-constraint-into/m-p/512337#M2481</guid>
      <dc:creator>acanaveras</dc:creator>
      <dc:date>2018-11-12T20:34:58Z</dc:date>
    </item>
    <item>
      <title>Re: proc optmodel - how to convert a conditional constraint into linear to be solved with milp</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/proc-optmodel-how-to-convert-a-conditional-constraint-into/m-p/512634#M2484</link>
      <description>&lt;P&gt;Try this:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;var IsSmall {BG} binary;
con row_assignment_lb1{i in BG}:
   sum {j in SITES} Assign [i,j] &amp;gt;= 0 * IsSmall[i] + 5 * (1 - IsSmall[i]);
con row_assignment_lb2{i in BG}:
   sum {j in SITES} Assign [i,j] &amp;lt;= 1 * IsSmall[i] + card(SITES) * (1 - IsSmall[i]);
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;If IsSmall[i] = 1, then the sum will be in [0,1].&amp;nbsp; If IsSmall[i] = 0, then the sum will be in [5,card(SITES)].&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You also should do this:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;con simetry {i in BG, j in SITES: i &amp;gt; j}:
   Assign[i,j] = 0;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Or use the FIX statement:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;for {i in BG, j in SITES: i &amp;gt; j}
   fix Assign[i,j] = 0;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Or avoid those variables altogether as in &lt;A href="https://go.documentation.sas.com/?docsetId=ormpug&amp;amp;docsetVersion=14.3&amp;amp;docsetTarget=ormpug_optmodel_examples07.htm&amp;amp;locale=en" target="_self"&gt;this documentation example&lt;/A&gt;.&lt;/P&gt;</description>
      <pubDate>Wed, 14 Nov 2018 15:04:08 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/proc-optmodel-how-to-convert-a-conditional-constraint-into/m-p/512634#M2484</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2018-11-14T15:04:08Z</dc:date>
    </item>
    <item>
      <title>Re: proc optmodel - how to convert a conditional constraint into linear to be solved with milp</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/proc-optmodel-how-to-convert-a-conditional-constraint-into/m-p/512958#M2486</link>
      <description>&lt;P&gt;Rob,&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks for your reply.. but I need to apply the same concept for a 3 dimension matrix&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Can you help me with this? This are the heuristics I want to apply:&lt;/P&gt;&lt;P&gt;- I need to cluster a set of points by proximity&amp;nbsp;&lt;/P&gt;&lt;P&gt;- Objective - I can do this by minimizing the sum of distances from all origins to all destinations for all the clusters created&lt;/P&gt;&lt;P&gt;- Constraint - Clusters must have more than x points (in example is 5)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;QUESTION:&lt;/STRONG&gt; How can I specify that if an origin is in one group, then it cannot be in other groups. I have implemented this, (as you recommended, but the problem is that the&amp;nbsp; limits are applied across the clusters.. I want to specify that if an origin is in one group... it cannot be in another group for any of the destinations.&amp;nbsp; See bellow an attempt to use your recommendation... problem is that the limits 0-1 AND 4 TO card apply for the origin across all the groups.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;proc optmodel;&lt;BR /&gt;set DEST = 1..&amp;amp;num_vars;&lt;BR /&gt;set GROUPS = 1..&amp;amp;num_groups;&lt;BR /&gt;set ORIG;&lt;BR /&gt;num dist {ORIG, DEST};&lt;BR /&gt;read data SFDISTANCES into ORIG=[_N_] {j in DEST} &amp;lt;dist[_N_,j]=col('x'||j)&amp;gt;;&lt;/P&gt;&lt;P&gt;/* Assign[i,g] = 1 if observation i assigned to group g, 0 otherwise */&lt;BR /&gt;var Assign {ORIG, DEST, GROUPS} binary;&lt;/P&gt;&lt;P&gt;Var IsOriginGroup{ ORIG,GROUPS} binary init 0;&lt;/P&gt;&lt;P&gt;con orig_assignment_lb1 {i in ORIG}:&lt;BR /&gt;sum {j in DEST, g in GROUPS} Assign [i,j,g] &amp;gt;= 0 * and {g in GROUPS} IsOriginGroup[i,g] + 4 * (1 - IsOriginGroup[i,g]);&lt;/P&gt;&lt;P&gt;con orig_assignment_lb2 {i in ORIG}:&lt;BR /&gt;sum {j in DEST, g in GROUPS} Assign [i,j,g] &amp;gt;= 1 * IsOriginGroup[i,g] + card(DEST) * (1 - IsOriginGroup[i,g]);&lt;/P&gt;&lt;P&gt;con Simetry {i in ORIG, j in DEST, g in GROUPS}:&lt;BR /&gt;Assign[i,j,g]=Assign[j,i,g];&lt;/P&gt;&lt;P&gt;con ASimetry {i in ORIG, g in GROUPS}:&lt;BR /&gt;Assign[i,i,g]= 0;&lt;/P&gt;&lt;P&gt;con NearlyEqual {g in GROUPS}:&lt;BR /&gt;sum {i in ORIG, j in DEST} Assign[i,j,g] &amp;gt;=4 ;&lt;/P&gt;&lt;P&gt;impvar GroupSum {g in GROUPS} = sum {i in ORIG,j in DEST} dist [i,j] * Assign[i,j,g];&lt;/P&gt;&lt;P&gt;min distance = sum {g in GROUPS} GroupSum[g];&lt;BR /&gt;&lt;BR /&gt;solve with milp / primalin allcuts=AGGRESSIVE RELOBJGAP=0.1 maxtime=50 ;&lt;/P&gt;&lt;P&gt;create data Allocated_Demand from&lt;BR /&gt;[ORIG DEST GROUPS]={i in ORIG, j in DEST, G IN GROUPS: Assign[i,j,g] = 1};&lt;BR /&gt;print Assign;&lt;BR /&gt;print GroupSum;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 14 Nov 2018 14:49:13 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/proc-optmodel-how-to-convert-a-conditional-constraint-into/m-p/512958#M2486</guid>
      <dc:creator>acanaveras</dc:creator>
      <dc:date>2018-11-14T14:49:13Z</dc:date>
    </item>
    <item>
      <title>Re: proc optmodel - how to convert a conditional constraint into linear to be solved with milp</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/proc-optmodel-how-to-convert-a-conditional-constraint-into/m-p/513128#M2487</link>
      <description>&lt;P&gt;I don't quite follow the logical implication you are trying to enforce.&amp;nbsp; If you can&amp;nbsp;express it in the form "if this variable = 1 then that variable = 0," I'll tell you how to enforce it with a linear constraint.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;in the mean time, there are two issues with your latest code. First, you cannot use the AND operator here:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;con orig_assignment_lb1 {i in ORIG}:
sum {j in DEST, g in GROUPS} Assign [i,j,g] &amp;gt;= 0 * and {g in GROUPS} IsOriginGroup[i,g] + 4 * (1 - IsOriginGroup[i,g]);&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Second, it is unsafe to compare to 1 here because the binary variables are unlikely to be exactly 0 or 1:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;create data Allocated_Demand from
[ORIG DEST GROUPS]={i in ORIG, j in DEST, G IN GROUPS: Assign[i,j,g] = 1};&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;It is safer&amp;nbsp;to check Assign[i,j,g] &amp;gt; 0.5 instead.&lt;/P&gt;</description>
      <pubDate>Wed, 14 Nov 2018 22:28:16 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/proc-optmodel-how-to-convert-a-conditional-constraint-into/m-p/513128#M2487</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2018-11-14T22:28:16Z</dc:date>
    </item>
  </channel>
</rss>

