Gurobi Optimization Result Writing into Csv file - optimization

I am using Gurobi 7 to solve my MIP. I have several different variables. However, I am specifically interested in two of those, "x" and "y" namely. For the reference, I am giving my code that shows how I added x and y variables into the solver:
# Creating Variables
x = {}
y = {}
# Adding Variables
for i in range(I):
x[i+1,P[i]-d[0]] = m.addVar(vtype=GRB.BINARY, name="x%s" % str([i+1,P[i]-d[0]]))
x[i+1,P[i]] = m.addVar(vtype=GRB.BINARY, name="x%s" % str([i+1,P[i]]))
for i in range(I):
for k in range(len(rangevalue)):
y[i+1, rangevalue[k] - E[i]] = m.addVar(vtype=GRB.BINARY,
name="y%s" % str([i+1, rangevalue[k] - E[i]]))
Even though the above code may not really make any sense, I just wanted to show it in case you may use it for my problem.
After I solve the problem, I get the following results:
m.printAttr('X')
Variable X
-------------------------
x[1, 3] 1
sigmaminus[1] 874
x[2, 2] 1
sigmaminus[2] 1010
x[3, 2] 1
sigmaminus[3] 1945
x[4, 4] 1
sigmaplus[4] 75
x[5, 4] 1
sigmaminus[5] 1153
x[6, 5] 1
sigmaminus[6] 280
x[7, 3] 1
sigmaplus[7] 1138
x[8, 2] 1
sigmaplus[8] 538
x[9, 1] 1
sigmaplus[9] 2432
x[10, 5] 1
sigmaminus[10] 480
omega[1] 12
OMEGA[1] 12
omega[2] 9
OMEGA[2] 12
omega[3] 8
OMEGA[3] 9
omega[4] 8
OMEGA[4] 8
OMEGA[5] 8
y[1, 2] 1
y[2, 9] 1
y[3, 5] 1
y[4, 6] 1
y[5, 4] 1
y[6, 6] 1
y[7, 3] 1
y[8, 11] 1
y[9, 8] 1
y[10, 1] 1
phiplus[6] 1
phiminus[7] 1
phiminus[10] 1
I specifically want to display x and y variables with their indexes. Other variables are not necessary. My question is how can I write these results into an csv file on one column as following?
x[1,3]
x[2,2]
x[3,2]
.
.
.
x[10,5]
y[1,2]
y[2,9]
y[3,5]
.
.
.
y[10,1]
I do not need their corresponding value which can only be "1" since they are binary variables. I just need to write the variables which have the value "1".

I would do something along these lines:
import csv
if m.SolCount == 0:
print("Model has no solution")
exit(1)
var_names = []
for var in m.getVars():
# Or use list comprehensions instead
if 'x' == str(var.VarName[0]) and var.X > 0.1:
var_names.append(var.VarName)
# Write to csv
with open('out.csv', 'wb') as myfile:
wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
wr.writerows(var_names)
I hope this helps. I am going to test this snippet a bit later. Update: works as intended.

Related

How to modify each element of a block by "foreach" in red/rebol

I want to modify each element of a block by foreach. I tried like this but failed:
>> a: [3 4 5 6]
== [3 4 5 6]
>> foreach i a [i + 1]
== 7
>> a
== [3 4 5 6] ;; block a is not changed. What I want is [4 5 6 7]
Is there a better way to achieve it?
Changes that you made to values do not persist in a block itself. This ties back to your question about call-by-value parameter passing in Rebol and Red: you modify a copy on the stack (passed down to + along with 1), not the actual value slot that sits inside block a.
To achieve what you want, you need to increment integers in-place, without pushing them on the stack. One way to do so is by using forall.
>> block: [1 2 3]
== [1 2 3]
>> also block forall block [block/1: block/1 + 1]
== [2 3 4]
What forall does is setting a word to a series and then incrementally bumping its index:
>> forall block [probe block]
[1 2 3]
[2 3]
[3]
Since it doesn't extract the actual values, you can access them using path notation, and then modify them in place. block/1 always pick the first value on each iteration.
As usual, no reply with your foreach.
a: [2 3 4 5]
b: copy []
foreach i a [append b i + 1]
and if you wish you can set a to b now
a: b
The problem with doing this in one step is that you do not have an index you can use here (despite the suggestive letter i, but that is representing the content of each item inside the block).
So now you can choose your favourite solution.
>> help forall
USAGE:
FORALL 'word body
DESCRIPTION:
Evaluates body for all values in a series.
FORALL is a native! value.
ARGUMENTS:
'word [word!] "Word referring to series to iterate over."
body [block!]
use forall
> a: [3 4 5 6]
== [3 4 5 6]
>> forall a [a/1: a/1 + 1]
== 7
>> probe a
[4 5 6 7]
== [4 5 6 7]

