Why I do not get the right answer - optimization

I think logically the following code is right but I get the wrong answer:
.mod file:
set R := {1,2};
set D1 := {1,2,4,5};
set P1 := {1,2,3,4,5};
var V{D1,R}, binary;
param Ud{D1,R} ;
param U{P1,R} ;
minimize obj{p in D1, r in R}: V[p,r] * (Ud[p,r]+ sum{j in P1: j!=p} U[j,r]);
s.t. a10{ r in R }: sum{p in D1} V[p,r]=2 ;
.dat file:
param Ud: 1 2:=
1 -10 -6
2 -20 -4
4 1 -10
5 -4 -4;
param U: 1 2 :=
1 -8.1 -3
2 -6.8 -8
3 -7.2 1
4 -16 -4
5 -6.8 -4;
Basically for each r and for two p , I want to minimize (Ud[p,r] + sum{j in P: j!=p} U[j,r])
But it always give me V[1,r]=v[5,r]=1 even if V[2,r] minimize obj function.
I except to get V[2,r]=1 because -20 + (-8.1-7.2 -16-6.8) is the most negative.

Your syntax for the objective function is incorrect; it should be
minimize obj: sum {p in D1, r in R} V[p,r] * (Ud[p,r]+ sum{j in P1: j != p} U[j,r]);
(Note the location of the colon (:), and the presence of the sum.) To be honest I'm not exactly sure what AMPL was doing in response to your objective function, but I would just treat the results as unpredictable.
With the revised objective function, the optimal solution is:
ampl: display V;
V :=
1 1 1
1 2 1
2 1 1
2 2 0
4 1 0
4 2 1
5 1 0
5 2 0
;

Related

How do I do it to just get a integer solution in AMPL?

We make phones. We have selling price, production cost, profit.
The goal is to maximize profits.
The following components are required to assemble each phone.
Maximum quantity of components .
Orders (so many phones were ordered from us, we sold them) :
Here is my mod file:
set PHONE;
set COMPONENTS;
param price {PHONE} >= 0;
param cost {PHONE} >= 0;
param maxComponents {COMPONENTS} >= 0;
param ordered {PHONE} >= 0;
param matrix {COMPONENTS, PHONE}; #The amount of components needed to make a particular phone.
var x {PHONE} >= 0; # Number of manufactured telephones.
maximize profit: sum {i in PHONE} ( ordered[i] * price[i] - x[i] * cost[i] );
subject to min_manufacture {i in PHONE}:
x[i] >= ordered[i]; # We must produce a minimum of what is ordered
subject to component {i in COMPONENTS}:
sum {j in PHONE} matrix[i,j] * x[j] <= maxComponents[i]; # The number of components used must not exceed the maximum.
subject to min_quantity {i in COMPONENTS, l in PHONE}:
sum {j in PHONE} matrix[i,j] * x[j] >= matrix[i,l]; # Minimum quantity used per component if we manufacture at least one telephone. For example, a triple phone requires at least 2 of the five components.
and dat file:
set PHONE := 1 2 3 4 5;
set COMPONENTS:= 1 2 3 4 5 6 7;
param price :=
1 450
2 120
3 500
4 390
5 100;
param cost :=
1 370
2 90
3 400
4 320
5 70;
param maxComponents :=
1 28
2 20
3 8
4 30
5 47
6 27
7 15;
param ordered :=
1 3
2 5
3 5
4 0
5 10;
param matrix: 1 2 3 4 5 :=
1 1 1 0 0 0
2 1 1 0 0 0
3 1 0 0 0 0
4 1 0 1 1 0
5 0 0 2 1 1
6 0 0 2 1 0
7 0 0 1 1 0;
The problem is that if, for example, the maximum amount of sixth components is three, the maximum amount of seventh components is two , then 1.5 is produced from the triple phone which cannot be . And quantity used of the fourth, fifth, sixth, seventh components for the triple phone 1,5 3 3 1,5 which also cannot be.
How do I do it to just get a integer solution?
Because if I write to the variable x that it's an integer, I get zero for everything.
My run file:
model phone.mod;
data phone.dat;
option presolve 0;
option solver cplex;
solve;
display profit, x;
display {i in COMPONENTS, j in PHONE} matrix[i,j] * x[j];
You need to declare the relevant variables as integer, like so:
var x {PHONE} >= 0 integer;
Some solvers are not able to deal with integer constraints and may ignore that constraint (with a warning message) but CPLEX should be fine.

how I can initialize a parameter in AMPL when it is defined on multiple sets?

