<?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 Newbie question on using PROC OPTMODEL for simple two-index MILP minimization in Mathematical Optimization, Discrete-Event Simulation, and OR</title>
    <link>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/361769#M1836</link>
    <description>&lt;P&gt;Hi!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have a simple problem I'm trying to code in PROC OPTMODEL (SAS 9.4, SAS/OR 14.1 on Linux x64 grid server), instead of my usual method of directly creating the MPS data set for PROC OPTMILP with a SAS data step. &amp;nbsp;But I'm striking out pretty badly, and thought I'd ask for assistance.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have a data set with three variables, i j c, sorted on i and j (i &amp;lt; j), the i and j pairs are unique, c is the cost for each pair i and j. &amp;nbsp;I'm choosing a set of least cost pairs, and each i or&amp;nbsp;j value can occur in only one of the chosen pairs (it can't occur on the left for one pair and on the right for another). &amp;nbsp;So, I want to create an array c[i,j] and binary decision variables v[i,j]. &amp;nbsp;I want to minimize sum over i and j of c[i,j]*v[i,j], I want sum over i and j of v[i,j] to add up to a specified constant number, and I have constraints that sum over i of v[i,j] + sum over k of v[j,k] &amp;lt;= 1 for each j. &amp;nbsp;I think this should be pretty simple to to do in OPTMODEL, but I haven't come close to getting anything to run. &amp;nbsp;Any assistance would be appreciated. &amp;nbsp;Thanks!&lt;/P&gt;</description>
    <pubDate>Thu, 25 May 2017 20:29:04 GMT</pubDate>
    <dc:creator>Top_Katz</dc:creator>
    <dc:date>2017-05-25T20:29:04Z</dc:date>
    <item>
      <title>Newbie question on using PROC OPTMODEL for simple two-index MILP minimization</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/361769#M1836</link>
      <description>&lt;P&gt;Hi!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have a simple problem I'm trying to code in PROC OPTMODEL (SAS 9.4, SAS/OR 14.1 on Linux x64 grid server), instead of my usual method of directly creating the MPS data set for PROC OPTMILP with a SAS data step. &amp;nbsp;But I'm striking out pretty badly, and thought I'd ask for assistance.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have a data set with three variables, i j c, sorted on i and j (i &amp;lt; j), the i and j pairs are unique, c is the cost for each pair i and j. &amp;nbsp;I'm choosing a set of least cost pairs, and each i or&amp;nbsp;j value can occur in only one of the chosen pairs (it can't occur on the left for one pair and on the right for another). &amp;nbsp;So, I want to create an array c[i,j] and binary decision variables v[i,j]. &amp;nbsp;I want to minimize sum over i and j of c[i,j]*v[i,j], I want sum over i and j of v[i,j] to add up to a specified constant number, and I have constraints that sum over i of v[i,j] + sum over k of v[j,k] &amp;lt;= 1 for each j. &amp;nbsp;I think this should be pretty simple to to do in OPTMODEL, but I haven't come close to getting anything to run. &amp;nbsp;Any assistance would be appreciated. &amp;nbsp;Thanks!&lt;/P&gt;</description>
      <pubDate>Thu, 25 May 2017 20:29:04 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/361769#M1836</guid>
      <dc:creator>Top_Katz</dc:creator>
      <dc:date>2017-05-25T20:29:04Z</dc:date>
    </item>
    <item>
      <title>Re: Newbie question on using PROC OPTMODEL for simple two-index MILP minimization</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/361774#M1837</link>
      <description>&lt;P&gt;If I understand correctly, the following should do what you want (where I have used 3 as the "specified constant number"):&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc optmodel;
   set &amp;lt;num,num&amp;gt; EDGES;
   num c {EDGES};
   read data indata into EDGES=[i j] c;
   set NODES = union {&amp;lt;i,j&amp;gt; in EDGES} {i,j};

   var V {EDGES} binary;
   min TotalCost = sum {&amp;lt;i,j&amp;gt; in EDGES} c[i,j] * V[i,j];
   con Cardinality:
      sum {&amp;lt;i,j&amp;gt; in EDGES} V[i,j] = 3;
   con Balance {j in NODES}:
      sum {&amp;lt;i,(j)&amp;gt; in EDGES} V[i,j] + sum {&amp;lt;(j),k&amp;gt; in EDGES} V[j,k] &amp;lt;= 1; 

   solve;
   print V;
   create data outdata from [i j] c V;
quit;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;For learning PROC OPTMODEL, you might find &lt;A href="http://go.documentation.sas.com/?docsetId=ormpex&amp;amp;docsetTarget=titlepage.htm&amp;amp;docsetVersion=14.2&amp;amp;locale=en" target="_self"&gt;this examples book&lt;/A&gt;&amp;nbsp;useful. &amp;nbsp;In particular, &lt;A href="http://go.documentation.sas.com/?docsetId=ormpex&amp;amp;docsetVersion=14.2&amp;amp;docsetTarget=ormpex_ex19_sect010.htm&amp;amp;locale=en" target="_self"&gt;this example&lt;/A&gt; illustrates a side-constrained network flow problem.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 25 May 2017 20:58:02 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/361774#M1837</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2017-05-25T20:58:02Z</dc:date>
    </item>
    <item>
      <title>Re: Newbie question on using PROC OPTMODEL for simple two-index MILP minimization</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/361780#M1840</link>
      <description>You nailed it, RobPratt! Thank you so much!!</description>
      <pubDate>Thu, 25 May 2017 21:22:34 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/361780#M1840</guid>
      <dc:creator>Top_Katz</dc:creator>
      <dc:date>2017-05-25T21:22:34Z</dc:date>
    </item>
    <item>
      <title>Re: Newbie question on using PROC OPTMODEL for simple two-index MILP minimization</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/368860#M1884</link>
      <description>&lt;P&gt;hey &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/1636"&gt;@RobPratt&lt;/a&gt;, I am struggling with a simple modification to the above code.&amp;nbsp; I'm really really new to SAS so please do forgive me if this is something very simple -- also new to the forum;&amp;nbsp; I've looked all over the web and this example is the closest I've found where the data is in the format which I've got and the problem statement is similar.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;In my case I have different constraints:&amp;nbsp; i have destinations(n=15Kish) and origins(100ish)&amp;nbsp; (i=destinations and j=origins) and must have every i assigned to only one j (that is each customer is assigned to only one distribution site).&amp;nbsp; The costs are drive times from the distribution hub to the customer and the objective is to minimize the drive times -- in short it's basically assigning a customer to it's associated site with the shortest drive time.&amp;nbsp; heres the mod i attempted which isn't working for me; sas tells me that the solution is "infeasible" which seems a bit odd to me.&amp;nbsp; in the simple case of 10 destinations and 3 distribution sites i also get the "infeasible" issue so I'm thinking it's my constraint line which is off.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;specifically I used the following constraint code:&lt;/P&gt;&lt;P&gt;/*device assigned to only one site*/&lt;BR /&gt;&amp;nbsp; con Balance {i in NODES}:&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sum {&amp;lt;(i),j&amp;gt; in SITEStoDEVICES} V[i,j] = 1;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;which is a modification of the constraints from the OP.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Without the constraint I get all V's as zero -- I think thats meaning no assignemnts are made which of course minimized drive time to be zero overall.&amp;nbsp; However, I set this up to ensure C1-C5 are assigned to S1 while C6-C10 are assigned to S2 with non assigned to S3.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Please help!&amp;nbsp; I'm just not understanding something simple here.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;in short the overall project objective that I'm trying to achieve is&lt;/P&gt;&lt;P&gt;1) assign customers to the associated sites with lowest drive times&lt;/P&gt;&lt;P&gt;2) get the all customers outside of a specified drive time&lt;/P&gt;&lt;P&gt;3) take the group from (2) and determine&amp;nbsp; where would be the best new sites to have as distribution hubs to ensure all customers are within the specified drive time.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;next phase would be to optimize on lowest number of distro hubs such that all customers are within a certain drive time but thats outsie the scope of my imediate need.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;below is the example data/code.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;data DTMS;&lt;BR /&gt;input destination&amp;nbsp; : $11. origin : $11. DriveTime;&lt;BR /&gt;datalines;&lt;BR /&gt;C1 S1 .15&lt;BR /&gt;C2 S1 .10&lt;BR /&gt;C3 S1 .11&lt;BR /&gt;C4 S1 .12&lt;BR /&gt;C5 S1 .13&lt;BR /&gt;C1 S2 5.15&lt;BR /&gt;C2 S2 5.10&lt;BR /&gt;C3 S2 5.11&lt;BR /&gt;C4 S2 5.12&lt;BR /&gt;C5 S2 5.13&lt;BR /&gt;C1 S2 7.15&lt;BR /&gt;C2 S3 7.10&lt;BR /&gt;C3 S3 7.11&lt;BR /&gt;C4 S3 7.12&lt;BR /&gt;C5 S3 7.13&lt;BR /&gt;C6&amp;nbsp; S1 5.15&lt;BR /&gt;C7&amp;nbsp; S1 5.10&lt;BR /&gt;C8&amp;nbsp; S1 5.11&lt;BR /&gt;C9&amp;nbsp; S1 5.12&lt;BR /&gt;C10 S1 5.13&lt;BR /&gt;C6&amp;nbsp; S2 .15&lt;BR /&gt;C7&amp;nbsp; S2 .10&lt;BR /&gt;C8&amp;nbsp; S2 .11&lt;BR /&gt;C9&amp;nbsp; S2 .12&lt;BR /&gt;C10 S2 .13&lt;BR /&gt;C6&amp;nbsp; S3 6.15&lt;BR /&gt;C7&amp;nbsp; S3 6.10&lt;BR /&gt;C8&amp;nbsp; S3 6.11&lt;BR /&gt;C9&amp;nbsp; S3 6.12&lt;BR /&gt;C10 S3 6.13&lt;BR /&gt;;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;proc optmodel;&lt;BR /&gt;set &amp;lt;str, str&amp;gt; SITEStoDEVICES;&lt;BR /&gt;num DriveTime {SITEStoDEVICES};&lt;BR /&gt;read data DTMS into SITEStoDEVICES = [destination origin] DriveTime;&lt;BR /&gt;&lt;BR /&gt;set NODES = union {&amp;lt;i,j&amp;gt; in SITEStoDEVICES} {i,j};&lt;BR /&gt;&lt;BR /&gt;/*assignment variable*/&lt;BR /&gt;var V {SITEStoDEVICES} binary;&lt;BR /&gt;&lt;BR /&gt;/*objective function*/&lt;BR /&gt;&amp;nbsp;&amp;nbsp; min TotalCost = sum {&amp;lt;i,j&amp;gt; in SITEStoDEVICES} DriveTime[i,j] * V[i,j];&lt;BR /&gt;&amp;nbsp;&lt;BR /&gt;/*device assigned to only one site*/&lt;BR /&gt;&amp;nbsp; con Balance {i in NODES}:&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sum {&amp;lt;(i),j&amp;gt; in SITEStoDEVICES} V[i,j] = 1;&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;solve;&lt;BR /&gt;&lt;BR /&gt;/*&amp;nbsp;&amp;nbsp; print V;*/&lt;BR /&gt;&amp;nbsp;&amp;nbsp; create data outdata from [i j] DriveTime V;&lt;BR /&gt;run;&lt;BR /&gt;&lt;BR /&gt;&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;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 20 Jun 2017 18:27:48 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/368860#M1884</guid>
      <dc:creator>whatkins</dc:creator>
      <dc:date>2017-06-20T18:27:48Z</dc:date>
    </item>
    <item>
      <title>Re: Newbie question on using PROC OPTMODEL for simple two-index MILP minimization</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/368889#M1885</link>
      <description>&lt;P&gt;&lt;A href="http://go.documentation.sas.com/?docsetId=ormpug&amp;amp;docsetVersion=14.2&amp;amp;docsetTarget=ormpug_optmodel_examples07.htm&amp;amp;locale=en" target="_self"&gt;This doc example&lt;/A&gt; is closer to what you want. &amp;nbsp;A big difference between your problem and the one from&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/145776"&gt;@Top_Katz&lt;/a&gt;&amp;nbsp;is that you have a bipartite network, and you need to treat the two sets of nodes differently.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The following two changes will accomplish your first step:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/*set NODES = union {&amp;lt;i,j&amp;gt; in SITEStoDEVICES} {i,j};*/
set CUSTOMERS = setof {&amp;lt;i,j&amp;gt; in SITEStoDEVICES} i;
set SITES     = setof {&amp;lt;i,j&amp;gt; in SITEStoDEVICES} j;

/*  con Balance {i in NODES}:*/
  con Balance {i in CUSTOMERS}:
      sum {&amp;lt;(i),j&amp;gt; in SITEStoDEVICES} V[i,j] = 1;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;But you do not actually need to solve an optimization problem to do that step. &amp;nbsp;You can just explicitly compute the minimum for each customer separately:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;   str argminDriveTime {CUSTOMERS};
   num minDriveTime;
   for {i in CUSTOMERS} do;
      minDriveTime = constant('BIG');
      for {&amp;lt;(i),j&amp;gt; in SITEStoDEVICES} do;
         if minDriveTime &amp;gt; DriveTime[i,j] then do;
            minDriveTime = DriveTime[i,j];
            argminDriveTime[i] = j;
         end;
      end;
      V[i,argminDriveTime[i]] = 1;
   end;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Tue, 20 Jun 2017 19:09:15 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/368889#M1885</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2017-06-20T19:09:15Z</dc:date>
    </item>
    <item>
      <title>Re: Newbie question on using PROC OPTMODEL for simple two-index MILP minimization</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/368909#M1886</link>
      <description>&lt;P&gt;wow that was quick.&amp;nbsp; Thank you &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/1636"&gt;@RobPratt&lt;/a&gt;; much appreciated.&amp;nbsp; The solution worked for my simple case and I'm figuring it'll do for the full scope case.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;i see where you're going with the straight up minimum selection for this simple situation.&amp;nbsp; however, i needed to know how to make the optimization portion work for the second phase of the project which is coming up.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;the issue i ran into with the referenced example is this portion of the code&lt;/P&gt;&lt;PRE class="xis-codeBlock"&gt;   /* distance from customer i to site j */
   num dist {i in CUSTOMERS, j in SITES}
       = sqrt((x[i] - x[j])^2 + (y[i] - y[j])^2);

   read data cdata into CUSTOMERS=[name] x y demand;
   read data sdata into SITES=[name] x y fixed_charge;&lt;/PRE&gt;&lt;P&gt;specifically I ran into was the fact that my data is vertically strutured with all the customer/site combos with their associated drive times.&amp;nbsp; The example assumed two data sets, one for customers and one for sites with both having x/y coordinants and the "cost" is distance which is calculable using the euclidian metric; I was able to easily enough chage that to use lat/longs and geo distances but distances doen't equate to drive times.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I wasn't sure how to modify the code to do a "group by" sort of thing with a single data frame.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I could easily enough get the data into three frames where I had customers, sites, and then drive times in a third frame but wasn't sure how to get the dist variable from the third frame by looking up the customer / site combo; and unfortunantly the drive times is not a calculable metric given the lat/longs of my customers/sites.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I would love to see how you'd modify the referenced code to do either&lt;/P&gt;&lt;P&gt;1) a look up for the dist variable from a third data frame&lt;/P&gt;&lt;P&gt;and/or&lt;/P&gt;&lt;P&gt;2) use a single data frame with customer/site combos and a seperate third column with the "dist" or cost variable.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;being so new SAS for these types of problems has really been fun but challenging.&amp;nbsp; Your help has been infinately valuable and I thank you again!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 20 Jun 2017 19:27:31 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/368909#M1886</guid>
      <dc:creator>whatkins</dc:creator>
      <dc:date>2017-06-20T19:27:31Z</dc:date>
    </item>
    <item>
      <title>Re: Newbie question on using PROC OPTMODEL for simple two-index MILP minimization</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/368914#M1887</link>
      <description>&lt;P&gt;Glad to help.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Your original READ DATA statement is already perfectly suited for the case that the drive times come from a sparse table instead of from a formula.&lt;/P&gt;</description>
      <pubDate>Tue, 20 Jun 2017 19:35:47 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/368914#M1887</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2017-06-20T19:35:47Z</dc:date>
    </item>
    <item>
      <title>Re: Newbie question on using PROC OPTMODEL for simple two-index MILP minimization</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/368917#M1888</link>
      <description>good to know. I'll play around with it now that I've seen a working example and should be able to self serve for the needed finale!</description>
      <pubDate>Tue, 20 Jun 2017 19:49:36 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/368917#M1888</guid>
      <dc:creator>whatkins</dc:creator>
      <dc:date>2017-06-20T19:49:36Z</dc:date>
    </item>
    <item>
      <title>Re: Newbie question on using PROC OPTMODEL for simple two-index MILP minimization</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/391265#M1967</link>
      <description>&lt;P&gt;Good Day Rob,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;As a follow up to this question I am now attempting to place a constraint on the model in which certain sites are known to be built for this facility location problem.&amp;nbsp; In short, we know from a business persepective specific locations must be built and want the remaining locations to be greefield solutioned.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here's what I've got.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Variable in my data frame "REQ_LOC_BY_MGMT_NUM" has 1's where the site is a known location to build and 0's otherwise.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I've tried the following:&lt;/P&gt;&lt;P&gt;added to the preamble of the code&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;num&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; REQ_LOC_BY_MGMT_NUM {SITEStoDEVICES};&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;added to the objective function statements&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;min&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; TotalDriveTime = sum {&amp;lt;customerName, siteName&amp;gt; in SITEStoDEVICES} DriveTimeMin[customerName, siteName] * V[customerName, siteName];&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;min&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; totalbuilds = sum {&amp;lt;deviceSiteId, techSiteId&amp;gt; in SITEStoDEVICES} Build[techSiteId];&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT face="Courier New" size="3"&gt;and new constraint&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;/* must build specific sites */&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;con&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; mustbuild {deviceSiteId in CUSTOMERS, techSiteId in SITES}:&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;REQ_LOC_BY_MGMT_NUM[deviceSiteId,techSiteId] &amp;lt;= Build[techSiteId];&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;it's throwing the error:&lt;/P&gt;&lt;P&gt;ERROR: The array subscript 'V['xxxxxxxxxxxxx','xxxxxxxxxxxxxxxxx']' is invalid at line 53 column 7.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thoughts on how to make this work?&amp;nbsp; It's probably me just not understainding the example from here:&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;A href="http://go.documentation.sas.com/?docsetId=ormpug&amp;amp;docsetTarget=ormpug_optmodel_examples07.htm&amp;amp;docsetVersion=14.2&amp;amp;locale=en" target="_blank"&gt;http://go.documentation.sas.com/?docsetId=ormpug&amp;amp;docsetTarget=ormpug_optmodel_examples07.htm&amp;amp;docsetVersion=14.2&amp;amp;locale=en&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks again!&lt;/P&gt;</description>
      <pubDate>Mon, 28 Aug 2017 16:13:48 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/391265#M1967</guid>
      <dc:creator>whatkins</dc:creator>
      <dc:date>2017-08-28T16:13:48Z</dc:date>
    </item>
    <item>
      <title>Re: Newbie question on using PROC OPTMODEL for simple two-index MILP minimization</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/391304#M1968</link>
      <description>&lt;P&gt;It sounds to me like you want the following:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;num REQ_LOC_BY_MGMT_NUM {SITES};
 
