Home > other >  Combinations of a given set of numbers to be as close to another known number
Combinations of a given set of numbers to be as close to another known number

Time:11-06

I have 3 drug vial sizes, 400mg 200mg and 80mg. I want to find combinations of these vials that get as close as possible to a total administered volume of 840mg. It needs to be as close as possible to 840mg but not less. I'm guessing it needs to be at most (840mg plus the smallest vial size ) - 1

I'm not sure how to approach this combinatorics question using SAS and or SQL. Any help would be appreciated.

CodePudding user response:

i adapted the SAS solution on http://rosettacode.org/wiki/Count_the_coins to give me all combinations between the max dosage (840) and the Maxdisage the smallest Vial (80) - 1 which was 919mg

%Let maxDose = 840;
%let Vials = {400,200,80};
%let SmallestVial = 80;

/* call OPTMODEL procedure in SAS/OR */
proc optmodel;
   /* declare set and names of coins */

   set Vials = {&vials};
   str name {Vials} = ['Vial1','Vial2','Vial3'];

   /* declare variables and constraint */
   var NumVials {Vials} >= 0 integer;
   con MAXDosage:
      &maxDose <= sum {i in Vials} i * NumVials[i] <= (&maxDose   &SmallestVial) - 1;

   /* call CLP solver */
   solve with CLP / findallsolns;

   /* write solutions to SAS data set */
   create data sols(drop=s) from [s]=(1.._NSOL_) {i in Vials} <col(name[i])=NumVials[i].sol[s]>;
quit;

/* print all solutions */
proc print data=sols;
run;

now i just need to place all this in a macro to use for any combination or vials and dosages, thanks

CodePudding user response:

I'd probably do something like

data solutions (keep=total count1-count3);
  vialsize1 = 400; vialsize2 = 200; vialsize3 = 80; mintotal = 840;
  do count1 = 0 to floor(mintotal/vialsize1)   1;
    do count2 = 0 to floor(mintotal/vialsize2)   1;
      do count3 = 0 to floor(mintotal/vialsize3)   1;
        total = (count1*vialsize1)   (count2*vialsize2)   (count3*vialsize3);
        ** Only output those that qualify **;
        if total >= mintotal then output;
      end;
    end;
  end;
run;

proc sort data=solutions;
  by total;

** Print smallest solution (closest to 840) **;
proc print data=solutions (obs=1);

That prints at least one of the optimal solutions if any exist. You can also just print out the full list of valid solutions by removing (obs=1).

  • Related