parameter is already defined in ampl - ampl

I want to define some parameters in ampl file, however the software indicates that the parameter is defined when I try to run it. How can I fix this problem?
set N := 1..6;
set N_row := 1..4;
var x{i in N} >= 0, <= 1 default 0;
param alpha{N_row};
param A{N_row,N};
param P{N_row,N};
param alpha := 1 1.0 2 1.2 3 3.0 4 3.2;
param A :=
[1,*] 1 10 2 3 3 17 4 3.5 5 1.7 6 8
[2,*] 1 0.05 2 10 3 17 4 0.1 5 8 6 14
[3,*] 1 3 2 3.5 3 1.7 4 10 5 17 6 8
[4,*] 1 17 2 8 3 0.05 4 10 5 0.1 6 14;
param P :=
[1,*] 1 0.1312 2 0.1696 3 0.5569 4 0.0124 5 0.8283 6 0.5886
[2,*] 1 0.2329 2 0.4135 3 0.8307 4 0.3736 5 0.1004 6 0.9991
[3,*] 1 0.2348 2 0.1451 3 0.3522 4 0.2883 5 0.3047 6 0.6650
[4,*] 1 0.4047 2 0.8828 3 0.8732 4 0.5743 5 0.1091 6 0.0381;
minimize Obj: sum {i in N_row} (alpha[i]*exp(-1*(sum{j in N} A[i,j]*(x[j]-P[i,j])**2)));
option solver scip;
solve;
display x;
display Obj;
display alpha;
display A;
display P;

It's generally good practice to keep model and data separate, but if you really want to do this, you can use the "data" statement to switch into data mode and then "model" to switch back. Like this:
set N := 1..6;
set N_row := 1..4;
var x{i in N} >= 0, <= 1 default 0;
param alpha{N_row};
param A{N_row,N};
param P{N_row,N};
data;
param alpha := 1 1.0 2 1.2 3 3.0 4 3.2;
param A :=
[1,*] 1 10 2 3 3 17 4 3.5 5 1.7 6 8
[2,*] 1 0.05 2 10 3 17 4 0.1 5 8 6 14
[3,*] 1 3 2 3.5 3 1.7 4 10 5 17 6 8
[4,*] 1 17 2 8 3 0.05 4 10 5 0.1 6 14;
param P :=
[1,*] 1 0.1312 2 0.1696 3 0.5569 4 0.0124 5 0.8283 6 0.5886
[2,*] 1 0.2329 2 0.4135 3 0.8307 4 0.3736 5 0.1004 6 0.9991
[3,*] 1 0.2348 2 0.1451 3 0.3522 4 0.2883 5 0.3047 6 0.6650
[4,*] 1 0.4047 2 0.8828 3 0.8732 4 0.5743 5 0.1091 6 0.0381;
model;
# etc.

Related

Backfill and Increment by one?

I have a column of a DataFrame that consists of 0's and NaN's:
Timestamp A B C
1 3 3 NaN
2 5 2 NaN
3 9 1 NaN
4 2 6 NaN
5 3 3 0
6 5 2 NaN
7 3 1 NaN
8 2 8 NaN
9 1 6 0
And I want to backfill it and increment the last value:
Timestamp A B C
1 3 3 4
2 5 2 3
3 9 1 2
4 2 6 1
5 3 3 0
6 5 2 3
7 3 1 2
8 2 8 1
9 1 6 0
YOu can use iloc[::-1] to reverse the data, and groupby().cumcount() to create the row counter:
s = df['C'].iloc[::-1].notnull()
df['C'] = df['C'].bfill() + s.groupby(s.cumsum()).cumcount()
Output
Timestamp A B C
0 1 3 3 4.0
1 2 5 2 3.0
2 3 9 1 2.0
3 4 2 6 1.0
4 5 3 3 0.0
5 6 5 2 3.0
6 7 3 1 2.0
7 8 2 8 1.0
8 9 1 6 0.0

How to find the average of multiple columns using a common column in pandas

How to calculate the mean value of all the columns with 'count' column.I have created a dataframe with random generated values in the below code.
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.rand(10,10)*100/10).astype(int)
df
output:
A B C D E F G H I J
0 4 3 2 8 5 0 9 9 0 5
1 1 5 8 0 5 9 8 3 9 1
2 9 5 1 1 3 2 6 3 8 3
3 4 0 8 1 7 3 4 2 8 8
4 9 4 8 2 7 9 7 8 9 7
5 1 0 7 3 8 6 1 7 2 0
6 3 6 8 9 6 6 5 0 8 4
7 8 9 9 5 3 9 0 7 5 5
8 5 5 8 7 8 4 3 0 9 9
9 2 4 2 3 0 5 2 0 3 0
I found mean value for a single column like this.How to find the mean for multiple columns with respect to count in pandas.
df['count'] = 1
print(df)
df.groupby('count').agg({'A':'mean'})
A B C D E F G H I J count
0 4 3 2 8 5 0 9 9 0 5 1
1 1 5 8 0 5 9 8 3 9 1 1
2 9 5 1 1 3 2 6 3 8 3 1
3 4 0 8 1 7 3 4 2 8 8 1
4 9 4 8 2 7 9 7 8 9 7 1
5 1 0 7 3 8 6 1 7 2 0 1
6 3 6 8 9 6 6 5 0 8 4 1
7 8 9 9 5 3 9 0 7 5 5 1
8 5 5 8 7 8 4 3 0 9 9 1
9 2 4 2 3 0 5 2 0 3 0 1
A
count
1 4.6
If need mean of all columns per groups by column count use:
df.groupby('count').mean()
If need mean by all rows (like grouping if same values in count) use:
df.mean().to_frame().T