con mustbuild {techSiteId in SITES: REQ_LOC_BY_MGMT_NUM[techSiteId] = 1}:
   Build[techSiteId] = 1;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Or you can use the FIX statement instead of declaring a single-variable constraint:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;for {techSiteId in SITES: REQ_LOC_BY_MGMT_NUM[techSiteId] = 1}
   fix Build[techSiteId] = 1;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;If these changes don't resolve your errors, please share the full code and data.&lt;/P&gt;</description>
      <pubDate>Mon, 28 Aug 2017 19:01:11 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/391304#M1968</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2017-08-28T19:01:11Z</dc:date>
    </item>
    <item>
      <title>Re: Newbie question on using PROC OPTMODEL for simple two-index MILP minimization</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/391313#M1969</link>
      <description>&lt;P&gt;Thanks for the quick reply Rob.&amp;nbsp; I'm running into errors when trying to read the data "REQ_LOC_BY_MGMT_NUM" into the model initially.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I've placed the statement "&lt;FONT color="#0000ff" face="Courier New"&gt;num&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; REQ_LOC_BY_MGMT_NUM {SITES};" both before and after the SITES node creation.&amp;nbsp; in both cases I get an error.&amp;nbsp; The first case I get the error &lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;ERROR 525-782: The symbol 'SITES' is unknown.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;and in the second case (placement after the SITES node create)&lt;/P&gt;&lt;P&gt;ERROR 525-782: The symbol 'REQ_LOC_BY_MGMT_NUM' is unknown.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Specifically&amp;nbsp;an example of what I've&amp;nbsp;got is here:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;/* Data Example */&lt;/P&gt;&lt;P&gt;&lt;FONT color="#000080" face="Courier New" size="3"&gt;&lt;STRONG&gt;data&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; DTMS;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;input&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; destination : &lt;/FONT&gt;&lt;FONT color="#008080" face="Courier New" size="3"&gt;$11.&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT face="Courier New" size="3"&gt;origin : &lt;/FONT&gt;&lt;FONT color="#008080" face="Courier New" size="3"&gt;$11.&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT face="Courier New" size="3"&gt;REQ_LOC_BY_MGMT_NUM : &lt;/FONT&gt;&lt;FONT color="#008080" face="Courier New" size="3"&gt;best8.&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;DriveTime ;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;datalines&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt;;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;C1 S1 0 .15&lt;/P&gt;&lt;P&gt;C2 S1 0 .10&lt;/P&gt;&lt;P&gt;C3 S1 0 .11&lt;/P&gt;&lt;P&gt;C4 S1 0 .12&lt;/P&gt;&lt;P&gt;C5 S1 0 .13&lt;/P&gt;&lt;P&gt;C1 S2 0 5.15&lt;/P&gt;&lt;P&gt;C2 S2 0 5.10&lt;/P&gt;&lt;P&gt;C3 S2 0 5.11&lt;/P&gt;&lt;P&gt;C4 S2 0 5.12&lt;/P&gt;&lt;P&gt;C5 S2 0 5.13&lt;/P&gt;&lt;P&gt;C1 S3 0 7.15&lt;/P&gt;&lt;P&gt;C2 S3 1 7.10&lt;/P&gt;&lt;P&gt;C3 S3 1 7.11&lt;/P&gt;&lt;P&gt;C4 S3 1 7.12&lt;/P&gt;&lt;P&gt;C5 S3 1 7.13&lt;/P&gt;&lt;P&gt;C6 S1 0 5.15&lt;/P&gt;&lt;P&gt;C7 S1 0 5.10&lt;/P&gt;&lt;P&gt;C8 S1 0 5.11&lt;/P&gt;&lt;P&gt;C9 S1 0 5.12&lt;/P&gt;&lt;P&gt;C10 S1 0 5.13&lt;/P&gt;&lt;P&gt;C6 S2 0 .15&lt;/P&gt;&lt;P&gt;C7 S2 0 .10&lt;/P&gt;&lt;P&gt;C8 S2 0 .11&lt;/P&gt;&lt;P&gt;C9 S2 0 .12&lt;/P&gt;&lt;P&gt;C10 S2 0 .13&lt;/P&gt;&lt;P&gt;C6 S3 1 6.15&lt;/P&gt;&lt;P&gt;C7 S3 1 6.10&lt;/P&gt;&lt;P&gt;C8 S3 1 6.11&lt;/P&gt;&lt;P&gt;C9 S3 1 6.12&lt;/P&gt;&lt;P&gt;C10 S3 1 6.13&lt;/P&gt;&lt;P&gt;;&lt;/P&gt;&lt;P&gt;　&lt;/P&gt;&lt;P&gt;&lt;FONT color="#000080" face="Courier New" size="3"&gt;&lt;STRONG&gt;proc&lt;/STRONG&gt;&lt;/FONT&gt; &lt;STRONG&gt;&lt;FONT color="#000080" face="Courier New" size="3"&gt;optmodel&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT face="Courier New" size="3"&gt;;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;set&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; &amp;lt;str, str&amp;gt; SITEStoDEVICES;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;num&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; DriveTime {SITEStoDEVICES};&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;read&lt;/FONT&gt; &lt;FONT color="#0000ff" face="Courier New" size="3"&gt;data&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; DTMS into SITEStoDEVICES = [destination origin] DriveTime REQ_LOC_BY_MGMT_NUM;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;set&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; CUSTOMERS = setof {&amp;lt;i,j&amp;gt; in SITEStoDEVICES} i;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;set&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; SITES = setof {&amp;lt;i,j&amp;gt; in SITEStoDEVICES} j;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;num&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; REQ_LOC_BY_MGMT_NUM {SITES};&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;/*assignment variable*/&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;var&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; V {SITEStoDEVICES} &lt;/FONT&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;binary&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt;;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;var&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; Build {SITEStoDEVICES} &lt;/FONT&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;binary&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt;;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;/* objective functions */&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;min&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; TotalCost = sum {&amp;lt;i,j&amp;gt; in SITEStoDEVICES} DriveTime[i,j] * V[i,j];&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;min&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; totalbuilds = sum {&amp;lt;deviceSiteId, techSiteId&amp;gt; in SITEStoDEVICES} Build[techSiteId];&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;/*device assigned to only one site*/&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;con&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; Balance {i in CUSTOMERS}:&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT face="Courier New" size="3"&gt;sum {&amp;lt;(i),j&amp;gt; in SITEStoDEVICES} V[i,j] = &lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT color="#008080" face="Courier New" size="3"&gt;1&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT face="Courier New" size="3"&gt;;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;/* must build sites with assigned locations */&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;con&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; link {deviceSiteId in CUSTOMERS, techSiteId in SITES}:&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;V[deviceSiteId,techSiteId] &amp;lt;= Build[techSiteId];&lt;/P&gt;&lt;P&gt;/*must build certain sites*/&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;con&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; mustbuild {techSiteId in SITES: REQ_LOC_BY_MGMT_NUM[techSiteId] = &lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT color="#008080" face="Courier New" size="3"&gt;1&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT face="Courier New" size="3"&gt;}:&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT face="Courier New" size="3"&gt;Build[techSiteId] = &lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT color="#008080" face="Courier New" size="3"&gt;1&lt;/FONT&gt;&lt;/STRONG&gt;&lt;FONT face="Courier New" size="3"&gt;;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;/*for {techSiteId in SITES: REQ_LOC_BY_MGMT_NUM[techSiteId] = 1}*/&lt;/P&gt;&lt;P&gt;/* fix Build[techSiteId] = 1;*/&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;solve&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt;;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;/* print V;*/&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;create&lt;/FONT&gt; &lt;FONT color="#0000ff" face="Courier New" size="3"&gt;data&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; outdata from [i j] DriveTime V Build REQ_LOC_BY_MGMT_NUM;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#000080" face="Courier New" size="3"&gt;&lt;STRONG&gt;run&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt;;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 28 Aug 2017 19:39:41 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/391313#M1969</guid>
      <dc:creator>whatkins</dc:creator>
      <dc:date>2017-08-28T19:39:41Z</dc:date>
    </item>
    <item>
      <title>Re: Newbie question on using PROC OPTMODEL for simple two-index MILP minimization</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/391315#M1970</link>
      <description>&lt;P&gt;the line&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;var&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; Build {&lt;/FONT&gt;SITEStoDEVICES} b&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;inary&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt;; &lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT face="Courier New" size="3"&gt;should read &lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;var&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt; Build {SITES} &lt;/FONT&gt;&lt;FONT color="#0000ff" face="Courier New" size="3"&gt;binary&lt;/FONT&gt;&lt;FONT face="Courier New" size="3"&gt;;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT face="Courier New" size="3"&gt;in the example code.&amp;nbsp; My apologies for being unclear there.&lt;/FONT&gt;&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;</description>
      <pubDate>Mon, 28 Aug 2017 19:56:01 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/391315#M1970</guid>
      <dc:creator>whatkins</dc:creator>
      <dc:date>2017-08-28T19:56:01Z</dc:date>
    </item>
    <item>
      <title>Re: Newbie question on using PROC OPTMODEL for simple two-index MILP minimization</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/391317#M1971</link>
      <description>&lt;P&gt;You should use a separate data set for&amp;nbsp;REQ_LOC_BY_MGMT_NUM:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data SiteData;
   input site $ REQ_LOC_BY_MGMT_NUM;
   datalines;