Array Numpy Side Effect

I found a strange effect when permuting array with numpy:
def permute(yy, kmax) :
kmax=5
kk= np.random.uniform(1,kmax)
nn= int(np.floor(len(yy)/kk))
yy3= np.zeros_like(yy );
np.copyto(yy3,yy)
for ii in range(0, nn):
ax= kk*ii-kk*nn
aux= yy[ax]
aux2= yy[kk*ii]
yy3[ax] = aux
yy3[kk*ii] = aux2
return yy3
and
yy= np.random.normal(0,1,50000)
yy1= permute(yy,2)
( np.var(yy)- np.var(yy1) )
( np.mean(yy)- np.mean(yy1) )
Result is not zero !!!
Do you think this comes from reference assignment in the array ?
I ran your function with np.arange(10) and got
1752:~/mypy$ python stack35004877.py
0.0
0.0
[0 1 2 3 4 5 6 7 8 9] # yy
[0 1 2 3 4 5 6 7 8 9] # yy1
And repeated it with the large random array, with the same 0s for the statistics.
Note that your code did not permute the input
Maybe it will be clearer if I clean it up:
def permute(yy, kmax=5) :
kk= np.random.randint(1,kmax) # int rather than float
nn= int(np.floor(len(yy)/kk))
print(nn,kk)
yy3= yy.copy()
for ii in range(0, nn):
ind1 = kk*ii
ind2 = ind1-kk*nn
yy3[ind2] = yy[ind2]
yy3[ind1] = yy[ind1]
return yy3
You aren't moving anything; and with kmax=2 you just copy every thing from yy to yy3 - something you already did outside the loop. With kmax=5 you don't copy everything in the loop - but the initial copy hides that.
With random.uniform(), kk is a float, and the indexes are also floats. That's not desirable, but apparently not a problem.
But even if I switch the indices:
yy3[ind2] = yy[ind1]
yy3[ind1] = yy[ind2]
I don't permute anything, because ind2 a negative value, that maps on to the same element as ind1. yy[-1] is the last item of yy.
[(0, -10), (1, -9), (2, -8),... (9, -1)]
I could work out the details, but I think you should do that yourself - with a small test case. And skip that initial copyto, that just hides errors in the iteration. Print the details, not just summary statistics from large random arrays.
And in the long run you don't want to use an iteration like this. You want to do the permutation with one indexing call. But first get this version working correctly.

Graph longest path using linear programming

