Solving a simple geometric puzzle in CLPQ/R (Prolog) - prolog

Consider the following square:
You are given three constraints:
All rectangles (A, B, C, D and E) have the same area;
Their geometric layout constitutes a square; and
The height of A is 2.
Now, I know this is very simple to solve by hand, but I thought it would be a very good example to show off the capabilities of CLP(Q/R) with Prolog:
SPOILER ALERT: If you want to first solve the puzzle by yourself, do not continue to read this, as there are constraints that will give away the solution.
Anyway, here's my attempt at defining (with I think include redundant constraints) this puzzle with CLP(Q/R):
:- use_module(library(clpr)).
solve(Eh) :-
A = B, B = C, C = D, D = E,
{ A >= 1, B >= 1, C >= 1, D >= 1, E >= 1,
Aw >= 1, Bw >= 1, Cw >= 1, Dw >= 1, Ew >= 1 },
{ Ah = 2 },
{ A = Ah * Aw,
B = Bh * Bw,
C = Ch * Cw,
D = Dh * Dw,
E = Eh * Ew },
{ (Bw + Cw) = Aw,
Dw = Cw,
(Ah + Bh) = Eh,
(Ch + Dh) = Bh,
(Aw + Ew) = Eh },
minimize(Eh).
Which when queried:
?- solve(Eh).
false.
...makes me sad. Such a beautiful example for a constraint solver... Anyone cares to undo my sadness?
Addendum: I used Mathematica and the FindMinimum function to check for my constraints. It seems to be working:
domain = a >= 1 && b >= 1 && c >= 1 && d >= 1 && e >= 1 && ah == 2.0 && a == b == c == d == e && aw >= 1 && bw >= 1 && cw >= 1 && dw >= 1 && ew >= 1
rectangles = (a == ah*aw && b == bh*bw && c == ch*cw && d == dh*dw && e == eh*ew)
FindMinimum[{eh,
domain && rectangles &&
((bw + cw ) == aw && dw == cw && (ah + bh) == eh && (ch + dh) == bh && (aw + ew) == eh)},
{a, b, c, d, e, ah, aw, bh, bw, ch, cw, dh, dw, eh, ew}]
Answers:
{8., {a -> 12.8, b -> 12.8, c -> 12.8, d -> 12.8, e -> 12.8,
ah -> 2., aw -> 6.4, bh -> 6., bw -> 2.13333, ch -> 3.,
cw -> 4.26667, dh -> 3., dw -> 4.26667,
eh -> 8., ew -> 1.6}}

There is a old/new entry in CLP, clpBNR. You can install it in a recent version of SWI-Prolog.
I think it would require to group equations together into a single {}.
?- pack_install(clpBNR).
:- use_module(library(clpBNR)).
solve_(Eh) :-
Vs = [A,B,C,D,E, Aw,Bw,Cw,Dw,Ew, Ah,Bh,Ch,Dh,Eh],
Vs::real(1,100),
{ Ah == 2,
A is Ah * Aw,
B is Bh * Bw,
C is Ch * Cw,
D is Dh * Dw,
E is Eh * Ew,
A == B,
B == C,
C == D,
D == E,
(Bw + Cw) == Aw,
Dw == Cw,
(Ah + Bh) == Eh,
(Ch + Dh) == Bh,
(Aw + Ew) == Eh
},
solve(Vs).
?- solve_(Eh).
::(Eh, ...( 8.000000)) .

Related

How to find the number of Optimal Sequence Alignment between two sequences?