S1 0
S2 0
S3 1
;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;And then you can read it as follows:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;read data SiteData into [site] REQ_LOC_BY_MGMT_NUM;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The Build variable needs to be indexed over SITES:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;var Build {SITES} binary;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;You have declared two objectives. &amp;nbsp;By default, only the second one is used. &amp;nbsp;Because Build depends only on site, I think the following makes more sense:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;min totalbuilds = sum {techSiteId in SITES} Build[techSiteId];&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;You should also create two separate output data sets:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;create data outdata from [i j] DriveTime V;
create data outdata2 from [j] Build REQ_LOC_BY_MGMT_NUM;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Or use an explicit [j] index as follows:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;create data outdata from [i j] DriveTime V Build[j] REQ_LOC_BY_MGMT_NUM[j];
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Finally, replace the RUN with QUIT.&lt;/P&gt;</description>
      <pubDate>Mon, 28 Aug 2017 20:10:15 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/391317#M1971</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2017-08-28T20:10:15Z</dc:date>
    </item>
    <item>
      <title>Re: Newbie question on using PROC OPTMODEL for simple two-index MILP minimization</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/391329#M1972</link>
      <description>&lt;P&gt;Thanks for the help Rob.&amp;nbsp; With the attempt to minimize number of builds based on both minimizing drivetimes and the known locations to build I came up with this.&amp;nbsp; If this looks off to you let me know but it appears to work with the following data as expected (sites 1, 2, and 3 are built with the only customer assiged to site 3 being C11).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc optmodel;
