Is it possible to convert a MathProg MIP file to a format recognised by SCIP? - glpk

I've been using GLPK to solve some mixed integer programming problems. Here's a sample input file in MathProg format:
set REACTIONS;
set REACTANTS;
param Ys {i in REACTANTS, j in REACTIONS};
param Gamma {i in REACTANTS, j in REACTIONS};
param eps;
param delt;
var w {i in REACTANTS} >=-delt <=delt;
var R0 {i in REACTIONS} >=0 <=1, integer;
var Rn {i in REACTIONS} >=0 <=1, integer;
minimize z: sum{i in REACTIONS} -Rn[i];
s.t. const1{i in REACTIONS} : sum{k in REACTANTS} w[k]*Gamma[k,i] <= delt*(1-R0[i]);
s.t. const2{i in REACTIONS} : -sum{k in REACTANTS} w[k]*Gamma[k,i] <= delt*(1-R0[i]);
s.t. const3{i in REACTIONS} : Rn[i] <= 1-R0[i];
s.t. const5{i in REACTIONS} : sum{k in REACTANTS} w[k]*Gamma[k,i] <= delt*(1-Rn[i])-eps;
s.t. const6{i in REACTIONS, j in REACTIONS: i <> j} : sum{k in REACTANTS} w[k]*(Ys[k,i]-Ys[k,j]) <= delt*(1-Rn[i]+Rn[j]+R0[j]);
data;
set REACTIONS:= 1 2 3 4 5 6;
set REACTANTS:= 1 2 3 4 5 6;
param Ys: 1 2 3 4 5 6:=
1 1 0 0 0 0 0
2 1 0 0 0 0 0
3 0 1 1 0 0 0
4 0 0 0 1 0 0
5 0 0 0 1 0 0
6 0 0 0 0 1 1;
param Gamma: 1 2 3 4 5 6:=
1 -1 1 0 0 0 1
2 -1 1 1 0 0 0
3 1 -1 -1 0 0 0
4 0 0 1 -1 1 0
5 0 0 0 -1 1 1
6 0 0 0 1 -1 -1;
param eps:=0.1;
param delt:=10;
end;
I've been running into performance problems for bigger problems of this type, and since SCIP claims to be several times faster than GLPK for MIP, it seems worth investigating. However, I haven't been able to make head or tail of the documentation when it comes to input file formats. SCIP's homepage says that it supports AMPL format, and the GLPK's homepagesays that MathProg is a subset of AMPL. Trying to feed the above file into SCIP 3.1.0 via scip -f file.nl returns the following error:
read problem <file.nl>
============
no reader for input file <file.nl> available
I'm not sure whether this is because I've failed to build SCIP with AMPL support, or something else. I found this blog post on building SCIP with AMPL support, but the instructions seem to be outdated as the source zip of SCIP 3.1.0 doesn't contain an interfaces folder.
So, I have two questions:
Is it possible to get SCIP to recognise my MathProg input as is?
If not, can anyone advise on how to convert it to a recognised format? An automated method would be preferable, as I don't really want to have to learn yet another format, but a manual method would be better than nothing.
Thanks for any help and apologies for my ignorance!

As I indicated in my comment above, the Ampl-interface is still included in the SCIP-distribution, and you should be able to compile it and read your problem
as documented in the excellent blog post you cite.
If you feel tempted to try different file formats, I see two options for you:
use glpk for translating your problem into a file format that is recognizable by SCIP. I found methods glp_write_mps() and glp_write_lp. SCIP can read both .lp and .mps-files. Make sure that you use exactly these file extensions, because SCIP doesn't recognize files in .lp-format but ending with .txt instead.
Use Zimpl to formulate your problems instead. The two formats of Zimpl and Ampl are strikingly similar, see the documentation for examples and further reference. Problem descriptions in Zimpl can be translated into .lp-format or read directly by SCIP, if you compile SCIP with the ZIMPL=true-option, which is the default.

Related

Build xy+xz+yz using NAND port