Today I have two sequences,
s1 = CCGGGTTACCA
s2 = GGAGTTCA
The Mismatch Score is -1, the Gap Score is -2.
The Optimal Sequence Alignment has two answers (miniumn penalty is -8).
ans1 = G - G A G T T - C - A
C C G G G T T A C C A
ans2 = - G G A G T T - C - A
C C G G G T T A C C A
ans3 = G - G A G T T - - C A
C C G G G T T A C C A
ans4 = - G G A G T T - - C A
C C G G G T T A C C A
If any algorithm can calculate the number of Optimal Sequence Alignment (it will return "4") ?
Or what can I do to solve this problem?
Thanks
My score system is on the picture.
I do the Needleman-Wunsch algorithm (dynamic program) to complete the table.
Finally, I give up to only find the number of Optimal Sequence Alignment.
I trackback to find all the possible answers and insert the set, so the the size of set is my answer.
set<pair<string, string>> st;
void findAll(string A, string B, int gap, int mis, int i, int j, string s1, string s2) {
if (s1.size() == max(A.size(), B.size()) && s2.size() == max(A.size(), B.size())) {
reverse(begin(s1), end(s1));
reverse(begin(s2), end(s2));
st.insert({s1, s2});
return;
}
if (i != 0 || j != 0) {
if (i == 0) {
findAll(A, B, gap, mis, i, j - 1, s1 + "-", s2 + B[j - 1]);
} else if (j == 0) {
findAll(A, B, gap, mis, i - 1, j, s1 + A[i - 1], s2 + "-");
} else {
if ((A[i - 1] == B[j - 1] && dp[i][j] == dp[i - 1][j - 1]) || (A[i - 1] != B[j - 1] && dp[i][j] == dp[i - 1][j - 1] + mis)) {
findAll(A, B, gap, mis, i - 1, j - 1, s1 + A[i - 1], s2 + B[j - 1]);
}
if (dp[i][j] == dp[i - 1][j] + gap) {
findAll(A, B, gap, mis, i - 1, j, s1 + A[i - 1], s2 + "-");
}
if (dp[i][j] == dp[i][j - 1] + gap) {
findAll(A, B, gap, mis, i, j - 1, s1 + "-", s2 + B[j - 1]);
}
}
}
}

ComputeGCD Dafny

Hi I am trying to prove that the code I write will return the GreatestCommonDivisor (ComputeGCD) with Dafny.
but i get stack . I dont undrstand how to prove it , and i cant change the ComputeGCD
requires and ensures . any Help please .
predicate CommonDivisor(a: nat, b: nat, c: nat)
{
c > 0 && c <=a && c <=b && a%c == b%c == 0 // i add that c<=a && c<=b
}
predicate GreatestCommonDivisor(a: nat, b: nat, c: nat)
{
CommonDivisor(a, b, c) &&
forall d: nat :: CommonDivisor(a, b, d) ==> d <= c
}
lemma {:verify false} GreatestCommonDivisorHeper (a: nat , b:nat , c: nat)
requires a > 0 && b > 0
ensures GreatestCommonDivisor( a, b, c)
{}
method {:verify false} ComputeGCD(a: nat, b: nat) returns (i: nat)
requires a > 0 && b > 0
ensures GreatestCommonDivisor(a, b, i)
{
var x: int;
i := a;
x := b;
assert i == a && x ==b;
while (x != i)
invariant i > 0 && x > 0
decreases x + i
{
if (i > x)
{
assert i > x;
i := i - x;
}
else{
assert i < x ;
x := x - i;
}
}
assert a > 0 && b > 0 ;
assert GreatestCommonDivisor(b - a, a, i);
GreatestCommonDivisorHeper(a,b,i);
// assert GreatestCommonDivisor(a, b, i) == GreatestCommonDivisor(a,b - a, i);
}

What sort of time complexity would be required to solve the RSA Factoring Challenge?