replace some entries in a column of dataframe by a column of another dataframe

I have a dataframe about user-product-rating as below,
df1 =
USER_ID PRODUCT_ID RATING
0 0 0 0
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
5 5 5 5
6 6 6 6
7 7 7 7
8 8 8 8
9 9 9 9
another dataframe is the true ratings of some users and some products as below,
df2 =
USER_ID PRODUCT_ID RATING
0 0 0 10
1 1 1 10
2 2 2 10
3 3 3 10
I want to use the true ratings from df2 to replace the corresponding ratings in df1. So what I want to obtain is
USER_ID PRODUCT_ID RATING
0 0 0 10
1 1 1 10
2 2 2 10
3 3 3 10
4 4 4 4
5 5 5 5
6 6 6 6
7 7 7 7
8 8 8 8
9 9 9 9
Any operation to realize this?
rng = [i for i in range(0,10)]
df1 = pd.DataFrame({"USER_ID": rng,
"PRODUCT_ID": rng,
"RATING": rng})
rng_2 = [i for i in range(0,4)]
df2 = pd.DataFrame({'USER_ID' : rng_2,'PRODUCT_ID' : rng_2,
'RATING' : [10,10,10,10]})
Try to use update:
df1 = df1.set_index(['USER_ID', 'PRODUCT_ID'])
df2 = df2.set_index(['USER_ID', 'PRODUCT_ID'])
df1.update(df2)
df1.reset_index(inplace=True)
df2.reset_index(inplace=True)
print(df2)
USER_ID PRODUCT_ID RATING
0 0 0 10.0
1 1 1 10.0
2 2 2 10.0
3 3 3 10.0
4 4 4 4.0
5 5 5 5.0
6 6 6 6.0
7 7 7 7.0
8 8 8 8.0
9 9 9 9.0
You can use combine first:
df2.astype(object).combine_first(df1)
USER_ID PRODUCT_ID RATING
0 0 0 10
1 1 1 10
2 2 2 10
3 3 3 10
4 4 4 4
5 5 5 5
6 6 6 6
7 7 7 7
8 8 8 8
9 9 9 9

TSP time windows in GUSEK