I have a weighted directed graph where there are no cycles, and I wish to define the constraints so that I can solve a maximization of the weights of a path with linear programming. However, I can't wrap my head around how to do that.
For this I wish to use the LPSolve tool. I thought about making an adjacency matrix, but I don't know how I could make that work with LPSolve.
How can I define the possible paths from each node using constraints and make it generic enough that it would be simple to adapt to other graphs?
Since you have a weighted directed graph, it is sufficient to define a binary variable x_e for each edge e and to add constraints specifying that the source node has flow balance 1 (there is one more outgoing edge selected than incoming edge), the destination node has flow balance -1 (there is one more incoming edge than outgoing edge selected), and every other node has flow balance 0 (there are the same number of outgoing and incoming edges selected). Since your graph has no cycles, this will result in a path from the source to the destination (assuming one exists). You can maximize the weights of the selected edges.
I'll continue the exposition in R using the lpSolve package. Consider a graph with the following edges:
(edges <- data.frame(source=c(1, 1, 2, 3), dest=c(2, 3, 4, 4), weight=c(2, 7, 3, -4)))
# source dest weight
# 1 1 2 2
# 2 1 3 7
# 3 2 4 3
# 4 3 4 -4
The shortest path from 1 to 4 is 1 -> 2 -> 4, with weight 5 (1 -> 3 -> 4 has weight 3).
We need the flow balance constraints for each of our four nodes:
source <- 1
dest <- 4
(nodes <- unique(c(edges$source, edges$dest)))
# [1] 1 2 3 4
(constr <- t(sapply(nodes, function(n) (edges$source == n) - (edges$dest == n))))
# [,1] [,2] [,3] [,4]
# [1,] 1 1 0 0
# [2,] -1 0 1 0
# [3,] 0 -1 0 1
# [4,] 0 0 -1 -1
(rhs <- ifelse(nodes == source, 1, ifelse(nodes == dest, -1, 0)))
# [1] 1 0 0 -1
Now we can put everything together into our model and solve:
library(lpSolve)
mod <- lp(direction = "max",
objective.in = edges$weight,
const.mat = constr,
const.dir = rep("=", length(nodes)),
const.rhs = rhs,
all.bin = TRUE)
edges[mod$solution > 0.999,]
# source dest weight
# 1 1 2 2
# 3 2 4 3
mod$objval
# [1] 5

unique for a block doesn't remove duplicates

The strings are part of urls of which I stripped out the base.
parse detects four urls in some html file. I've narrowed down the problem to this:
REBOL []
images: [{,W,H,wi,1TV1Rvu8EF9FDdUxKy+hTKK/RNifw3WQDJEI/sYkX78tyNifGd0/U4RpaBox1rO448B4dv24sYoTgxOMVC7Lz5J9sJXlk0nkM89n55HzX7qbRiX/cSkd3lepAEIj3LVTN7gmQLCI2+INwwg18IyDklZ3VZWkw011+77dkfgTTRlRaY397ricx4dk4BTHvCLZ} {,W,H,wi,1TV1Rvu8EF9FDdUxKy+hTKK/RNifw3WQDJEI/sYkX78tyNifGd0/U4RpaBox1rO448B4dv24sYoTgxOMVC7Lz5J9sJXlk0nkM89n55HzX7qbRiX/cSkd3lepAEIj3LVTN7gmQLCI2+INwwg18IyDklZ3VZWkw011+77dkfgTTRlRaY397ricx4dk4BTHvCLZ} {,W,H,wi,1TV1Rvu8EF9FDdUxKy+hTKK/RNifw3WQDJEI/sYkX78wvYn3cKtEeN/9Y8EfNR8J48B4dv24sYoTgxOMVC7Lz5J9sJXlk0nkM89n55HzX7qbRiX/cSkd3lepAEIj3LVTN7gmQLCI2+INwwg18IyDklZ3VZWkw011+77dkfgTTRlRaY397ricx4dk4BTHvCLZ} {,W,H,wi,1TV1Rvu8EF9FDdUxKy+hTKK/RNifw3WQDJEI/sYkX78wvYn3cKtEeN/9Y8EfNR8J48B4dv24sYoTgxOMVC7Lz5J9sJXlk0nkM89n55HzX7qbRiX/cSkd3lepAEIj3LVTN7gmQLCI2+INwwg18IyDklZ3VZWkw011+77dkfgTTRlRaY397ricx4dk4BTHvCLZ}]
print join "before: " length? images
unique images
print join "after: " length? images
print join "1=2? " images/1 = images/2
print join "1=3? " images/1 = images/3
print join "1=4? " images/1 = images/4
print join "2=3? " images/2 = images/3
print join "2=4? " images/2 = images/4
print join "3=4? " images/3 = images/4
As can be seen, urls 1 and 2 are identical, and the same can be said to urls 3 and 4. Still, unique doesn't remove the duplicates. Why does this happen, how to deal with it?
UNIQUE does not modify original series. Whether function modifies is usually mentioned in it's help string, see SORT for example. Just set your block to the result of UNIQUE, like this:
>> a: [1 2 3 4 3 4 4]
== [1 2 3 4 3 4 4]
>> unique a
== [1 2 3 4]
>> a
== [1 2 3 4 3 4 4]
>> a: unique a
== [1 2 3 4]
>> a
== [1 2 3 4]