Although the challenge ended a long time ago, I'm kinda bored so I decided to try to factorise some of the numbers.
I initially had an O(n) algorithm, but then, I decided to research big O notation.
Apparently (I could be wrong), O(n) algorithms and O(2n) algorithms basically have the same running time. So do O(n) and O(4n) algorithms. In fact, O(n) and O(cn) algorithms (where c is an integer) essentially have the same running time.
So now, I have an O(8n) algorithm, but it isn't quick enough for 77-bit numbers.
What sort of time complexity would be required to factorise the first few RSA numbers (in under 5-ish minutes)?
My O(8n) algorithm:
import math
num = int(input())
sq = math.sqrt(num)
if num % 2 == 0:
print(2, int(num / 2))
elif sq % 1 == sq:
print(int(sq), int(sq))
else:
sq = round(sq)
a = 3
b = sq + (1 - (sq % 2))
c = ((b + 1) / 2)
d = ((b + 1) / 2)
c -= (1 - (c % 2))
d += (1 - (d % 2))
e = ((c + 1) / 2)
f = ((c + 1) / 2)
e -= (1 - (e % 2))
f += (1 - (f % 2))
g = ((d + 1) / 2) + d
h = ((d + 1) / 2) + d
g -= (1 - (g % 2))
h += (1 - (h % 2))
while a <= sq and num % a != 0 and b > 2 and num % b != 0 and c <= sq and num % c != 0 and d > 2 and num % d != 0 and e <= sq and num % e != 0 and f > 2 and num % f != 0 and g <= sq and num % g != 0 and h > 2 and num % h != 0:
a += 2
b -= 2
c += 2
d -= 2
e += 2
f -= 2
g += 2
h -= 2
if num % a == 0:
print(a, int(num / a))
elif num % b == 0:
print(b, int(num / b))
elif num % c == 0:
print(c, int(num / c))
elif num % d == 0:
print(d, int(num / d))
elif num % e == 0:
print(e, int(num / e))
elif num % f == 0:
print(f, int(num / f))
elif num % g == 0:
print(g, int(num / g))
elif num % h == 0:
print(h, int(num / h))
Your algorithm is poorly-implemented trial division. Throw it away.
Here is my basic prime-number library, using the Sieve of Eratosthenes to enumerate prime numbers, the Miller-Rabin algorithm to recognize primes, and wheel factorization followed by Pollard's rho algorithm to factor composites, which I leave to you to translate to Python:
function primes(n)
i, p, ps, m := 0, 3, [2], n // 2
sieve := makeArray(0..m-1, True)
while i < m
if sieve[i]
ps := p :: ps # insert at head of list
for j from (p*p-3)/2 to m step p
sieve[i] := False
i, p := i+1, p+2
return reverse(ps)
function isPrime(n, k=5)
if n < 2 then return False
for p in [2,3,5,7,11,13,17,19,23,29]
if n % p == 0 then return n == p
s, d = 0, n-1
while d % 2 == 0
s, d = s+1, d/2
for i from 0 to k
x = powerMod(randint(2, n-1), d, n)
if x == 1 or x == n-1 then next i
for r from 1 to s
x = (x * x) % n
if x == 1 then return False
if x == n-1 then next i
return False
return True
function factors(n, limit=10000)
wheel := [1,2,2,4,2,4,2,4,6,2,6]
w, f, fs := 0, 2, []
while f*f <= n and f < limit
while n % f == 0
fs, n := f :: fs, n / f
f, w := f + wheel[w], w+1
if w = 11 then w = 3
if n == 1 return fs
h, t, g, c := 1, 1, 1, 1
while not isPrime(n)
repeat
h := (h*h+c) % n # the hare runs
h := (h*h+c) % n # twice as fast
t := (t*t+c) % n # as the tortoise
g := gcd(t-h, n)
while g == 1
if isPrime(g)
while n % g == 0
fs, n := g :: fs, n / g
h, t, g, c := 1, 1, 1, c+1
return sort(n :: fs)
function powerMod(b, e, m)
x := 1
while e > 0
if e%2 == 1
x, e := (x*b)%m, e-1
else b, e := (b*b)%m, e//2
return x
function gcd(a, b)
if b == 0 then return a
return gcd(b, a % b)
Properly implemented, that algorithm should factor your 79-bit number nearly instantly.
To factor larger numbers, you will have to work harder. Look up "elliptic curve factorization" and "self-initializing quadratic sieve" to find factoring algorithms that you can implement yourself.