Suppose I have
param m; #number of modes
param n; #number of individual
param a; #number of alternatives
param f; #number of household
set M, default{1..m}; #set of modes
set N, default{1..n}; #set of individuals
set A, default{1..a}; #set of alternatives
set F, default{1..f}; #set of family
set E, within F cross N
How I can initialize param X{E,M,A} ?
Suppose
a:=2 , m:=3 , n:= 4 f:=2;
and set E is defined:
set E:= 1 1 1 2 2 3 2 4 ;
You can declare the parameter just as you suggested:
param X{E,M,A};
Now, if you want to provide a default value (which I assume is what you are asking), you can do it in the usual way:
param X{E,M,A} default 0;
Then provide some non-default values in the .dat file, e.g.,:
param: X :=
1 1 1 2 5
2 3 2 1 6;
Note that AMPL doesn't fill the default values into the parameter until you call solve. From the AMPL book, p. 120:
The expression that gives the default value of a parameter is evaluated only when the parameter’s value is first needed, such as when an objective or constraint that uses the parameter is processed by a solve command.
So if you type display X; after you have issued the model and data commands but before you have issued the solve command, you'll only get the non-default values, e.g.:
X :=
1 1 1 2 5
2 3 2 1 6
;
But if you use display X; after you call solve, you'll get the full list:
X [1,*,*,1] (tr)
: 1 2 :=
1 0 0
2 0 0
3 0 0
[1,*,*,2] (tr)
: 1 2 :=
1 5 0
2 0 0
3 0 0
[2,*,*,1] (tr)
: 3 4 :=
1 0 0
2 6 0
3 0 0
[2,*,*,2] (tr)
: 3 4 :=
1 0 0
2 0 0
3 0 0
;
For completeness, here are the .mod and .dat files I used for this answer:
.mod:
param m; #number of modes
param n; #number of individual
param a; #number of alternatives
param f; #number of household
set M, default{1..m}; #set of modes
set N, default{1..n}; #set of individuals
set A, default{1..a}; #set of alternatives
set F, default{1..f}; #set of family
set E, within F cross N;
param X{E,M,A} default 0;
var myVar{E,M,A} >= 0;
minimize Obj: sum {(i,j) in E, mm in M, aa in A} X[i,j,mm,aa] * myVar[i,j,mm,aa];
.dat:
param a:=2;
param m:=3;
param n:= 4;
param f:=2;
set E:= 1 1 1 2 2 3 2 4 ;
param: X :=
1 1 1 2 5
2 3 2 1 6;

Minimum Network Flow in GAMS

I am trying to solve below network problem in GAMS Cplex. I am unable to get the desired output as the GAMS is giving the arcs which doesnt exist as output. Could you please help me in correcting this.
Program:
Set
i supply nodes /1,2,3,4/;
Alias(i,j);
Set
arc(i,j) arcs from node i to j
/1 .2
2 .3
3 .4
1 .4
2 .4/;
Parameter b(i) number of units available or required at node i
/ 1 5
2 2
3 -4
4 -3/ ;
Table c(i,j) cost of shipping from node i to node j
1 2 3 4
1 0 3 0 1
2 0 0 6 5
3 0 0 0 0
4 0 0 2 0 ;
Positive variables
x(i,j) number of units shipped along arc from i to j;
Variable z;
Equations obj, cons(i);
obj.. z =E= sum(arc(i,j),c(arc)*x(arc));
cons(i).. sum(j,x(i,j)) - sum(j,x(j,i)) =E= b(i);
I think you need to use the set "arc" in your constraints "cons" like this:
cons(i).. sum(arc(i,j),x(i,j)) - sum(arc(j,i),x(j,i)) =E= b(i);
Hope that helps,
Lutz

Currying a function with a variable in J

I can create a function that multiplies by 2 with 2&\*, and indeed 20 = (2&\*)10
What I want to do is create a factory-function that makes these to order.
So, I want a monad f s.t. ( f y ) x == (y * x )
whilst (\*& 2) 3 works ((\*&) 2) 3 doesn't, so trying explicitly:
(3 : 'y&*') 2 produces a syntax error.
Where am I going wrong ?
A verb that creates a verb is actually an adverb1 in J:
f =: 1 : 'm&*'
2 f
2&*
(2 f) 5
10
(i.10)f 5
0 5 10 15 20 25 30 35 40 45
or tacitly:
f =: &*
2 f
2&*
h =: 3 :'...' won't work because that produces a verb and then h y wants to be a noun.
g =: 4 :'x&* y' is fine and equivalent to f.
[1]: or a conjunction

SAS: prof freq list view, creating dummy

is there any way to create dummy variables for the list view generated from SAS: proc freq?
e.g.
this is my proc freq output :
x y z N %
0 0 0 10 2.8
0 0 1 20 5.6
0 1 0 30 8.3
0 1 1 40 11.1
1 0 0 50 13.9
1 0 1 60 16.7
1 1 0 70 19.4
1 1 1 80 22.2
can I create (easily in proc freq) dummy variables that can have 1/0 values for each level of the output (that is, 8 dummy variables) OR alternatively, a single variable which will have incremental value of 1,2,3,... for each level of output???
Thanks in advance !!
Here's one way you can do it with a single variable, assuming you just have combinations of variables with values of only 0 or 1:
data yourdata;
do i = 1 to 100;
x = round(ranuni(1));
y = round(ranuni(2));
z = round(ranuni(3));
t = 1;
output;
end;
run;
proc summary nway data = yourdata;
class x y z;
var t;
output out = summary_ds n=;
run;
data summary_ds;
set summary_ds;
singlevar = input(cats(x,y,z),binary3.);
run;