Understanding PsychoPy's data logging

I have a test PsychoPy Builder script that I am using to investigate some counter-intuitive behaviour. The structure is four routines:
"Init", not in a loop, the following code in "Begin Experiment":
x = 0
y = 0
z = 0
foo = [0, 0, 0]
"One", in a loop, the following code in "End Routine":
x = x + 1
foo[0] = foo[0] + 1
thisExp.addData("x", x)
thisExp.addData("y", y)
thisExp.addData("z", z)
thisExp.addData("foo", foo)
"Two", in a loop, the following code in "End Routine":
y = y + 2
foo[1] = foo[1] + 2
thisExp.addData("x", x)
thisExp.addData("y", y)
thisExp.addData("z", z)
thisExp.addData("fooY", foo[1])
thisExp.addData("foo", foo)
"Three", in a loop, the following code in "End Routine":
z = z + 3
foo[2] = foo[2] + 3
thisExp.addData("x", x)
thisExp.addData("y", y)
thisExp.addData("z", z)
thisExp.addData("foo", foo)
There is no other code, no other components. The routines "One", "Two", and "Three" form a loop in that order executed five times. The relevant columns of the CSV output file are as follows:
trials.thisRepN trials.thisTrialN trials.thisN trials.thisIndex x y z foo fooY
0 0 0 0 1 2 3 [5, 10, 15] 2
1 0 1 0 2 4 6 [5, 10, 15] 4
2 0 2 0 3 6 9 [5, 10, 15] 6
3 0 3 0 4 8 12 [5, 10, 15] 8
4 0 4 0 5 10 15 [5, 10, 15] 10
Is this the expected output? If so, why? Note that the individual variables, x, y, and z, are displaying updated values each time through the loop (at the end of the loop), while the list foo shows only the final value after the loop iterates all five times, but it shows this in every line. But calling out individual elements of the list displays as individual variables do.
What is the logic and rationale behind this?
Is there a way to make the list output perform as the others do?
Is there a way to force the output to capture/display any of these variables as they are when the addData() is invoked rather than waiting until the end of the loop?
I think I know what is going wrong here. It's probably because python assigns by reference rather than copy. This is explained in detail elsewhere but briefly,
original = [1, 2]
new = original # new is simply a reference to original! It is not a copy.
new[0] = 'Oops' # original is now ['Oops', 2] as is new (which is just a reference or pointer
In your case, the TrialHandler receives the reference, which simply points to the "foo" variable which is updated throughout the experiment. Since the log is only saved in the end of the experiment, all the rows in "foo" now points to the "foo variable" which now holds the value [5, 10, 15].
This assignment-by-reference can be extremely beautiful and handy, but sometimes cause headache like in your example. It applies to all python mutables: lists, dicts, functions, and classes. But not for immutables, like numbers, tuples and strings! That's why your script works for digits but not for the list.
There are different solutions. The simplest is probably to replace the addData calls with thisExp.addData("foo", tuple(foo)) which converts the mutable list to an immutable tuple. One can also do thisExp.addData("foo", [x for x in foo]). A more all-round solution for all kinds of objects is to run import copy in the beginning of the experiment and then add data like thisExp.addData("foo", copy.copy(foo)) in the other codeblocks (if you have a complicated object, use copy.deepcopy instead).