override moveTo and moveByPx methods of OpenLayers.Map

How to override moveTo and moveByPx methods of OpenLayers.Map for eliminate "movestart" event triggering for any actions except zooming ?
map = new OpenLayers.Map("map");
OpenLayers.Map.prototype.moveByPx = function (a, b) {
var c = this.size.w / 2,
d = this.size.h / 2,
e = c + a,
f = d + b,
g = this.baseLayer.wrapDateLine,
h = 0,
k = 0;
this.restrictedExtent && (h = c, k = d, g = !1);
a = g || e <= this.maxPx.x - h && e >= this.minPx.x + h ? Math.round(a) : 0;
b = f <= this.maxPx.y - k && f >= this.minPx.y + k ? Math.round(b) : 0;
if (a || b) {
this.dragging || (this.dragging = !0);
this.center = null;
a && (this.layerContainerOriginPx.x -= a, this.minPx.x -= a, this.maxPx.x -= a);
b && (this.layerContainerOriginPx.y -= b, this.minPx.y -= b, this.maxPx.y -= b);
this.applyTransform();
d = 0;
for (e = this.layers.length; d < e; ++d)
c = this.layers[d], c.visibility && (c === this.baseLayer || c.inRange) && (c.moveByPx(a, b), c.events.triggerEvent("move"));
this.events.triggerEvent("move")
}
}
map.events.register("movestart", map, function (e) {
My Code...
});

NMinimize is very slow