for an homework I have to write xy+xz+yz using only NANDS port.
I will use the notation NAND(x,y) - or other types of bracket to make things clearer -, below my attempt and then an explanation for every step. I'd like to know if i'm doing this right and if there are better ways to do it.
My Solution
NAND[NAND(NAND(NAND(x,y),NAND(x,z)),NAND(NAND(x,y),NAND(x,z))),NAND(NAND(NAND(y,z),NAND(y,z)),NAND(NAND(y,z),NAND(y,z))))]`
I know this looks really impossible to read and keep track of. I'm sorry, didn't know how to make this more beautiful. Hope my explanation will clarify things.
I divided xy+xz+yz in two groups: xy+xz and yz
First Group:
xy+xz = NAND(NAND(x,y),NAND(xz)) = NOT[NOT(xy)*NOT(xz)] = xy+xz
Second Group:
yz = NAND(NAND(y,z),NAND(y,z)) = NOT(NOT(yz)*NOT(yz)) = yz (since yz+yz = yz)
Now I have to combine the first group with the second, for readibility I'll call the first group (in NAND as g1) and the second g2;
g1+g2= NAND[NAND(g1,g1),NAND(g2,g2)] = NOT[NOT(g1)*NOT(g2)] = g1+g2
So at the end:
xy+xz+yz= NAND[NAND(NAND(NAND(x,y),NAND(x,z)),NAND(NAND(x,y),NAND(x,z))),NAND(NAND(NAND(y,z),NAND(y,z)),NAND(NAND(y,z),NAND(y,z))))]
Is my reasoning right? There's a more easy way?
Thanks a lot guys
Your answer is correct (although you have some missing punctuation -- a couple commas and a parenthesis). You can confirm by generating a truth table of all possible outputs as so. I wrote a few lines of C code to confirm. As for your second question to whether there is an easier way, I don't know. Maybe someone else can help out.
x y z xy+xz+yz nands
------------------------------
0 0 0 0 0
0 0 1 0 0
0 1 0 0 0
0 1 1 1 1
1 0 0 0 0
1 0 1 1 1
1 1 0 1 1
1 1 1 1 1

Explanation of 1 mod 3

So i've been looking into modulo recently. I'm trying to improve my math skills, which are not the best if i'm honest. But something i am trying to improve. I understand how this works i think. I am also quite competent with long division. However something is bugging me and i can't seem to find an answer for it online.
I know that 7 % 5 = 2 (5 goes into 7 once, with a remainder of 2).
What i don't understand is this;
1 % 3 = 1
How can this be, 3 goes into 1, 0 times, with a remainder of 3? Surely the answer to 1 % 3 = 3?
Can anyone explain this in its most simplest terms please?
Am i correct in thinking that if the dividend (1) is less than the devisor (3) which we know will equal 0 remainder x, it just uses the dividend as the result?
Thanks for your help.
The remainder in 1%3 refers to what remains of 1 (not 3) after you divide by 3. As you have already said, 3 goes into 1 zero times. So -- when you remove 0 multiples of 3 from 1, all of 1 remains. Thus 1 % 3 = 1.
The result of a modulo operation n % m is just that number r for which q * m + r = n (q may be anything). The only requirement we have is that 0 <= r < m.
So for instance:
7 % 5 --> 1 * 5 + 2 == 7 --> r = 2
1 % 3 --> 0 * 3 + 1 == 1 --> r = 1

how do i check even or odd in postscript

I'm trying to check if the number on the top of the stack is even or odd without affecting my stack because I'm using it in a recursive function. I also tried to double pop but this code still messes up the function.
dup 2 0 mod eq
{ 0 0 0 setrgpcolor}
{0.6 0.6 0.6 setrgpcolor}ifelse
pop
You got the order of the arguments wrong. One step at a time (assuming the top stack number is 123):
123
dup 2 0 mod eq
do dup:
123 123 2 0 mod eq
do mod on 2 0 (!)
123 123 --undefined-- eq
and the eq is too little, too late...
Swap the 2 operands to get the right result:
dup 2 mod 0 eq
{ .. number is even ..}
{ .. number is odd ..} ifelse
(Note:
Is setrgpcolor a typo, or is there really a color model named so?)

Taylor series for cosinus return wrong result for 0

I want to write in Maple Taylor series for cosinus function. Here's my code:
better_cos := proc (x) options operator, arrow; sum((-1)^n*x^(2*n)/factorial(2*n), n = 0 .. 20) end proc;
better_cos(0) returns 0 instead of 1 (cos(0) == 1). It's probably because x^(2*n) return always 0 instead of 1. For example:
fun_sum := proc (x) options operator, arrow; sum(x^(2*n), n = 0 .. 0) end proc
return 0 for x == 1.
It's weird because 0^0 returns 1. Do you have any idea how can I correctly implement taylor series for cosinus?
You should be able to get what you want by using add instead of sum in your better_cos operator.
Using add is often more appropriate for adding up a finite number of terms of a numeric sequence, and also note that add has Maple's so-called special evaluation rules.
If you intend to take the sum of a fixed number of terms (ie. n from 0 to 20) then you should not write a procedure that computes the factorials for each input argument (ie. for each value of x). Instead, produce the truncated series just once, and then use unapply to produce an operator. This approach also happens to deal with your original problem, since the x^0 term becomes 1 because the symbol x is used.
You could also rearrange the polynomial (truncated series) so that it is in Horner form, to try and minimize arithmetic steps when evaluating subsequently at various numeric values of x.
For example, using 5 terms for brevity instead of 20 as you had it,
convert(add((-1)^n*x^(2*n)/factorial(2*n), n = 0 .. 5),horner);
/ 1 /1 / 1 / 1 1 2\ 2\ 2\ 2\ 2
1 + |- - + |-- + |- --- + |----- - ------- x | x | x | x | x
\ 2 \24 \ 720 \40320 3628800 / / / /
bc := unapply(%,x):
You can now apply the procedure bc as you wish, either with symbolic or numeric arguments.
expand(bc(x));
1 2 1 4 1 6 1 8 1 10
1 - - x + -- x - --- x + ----- x - ------- x
2 24 720 40320 3628800
bc(0);
1
bc(1.2);
0.3623577360
If you prefer to have your procedure better_cos take a pair of arguments, so that the number of terms is variable, then you could still consider using add to deal with your original problem. eg,
bc := (x,N)->add((-1)^n*x^(2*n)/(2*n)!, n = 0 .. N):
I suppose that this is a homework assignment, and that you realize that you could also use the existing system commands taylor or series to get the same results, ie.
convert(series(cos(x),x=0,10),polynom);
1 2 1 4 1 6 1 8
1 - - x + -- x - --- x + ----- x
2 24 720 40320
convert(taylor(cos(x),x=0,10),polynom);
1 2 1 4 1 6 1 8
1 - - x + -- x - --- x + ----- x
2 24 720 40320
Here's the Taylor series definition:
Don't start the loop with zero; initialize with one and start at two.
Factorial is inefficient, too.

Matlab SimBiology - Allow self connecting nodes

I'm using Matlab's SimBiology tool box to generate biograph (which are, just graphs).
When I'm trying to include a node which connects to itself, e.g:
g = [
0 1 0;
1 0 1;
0 0 1; % This one connects to itself.
]
I get the following warning message :
Warning: Self connecting nodes are not allowed, ignoring the diagonal of CM.
As my data sets include some self connecting nodes, I was wondering if this is a configurable feature.
Thanks!
Unfortunately biograph can not have self-connecting edges. If your purpose is only for visualization you could add some nodes with empty labels. Here is an example for a small graph and two self-connecting nodes:
cm = [0 1 1 0 0;1 0 0 1 1;1 0 1 0 0;0 0 0 0 1;1 0 1 0 1];
ids = {'M30931','L07625','K03454','M27323','M15390'};
sc = find(diag(cm));
cm = cm-diag(diag(cm));
n = size(cm,1);
m = numel(sc);
cm(n+m,n+m)=0;
cm(sub2ind([n+m,n+m],[sc;(1:m)'+n],[(1:m)'+n;sc]))=1;
ids((1:m)+n) = {' '};
bg = biograph(cm);
for i = 1:numel(bg.Nodes)
bg.Nodes(i).Label = ids{i};
if i>n
bg.Nodes(i).Shape = 'circle';
end
end
view(bg)
HTH
Lucio

Resources