Building a linear constrait with 3 binary variables - constraints

I am trying to build a linear constraint that follows this logic
if either x1 = 1 or x2 =1 then y1 = 1
but if x1 = 0 and x2 = 0 then y1 = 0
if both x1 = 1 and x2= 1 then y1 = 1

Assumptions:
we are talking about integer-programming here
x1, x2 are binary-variables / integer-variables in [0, 1]
The truth-table looks like:
x1 x2 || y1
----------------
0 0 || 0
0 1 || 1
1 0 || 1
1 1 || 1
This is just:
y1 = x1 OR x2
This is trivially linearized (see relevant answer on cs.stackexchange.com):
y1 = binary-var / (could be integer-var too)
y1 <= x1 + x2
y1 >= x1
y1 >= x2

Related

Encountering conditional if else

I got a data frame (test) with a matrix of 4 x 2. I intended to use ifelse function to fix the dataset. Lines of code as below:
test <- data.frame(cbind(c(4,-5,-6,1),c("1","-3","4","-3")),stringsAsFactors = F)
test$X1 <- as.numeric(test$X1)
test$X2 <- as.numeric(test$X2)
test$X2 <- ifelse(test$X1<0 & test$X2>0, test$X2, test$X2*-1)
How do we write a code which apply the vice versa condition which means that if X1 < 0 & X2 > 0, then make X2 < 0, which apply the same on X1 (vice versa on the same logic)
The expected output is:
X1 <- 4 -5 -6 -1
X2 <- 1 -3 -4 -3
Would appreciate on any ideas.
We could achieve the desired result as follows using dplyr(assuming I understood the logic (which means that if X1 < 0 & X2 > 0, then make X2 < 0, which apply the same on X1 (vice versa on the same logic) well):
test %>%
mutate(X2 = ifelse(X1 <0 & X2>0, -X2, X2),
X1 = ifelse(X2<0 & X1>0, -X1,X1))
X1 X2
1 4 1
2 -5 -3
3 -6 -4
4 -1 -3
You could do
test$X2 <- with(test, X2 * c(1, -1)[(X1 < 0 & X2 > 0) + 1])
test$X1 <- with(test, X1 * c(1, -1)[(X1 > 0 & X2 < 0) + 1])
test
# X1 X2
#1 4 1
#2 -5 -3
#3 -6 -4
#4 -1 -3
To explain, let's take the first case.
The condition returns a logical vector
with(test, X1 < 0 & X2 > 0)
#[1] FALSE FALSE TRUE FALSE
By adding + 1 we convert it to numerical index where FALSE becomes 1 and TRUE becomes 2
with(test, X1 < 0 & X2 > 0) + 1
#[1] 1 1 2 1
We use this index to subset c(1, -1)
c(1, -1)[with(test, X1 < 0 & X2 > 0) + 1]
#[1] 1 1 -1 1
which is then multiplied to X2
with(test, X2 * c(1, -1)[(X1 < 0 & X2 > 0) + 1])
#[1] 1 -3 -4 -3

if else: else portion not returning output

I am currently trying to cycle through a dataframe of integers and characters and change one value of each row, conditionally. For all rows that do not meet the conditions I would just like to add them back into a new dataframe filled with the modified rows.
I've done this before with no trouble, but I feel as though I have been staring at this too long without any enlightenment.
a<-data.frame(cbind(1,'a',2,'c',3,'d'), stringsAsFactors = F)
b<-data.frame(cbind(1,'a',2,'c',3,'g'), stringsAsFactors = F)
c<-data.frame(cbind(1,'f',4,'g',5,'h'), stringsAsFactors = F)
x<-rbind(a,b,c)
fun<-function(x){
fin<-NULL
for(i in 1:nrow(x)){
v<-x[i+1,]
if ((x[i,1]== v[i,1]) & (x[i,2]==v[i,2]) ){
x[i,3]<-"f"
fin<-rbind(fin, x[i,])
}else {fin<-rbind(fin, x[i,]) }
return(fin)
}
}
fun(x)
X1 X2 X3 X4 X5 X6
1 1 a f c 3 d
>
The result I desire:
X1 X2 X3 X4 X5 X6
1 1 a f c 3 d
1 1 a 2 c 3 g
1 1 f 4 g 5 h
Or an alternative:
library(dplyr)
library(magrittr)
> z <- x %>% mutate(match = ifelse(( (lead(X1)==X1) & (lead(X2)==X2)),"YES","NO"))
> z %>% mutate(X3 = replace(X3, match=="YES", "f"))
X1 X2 X3 X4 X5 X6 match
1 1 a f c 3 d YES
2 1 a 2 c 3 g NO
3 1 f 4 g 5 h <NA>

Using RNN in R with multiple input variables

According to a previous question, there is an simple example:
/* Example*/
library('rnn')
# create training numbers
set.seed(1)
X1 = sample(0:127, 7000, replace=TRUE)
X2 = sample(0:127, 7000, replace=TRUE)
# create training response numbers
Y <- X1 + X2
# convert to binary
X1 <- int2bin(X1, length=8)
X2 <- int2bin(X2, length=8)
Y <- int2bin(Y, length=8)
# create 3d array: dim 1: samples; dim 2: time; dim 3: variables
X <- array( c(X1,X2), dim=c(dim(X1),2) )
# train the model
model <- trainr(Y=Y,
X=X,
learningrate = 0.1,
hidden_dim = 10,
start_from_end = TRUE )
/* End of Example*/
However, I want to ask how to define the input vector X of multiple variables for the trainr(). My data type is:
Y = 1
T = 0 T = 1 T = 3 T = 4 T = 5
X1 = 1 0 1 0 1
X2 = 1 1 1 0 1
X3 = 0 0 0 0 1
X1 = 1 0 1 0 1
X2 = 0 1 1 1 1
X3 = 0 0 0 0 1
...
Y = 2
T = 0 T = 1 T = 3 T = 4 T = 5
X1 = 0 0 1 0 1
X2 = 1 1 0 0 1
X3 = 0 1 0 0 1
X1 = 1 0 1 0 1
X2 = 1 1 1 0 1
X3 = 0 1 0 0 1
...
Y = 3
T = 0 T = 1 T = 3 T = 4 T = 5
X1 = 1 0 1 0 1
X2 = 1 0 1 0 1
X3 = 0 1 0 0 1
X1 = 1 1 1 0 1
X2 = 1 0 1 0 1
X3 = 0 1 0 0 0
...
To understand details of the package, I tried the following cases:
library(rnn)
set.seed(1)
X1 = sample(0:127, 5000, replace=TRUE)
X2 = sample(0:127, 5000, replace=TRUE)
X3 = sample(0:127, 5000, replace=TRUE)
X4 = sample(0:127, 5000, replace=TRUE)
Y <- X1 + X2 + X3 + X4
X1 <- int2bin(X1)
X2 <- int2bin(X2)
X3 <- int2bin(X3)
X4 <- int2bin(X4)
Y <- int2bin(Y)
X <- array( c(X1,X2,X3,X4), dim=c(dim(X1),4) )
Y <- array( Y, dim=c(dim(Y),1) )
model <- trainr(Y=Y,
X=X,
learningrate = 0.1,
hidden_dim = 10,
start_from_end = TRUE )
plot(colMeans(model$error),type='l',
xlab='epoch',
ylab='errors' )
A1 = int2bin( sample(0:127, 7000, replace=TRUE) )
A2 = int2bin( sample(0:127, 7000, replace=TRUE) )
A3 = int2bin( sample(0:127, 7000, replace=TRUE) )
A4 = int2bin( sample(0:127, 7000, replace=TRUE) )
A <- array( c(A1,A2,A3,A4), dim=c(dim(A1),4) )
B <- predictr(model,
A )
A1 <- bin2int(A1)
A2 <- bin2int(A2)
A3 <- bin2int(A3)
A4 <- bin2int(A4)
B <- bin2int(B)
hist( B-(A1+A2+A3+A4) )
However, the histogram showed the normal distribution with the center in -250. I think the distribution is not a reasonable one. Can any elaborate the result?
In fact, I want to know how to create the input vector X of all time for analysis corresponding to the Y value. Thanks for any response

R - Manhattan / Euclidean distance calculations into a matrix

I would like to ask help on distance measures for continuous variables
There is an example:
x1 = (0,0)
x2 = (1,0)
x3 = (5,5)
The example is to find the distance matrix for L1-norm and L2-norm(Euclidean).
I don't know how to compute in R to get the following answer:
I have tried to do it like this but it didn't work as expected.
y2 <- c(0,0)
y3 <- c(1,0)
y4 <- c(5,5)
y5 <- rbind(y2,y3,y4)
dist(y5)
y2 <- c(0,0)
y3 <- c(1,0)
y4 <- c(5,5)
mat <- rbind(y2, y3, y4)
d1 <- dist(mat, upper=TRUE, diag=TRUE, method="manhattan")
d1
# y2 y3 y4
# y2 0 1 10
# y3 1 0 9
# y4 10 9 0
d2 <- dist(mat, upper=TRUE, diag=TRUE)^2
d2
# y2 y3 y4
# y2 0 1 50
# y3 1 0 41
# y4 50 41 0

How do I convert table formats in R

Specifically,
I used the following set up:
newdata <- tapply(mydata(#), list(mydata(X), mydata(Y)), sum)
I currently have a table that currently is listed as follows:
X= State, Y= County within State, #= a numerical total of something
__ Y1 Y2 Y3 Yn
X1 ## ## ## ##
X2 ## ## ## ##
X3 ## ## ## ##
Xn ## ## ## ##
What I need is a table listed as follows:
X1 Y1 ##
X1 Y2 ##
X1 Y3 ##
X1 Yn ##
X2 Y1 ##
X2 Y2 ##
X2 Y3 ##
X2 Yn ##
Xn Y1 ##
Xn Y2 ##
Xn Y3 ##
Xn Yn ##
library(reshape2)
new_data <- melt(old_data, id.vars=1)
Look into ?melt for more details on syntax.
example:
> df <- data.frame(x=1:5, y1=rnorm(5), y2=rnorm(5))
> df
x y1 y2
1 1 -1.3417817 -1.1777317
2 2 -0.4014688 1.4653270
3 3 0.4050132 1.5547598
4 4 0.1622901 -1.2976084
5 5 -0.7207541 -0.1203277
> melt(df, id.vars=1)
x variable value
1 1 y1 -1.3417817
2 2 y1 -0.4014688
3 3 y1 0.4050132
4 4 y1 0.1622901
5 5 y1 -0.7207541
6 1 y2 -1.1777317
7 2 y2 1.4653270
8 3 y2 1.5547598
9 4 y2 -1.2976084
10 5 y2 -0.1203277
Some example data
mydata <- data.frame(num=rnorm(40),
gp1=rep(LETTERS[1:2],2),
gp2=rep(letters[1:2],each=2))
And applying tapply to it:
tmp <- tapply(mydata$num, list(mydata$gp1, mydata$gp2), sum)
The result of tapply is a matrix, but you can treat it like a table and use as.data.frame.table to convert it. This does not rely on any additional packages.
as.data.frame.table(tmp)
The two different data structures look like:
> tmp
a b
A 8.381483 6.373657
B 2.379303 -1.189488
> as.data.frame.table(tmp)
Var1 Var2 Freq
1 A a 8.381483
2 B a 2.379303
3 A b 6.373657
4 B b -1.189488

Resources