You are my last hope.
In my university there are no people able to answer my question.
I've got a function quite complex depending on 6 paramethers a0,a1,a2,b0,b1,b2 that minimize the delta of pression, volume liquid and volume vapor calculated by a rather new equation of state.
NMinimize is very slow and I could not do any considerations about this equation because timing is very high.
In the code there are some explanations and some problems concerning my code.
On my knees I pray you to help me.
I'm sorry, but after 4 months on construction of these equation I could not test it. And frustration is increasing day after day!
Clear["Global`*"];
data = {{100., 34.376, 0.036554, 23.782}, {105., 56.377, 0.037143,
15.116}, {110., 88.13, 0.037768, 10.038}, {115., 132.21, 0.038431,
6.9171}, {120., 191.43, 0.039138, 4.9183}, {125., 268.76,
0.039896, 3.5915}, {130., 367.32, 0.040714, 2.6825}, {135.,
490.35, 0.0416, 2.0424}, {140., 641.18, 0.042569, 1.5803}, {145.,
823.22, 0.043636, 1.2393}, {150., 1040., 0.044825,
0.98256}, {155., 1295., 0.046165, 0.78568}, {160., 1592.1,
0.047702, 0.63206}, {165., 1935.1, 0.0495, 0.51014}, {170.,
2328.3, 0.051667, 0.41163}, {175., 2776.5, 0.054394,
0.33038}, {180., 3285.2, 0.058078, 0.26139}, {185., 3861.7,
0.063825, 0.19945}, {190., 4518.6, 0.079902, 0.12816}};
tvector = data[[All, 1]];(*K*)
pvector =
data[[All, 2]];(*KPa*)
vlvector = data[[All, 3]];(*L/mol*)
vvvector =
data[[All, 4]];
(*L/mol.*)
r = 8.314472;
tc = 190.56;
avvicinamento = Length[tvector] - 3;
trexp = Take[tvector, avvicinamento]/tc;
vlexp = Take[vlvector, avvicinamento];
vvexp = Take[vvvector, avvicinamento];
zeri = Table[i*0., {i, avvicinamento}];
pexp = Take[pvector, avvicinamento];
(*Function for calculation of Fugacity of CSD Equation*)
(*Function for calculation of Fugacity of CSD Equation*)
fug[v_, p_, t_, a_, b_] :=
Module[{y, z, vbv, vb, f1, f2, f3, f4, f}, y = b/(4 v);
z = (p v)/(r t);
vbv = Log[(v + b)/v];
vb = v + b;
f1 = (4*y - 3*y^2)/(1 - y)^2;
f2 = (4*y - 2*y^2)/(1 - y)^3;
f3 = (2*vbv)/(r t*b)*a;
f4 = (vbv/b - 1/vb)/(r t)*a;
f = f1 + f2 - f3 + f4 - Log[z];
Exp[f]]
(*g Minimize the equality of fugacity*)
g[p_?NumericQ, t_?NumericQ, a0_?NumericQ, a1_?NumericQ, a2_?NumericQ,
b0_?NumericQ, b1_?NumericQ, b2_?NumericQ] := Module[{},
a = a0*Exp[a1*t + a2*t^2];
b = b0 + b1*t + b2*t^2;
csd = a/(r*t*(b + v)) - (-(b^3/(64*v^3)) + b^2/(16*v^2) +
b/(4*v) + 1)/(1 - b/(4*v))^3 + (p*v)/(r*t);
vol = NSolve[csd == 0 && v > 0, v, Reals];
sol = v /. vol;
(*If[Length[sol]==1,Interrupt[];Print["Sol==1"]];*)
vliquid = Min[sol];
vvapor = Max[sol];
fl = fug[vliquid, p, t, a, b];
fv = fug[vvapor, p, t, a, b];
(*Print[{t,p,vol,Abs[fl-fv]}];*)
Abs[fl - fv]];
(*This function minimize the pcalc-pexp and vcalc-vexp *)
hope[a0_?NumericQ, a1_?NumericQ, a2_?NumericQ, b0_?NumericQ,
b1_?NumericQ, b2_?NumericQ] :=
Module[{},
pp[a0, a1, a2, b0, b1, b2] :=
Table[FindRoot[{g[p, tvector[[i]], a0, a1, a2, b0, b1, b2]},
{p,pvector[[i]]}],{i,avvicinamento}];
pressioni1 = pp[a0, a1, a2, b0, b1, b2];
pcalc = p /. pressioni1;
differenza = ((pcalc - pexp)/pexp)^2;
If[MemberQ[differenza, 0.],
differenza = zeri + RandomReal[{100000, 500000}];(*
First problem:
As I've FindRoot that finds the solutions equal to the starting \
point, I don't want these kind of solutions and with this method - \
+RandomReal[{100000,500000}] -
a keep away this solutions.Is it right? *)
deltap = Total[differenza],
differenzanonzero = Select[differenza, # > 0 &];
csd1[a_, b_, p_, t_] :=
a/(r*t*(b + v)) - (-(b^3/(64*v^3)) + b^2/(16*v^2) + b/(4*v) +
1)/(1 - b/(4*v))^3 + (p*v)/(r*t);(*Funzione CSD*)
volumi =
Table[NSolve[csd1[a, b, pcalc[[i]], tvector[[i]]], v, Reals], {i,
avvicinamento}];
soluzioni = v /. volumi;
vvcalc = Table[Max[soluzioni[[i]]], {i, avvicinamento}];
vlcalc = Table[Min[soluzioni[[i]]], {i, avvicinamento}];
deltavl = Total[((vlexp - vlcalc)/vlcalc)^2];
deltavv = Total[((vvexp - vvcalc)/vvcalc)^2];
deltap = Total[differenza];
Print[a0, " ", b0, " ", delta];
delta = 0.1*deltavl + 0.1*deltavv + deltap]];
NMinimize[{hope[a0, a1, a2, b0, b1, b2],
500 < a0 < 700 && -0.01 < a1 < -1.0*10^-5 && -10^-5 < a2 < -10^-7 &&
0.0010 < b0 < 0.1 && -0.0010 < b1 < -1.0*10^-5 &&
10^-9 < b2 < 10^-7}, {a0, a1, a2, b0, b1, b2}]
Thanks in advance!
Mariano Pierantozzi
PhD Student in chemical Engineering

Resources