views:

107

answers:

4

I have the following inequalities on 21 variables:

http://pastebin.com/raw.php?i=FTU970Em

When I run "Reduce[ineq,Integers]" on this, Mathematica hangs for a long time.

That makes sense: there are MANY sets of values for x[1]..x[21] that satisfy the inequalities.

All I really want is bounds for each variable (eg, "2 <= x[i] <= 7" for each i).

How can I get this efficiently w/ Mathematica? Is there a better program for this?

Note: this is part of the larger project:

http://stackoverflow.com/questions/3799748

The entire hideous list of inequalities: http://pastebin.com/CyX9f70J

Running "Reduce[ineq,Integers]" on the above yields "false", so I've probably incorrectly translated: http://conquerclub.barrycarter.info/ONEOFF/7460216.html

+1  A: 

Are there many sets of values which satisfy the inequalities ?

I ran the following commands through Mathematica:

In[14]:= ineqs = {x0 == 3, x1 >= 1, x1 <= x0, x2 >= 1, x2 <= x1, 
       x3 >= 1, x3 <= x2, x4 >= 1, x4 <= x3, x5 <= x4 + 3, x5 >= 1, 
       x6 >= 1, x6 <= x5, x7 >= 1, x7 <= x6, x8 >= 1, x8 <= x7, x9 >= 1, 
       x9 <= x8, x10 >= 1, x10 <= x9, x11 >= 1, x11 <= x10, x12 >= 1, 
       x12 <= x11, x13 >= 1, x13 <= x12, x14 <= x13 + 4, x14 >= 1, 
       x15 >= 1, x15 <= x14, x16 >= 1, x16 <= x15, x17 <= x16 + 6, 
       x17 >= 1, x18 >= 1, x18 <= x17, x19 >= 1, x19 <= x18, x20 >= 1, 
       x20 <= x19, x21 >= 1, x21 <= x20, x21 == 1};

In[15]:= vars = 
      Union[{x0, x1, x1, x2, x2, x3, x3, x4, x4, x5, x5, x6, x6, x7, x7, 
        x8, x8, x9, x9, x10, x10, x11, x11, x12, x12, x13, x13, x14, x14, 
        x15, x15, x16, x16, x17, x17, x18, x18, x19, x19, x20, x20, x21, 
        x21, x21}];

In[16]:= FindInstance[ineqs, vars]

and got the result:

Out[16]= {{x0 -> 3, x1 -> 1, x10 -> 1, x11 -> 1, x12 -> 1, x13 -> 1, 
  x14 -> 1, x15 -> 1, x16 -> 1, x17 -> 1, x18 -> 1, x19 -> 1, x2 -> 1,
   x20 -> 1, x21 -> 1, x3 -> 1, x4 -> 1, x5 -> 1, x6 -> 1, x7 -> 1, 
  x8 -> 1, x9 -> 1}}

I haven't been able to persuade Mathematica to provide another set of assignments and a little work with pencil and paper doesn't point me towards other sets of assignments. But it's late here, I may have missed something obvious.

High Performance Mark
I'm pretty sure changing x1 to 2 also works. In fact, I think many sequences of the form (3,3,3..,1,1,1) would also work. The equations for most of the xi (except x0, x5, x14, x17, x21) are identical, so I'm pretty sure the drop from 3 to 1 (for example) can occur at any point between x1 and x4.
barrycarter
A: 

OK, it turns out that solving this particular set of equations is easy, once you rewrite some of them slightly:

x5 <= x4 + 3 becomes x5 - 3 <= x4 
x6 <= x5 becomes x6 - 3 <= x5 - 3 

and so on until:

x13 <= x12 becomes x13 - 3 <= x12 - 3 
x14 <= x13 + 4 becomes x14 - 7 <= x13 -3 

By doing this, {x0, x1, x2, x3, x4, x5-3, x6-3, ..., x13-3, x14-7, ..., x21} becomes a strictly decreasing sequence of integers starting at 3 and ending at 1.

In fact, any sequence w/ that property works, since xi>=1 is trivally satisfied.

However, while this works to solve this particular set of inequalities, it doesn't work in general, so I don't consider it a complete solution.

barrycarter
A: 

I second the CLP(FD) suggestion given in the other thread. Using SWI-Prolog 5.10:

:- use_module(library(clpfd)).

vars([X0,X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,X13,X14,X15,X16,X17,X18,
      X19,X20,X21]) :-
        X0 #= 3, X1 #>= 1, X1 #=< X0, X2 #>= 1, X2 #=< X1,
        X3 #>= 1, X3 #=< X2, X4 #>= 1, X4 #=< X3, X5 #=< X4 + 3,
        X5 #>= 1, X6 #>= 1, X6 #=< X5, X7 #>= 1, X7 #=< X6,
        X8 #>= 1, X8 #=< X7, X9 #>= 1, X9 #=< X8, X10 #>= 1,
        X10 #=< X9, X11 #>= 1, X11 #=< X10, X12 #>= 1, X12 #=< X11,
        X13 #>= 1, X13 #=< X12, X14 #=< X13 + 4, X14 #>= 1, X15 #>= 1,
        X15 #=< X14, X16 #>= 1, X16 #=< X15, X17 #=< X16 + 6, X17 #>= 1,
        X18 #>= 1, X18 #=< X17, X19 #>= 1, X19 #=< X18, X20 #>= 1,
        X20 #=< X19, X21 #>= 1, X21 #=< X20, X21 #= 1.

Example queries:

?- vars(Vs), maplist(fd_dom, Vs, Ds).
Ds = [3..3, 1..3, 1..3, 1..3, 1..3, 1..6, 1..6, 1..6, ... .. ...|...]

?- vars(Vs), label(Vs).
Vs = [3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ;
Vs = [3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1] ;
Vs = [3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1] ;
etc.
mat