set &amp;lt;str, str&amp;gt; SITEStoDEVICES;
num DriveTime {SITEStoDEVICES};
read data DTMS into SITEStoDEVICES = [destination origin] DriveTime;

set CUSTOMERS = setof {&amp;lt;i,j&amp;gt; in SITEStoDEVICES} i;
/*set SITES     = setof {&amp;lt;i,j&amp;gt; in SITEStoDEVICES} j;*/

/*assignment variable*/
var V {SITEStoDEVICES} binary;

set &amp;lt;str&amp;gt; SITES;
num REQ_LOC_BY_MGMT_NUM {SITES};
read data SiteData into SITES =  [site] REQ_LOC_BY_MGMT_NUM;

/* build variable*/
var Build {SITES} binary;

/* objective functions */
/*   min TotalCost   = sum {&amp;lt;i,j&amp;gt; in SITEStoDEVICES} DriveTime[i,j] * V[i,j];*/
/*   min totalbuilds = sum {&amp;lt;deviceSiteId, techSiteId&amp;gt; in SITEStoDEVICES} Build[techSiteId];*/

min cost = sum {i in CUSTOMERS, j in SITES} V[i,j] * DriveTime[i,j];
min totalcost = cost + sum{j in SITES} Build[j];
/*min totalbuilds = sum {&amp;lt;deviceSiteId, techSiteId&amp;gt; in SITEStoDEVICES} Build[techSiteId]*DriveTime[deviceSiteId, techSiteId];*/
 