I'm trying to do a program where I have 9 places to visit and each of them have a time window to visit, [a,b] in the program. The time in each city is p and I have one deposit where I start with only one car and I need to finish in the deposit as well. I dont need to visit all the cities the same day.
By the time this is what I have, but the program sais that "p" is not definded. Maybe you can help me and tell me some hints about how to do it.
param n, integer, >= 3;
/* number of nodes */
param MAX_TIME := 600;
param MAX_X :=20;
param maxspeed;
set CITIES := 1..n;
/* set of nodes */
set ARCS, within CITIES cross CITIES;
/* set of arcs */
param DIST{(i,j) in ARCS};
/* distance from node i to node j */
param NEXTC, integer, >= 0;
/* Next city after i in the solution */
var x{(i,j) in ARCS}, binary;
/* x[i,j] = 1 means that the salesman goes from node i to node j */
param bigM := 5000;
var tar{CITIES}; /*arrival */
var tlv{CITIES}; /* departure */
var tea{CITIES} >= 0; /* early arrival (arrival before the designated time window) */
var tla{CITIES} >= 0; /* late arrival (arrival after the designated time window) */
var ted{CITIES} >= 0; /* early departure (departure before the designated time window) */
var tld{CITIES} >= 0; /* late departure (departure after the designated time window) */
s.t. t1 {i in CITIES} : tlv[i] >= tar[i];
s.t. t2 {i in CITIES, j in CITIES} : tar[j] >= tlv[i] + p[i] + DIST[i,j]/maxspeed - bigM*(1-x[i,j]);
s.t. t3 {i in CITIES} : tea[i] >= a[i] - tar[i]; /* early arrival */
s.t. t4 {i in CITIES} : tla[i] >= tar[i] - b[i]; /* late arrival */
s.t. t5 {i in CITIES} : ted[i] >= a[i] - tlv[i]; /* early departure */
s.t. t6 {i in CITIES} : tld[i] >= tlv[i] - b[i]; /* late departure */
set days := 1..5;
param root := 1;
var y{(i,j) in ARCS}, >= 0;
/* y[i,j] is a flow through arc (i,j) */
minimize total: sum{(i,j) in ARCS} DIST[i,j] * x[i,j];
solve;
printf "Optimal tour has length %d\n",
sum{(i,j) in ARCS} DIST[i,j] * x[i,j];
printf("From node To node Distance\n");
printf{(i,j) in ARCS: x[i,j]} " %3d %3d %8g\n",
i, j, DIST[i,j];
data;
param n := 9;
param : ARCS : DIST :=
1 2 21
1 3 8
1 4 6
1 5 10
1 6 2
1 7 4
1 8 5
1 9 5
2 1 21
2 3 18
2 4 21
2 5 23
2 6 22
2 7 20
2 8 22
2 9 25
3 1 7
3 2 16
3 4 3
3 5 9
3 6 8
3 7 4
3 8 7
3 9 9
4 1 8
4 2 18
4 3 3
4 5 10
4 6 9
4 7 6
4 8 9
4 9 11
5 1 9
5 2 25
5 3 11
5 4 9
5 6 11
5 7 8
5 8 11
5 9 13
6 1 4
6 2 23
6 3 8
6 4 7
6 5 11
6 7 5
6 8 7
6 9 8
7 1 3
7 2 20
7 3 6
7 4 5
7 5 8
7 6 4
7 8 3
7 9 8
8 1 3
8 2 20
8 3 5
8 4 4
8 5 8
8 6 5
8 7 4
8 9 7
9 1 7
9 2 24
9 3 10
9 4 8
9 5 13
9 6 7
9 7 7
9 8 6;
param : a :=
1 705
2 420
3 420
4 420
5 420
6 420
7 420
8 420
9 420;
param : b :=
1 785
2 795
3 725
4 500
5 785
6 785
7 430
8 785
9 785;
param : p :=
1 65
2 55
3 125
4 65
5 65
6 65
7 65
8 65
9 65;
end;
Thank you.
In the constraint t2 you use p[i]:
tar[j] >= tlv[i] + p[i] + DIST[i,j]/maxspeed - bigM*(1-x[i,j]);
but p is not declared. You should declare it is a parameter or a variable depending on whether it is an input data or something that needs to be determined in the optimization process. For example:
param p{CITIES};

how to calculate "consecutive mean" in R without using loop, or in a more efficient way?

I have a set a data that I need to calculate their "consecutive mean" (I dunno if it is the correct name, but I can't find anything better), here is an example:
ID Var2 Var3
1 A 1
2 A 3
3 A 5
4 A 7
5 A 9
6 A 11
7 B 2
8 B 4
9 B 6
10 B 8
11 B 10
Here I need to calculated the mean of 3 Var3 variable in the same subset consecutively (i.e. there will be 4 means caulculated for A: mean(1,3,5), mean(3,5,7), mean(5,7,9), mean(7,9,11), and 3 means calculated for B: mean(2,4,6), mean(4,6,8), mean(6,8,10). And the result should be:
ID Var2 Var3 Mean
1 A 1 N/A
2 A 3 N/A
3 A 5 3
4 A 7 5
5 A 9 7
6 A 11 9
7 B 2 N/A
8 B 4 N/A
9 B 6 4
10 B 8 6
11 B 10 8
Currently I am using a "loop-inside-a-loop" approach, I subset the dataset using Var2, and then I calculated the mean in another start from the third data.
It suits what I need, but it is very slow, is there any faster way for this problem?
Thanks!
It's generally referred to as a "rolling mean" or "running mean". The plyr package allows you to calculate a function over segments of your data and the zoo package has methods for rolling calculations.
> lines <- "ID,Var2,Var3
+ 1,A,1
+ 2,A,3
+ 3,A,5
+ 4,A,7
+ 5,A,9
+ 6,A,11
+ 7,B,2
+ 8,B,4
+ 9,B,6
+ 10,B,8
+ 11,B,10"
>
> x <- read.csv(con <- textConnection(lines))
> close(con)
>
> ddply(x,"Var2",function(y) data.frame(y,
+ mean=rollmean(y$Var3,3,na.pad=TRUE,align="right")))
ID Var2 Var3 mean
1 1 A 1 NA
2 2 A 3 NA
3 3 A 5 3
4 4 A 7 5
5 5 A 9 7
6 6 A 11 9
7 7 B 2 NA
8 8 B 4 NA
9 9 B 6 4
10 10 B 8 6
11 11 B 10 8
Alternately using base R
x$mean <- unlist(tapply(x$Var3, x$Var2, zoo::rollmean, k=3, na.pad=TRUE, align="right", simplity=FALSE))