/*device assigned to only one site and every device is assigned*/
con Balance {i in CUSTOMERS}:
      sum {&amp;lt;(i),j&amp;gt; in SITEStoDEVICES} V[i,j] = 1;

/* must build sites */
con mustbuild {techSiteId in SITES: REQ_LOC_BY_MGMT_NUM[techSiteId] = 1}:
   Build[techSiteId] = 1;

/* must build sites with assigned locations */
con link {deviceSiteId in CUSTOMERS, techSiteId in SITES}:
      V[deviceSiteId,techSiteId] &amp;lt;= Build[techSiteId];

/* do not assign customer to site more than x units away */
con distance_at_most {i in CUSTOMERS, j in SITES: DriveTime[i,j] &amp;gt; 1.99}:
      V[i,j] = 0;

/*    solve;*/
solve with milp/timetype=real;

create data outdata from [i j] DriveTime V Build[j] REQ_LOC_BY_MGMT_NUM[j];

run;&lt;/CODE&gt;&lt;/PRE&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;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data SiteData;
   input site $ REQ_LOC_BY_MGMT_NUM;
   datalines;
S1 0
S2 0
S3 1
S4 0
;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data DTMS;
input destination  : $11. 
      origin : $11. 
	  REQ_LOC_BY_MGMT_NUM : best8.
      DriveTime ;
datalines;
C1 S1 0 .15
C2 S1 0 .10
C3 S1 0 .11
C4 S1 0 .12
C5 S1 0 .13
C6  S1 0 2.15
C7  S1 0 2.10
C8  S1 0 2.11
C9  S1 0 2.12
C10 S1 0 2.13
C11 S1 0 1.99
C1 S2 0 2.75
C2 S2 0 2.70
C3 S2 0 2.71
C4 S2 0 2.72
C5 S2 0 2.73
C6  S2 0 .15
C7  S2 0 .10
C8  S2 0 .11
C9  S2 0 .12
C10 S2 0 .13
C11 S2 0 2.99
C1 S3 1 7.15
C2 S3 1 7.10
C3 S3 1 7.11
C4 S3 1 7.12
C5 S3 1 7.13
C6  S3 1 6.15
C7  S3 1 6.10
C8  S3 1 6.11
C9  S3 1 6.12
C10 S3 1 6.13
C11 S3 1 1.05
C1 S4 0 0.15
C2 S4 0 0.10
C3 S4 0 0.11
C4 S4 0 0.12
C5 S4 0 7.13
C6  S4 0 0.15
C7  S4 0 0.10
C8  S4 0 0.11
C9  S4 0 7.12
C10 S4 0 7.13
C11 S4 0 8.79
;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Mon, 28 Aug 2017 21:24:33 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Newbie-question-on-using-PROC-OPTMODEL-for-simple-two-index-MILP/m-p/391329#M1972</guid>
      <dc:creator>whatkins</dc:creator>
      <dc:date>2017-08-28T21:24:33Z</dc:date>
    </item>
  </channel>
</rss>

