Efficient predicate for palindrome in Minizinc - constraint-programming

To help me learning Minizinc, I am trying to solve an easy problem. My code finds an answer but I am surprised that it takes about 10 seconds to run for such an easy problem.
The problem is "What is the smallest palindromic integer > 10, so that the sum of its digits is > 10 and palindromic too ?".
And I want the code to do large assumptions only: answer has 8 digits at most.
My code is (the toNum predicate comes from hakank website):
predicate toNum(array[int] of var int: a, var int: n, int: base) =
let { int: len = length(a) }
in
n = sum(i in 1..len) (
ceil(pow(int2float(base), int2float(len-i))) * a[i]
)
/\ forall(i in 1..len) (a[i] >= 0 /\ a[i] < base)
;
predicate toNum10(array[int] of var 0..9: a, var int: n) = toNum(a, n, 10);
predicate palindrome_array(array[int] of var int: t) =
let { int: l = length(t), var 1..l: d } in (
forall(j in 1..d-1) (t[j] = 0) /\
t[d] != 0 /\
forall(j in d..(l+d-1) div 2) (t[j] = t[l+d-j])
)
;
predicate palindrome_int(var int: n) =
let { int: size = ceil(log10(int2float(ub(n))))+1,
array[1..size] of var 0..9: digits } in (
toNum10(digits, n) /\
palindrome_array(digits)
)
;
var int: n;
array[1..8] of var 0..9: t;
constraint toNum10(t, n);
constraint palindrome_int(n);
constraint n>10;
var int: s = sum(t);
constraint palindrome_int(s);
constraint s>10;
constraint alldifferent([n, s]);
solve minimize n;
The complete version has the following additional constraints:
var int: s2 = sum(i in 1..8) (t[i]*t[i]);
constraint palindrome_int(s2);
constraint s2 > 10;
var int: s3 = sum(i in 1..8) (t[i]*t[i]*t[i]);
constraint palindrome_int(s3);
constraint s3 > 10;
constraint alldifferent([n, s, s2, s3]);
What's wrong/slow with my code ?

Try to replace "solve minimize n;" with the following labeling strategy:
solve :: int_search(t, first_fail, indomain_min, complete) minimize n;
On my machine, it then takes < 0.1s.

Related

Minizinc bitwise operators (or similar efficient operation)?

I would like to constrain an integer variable to have as value the bitwise XOR of some other integers.
I know I can encode the values in boolean arrays instead of integers and have something like forall (i, j in 1..n) c[i] = a[i] xor b[i] but I would like something more efficient.
Is there any way to use bitwise operators in Minizinc (or directly Flatzinc)?
Or alternatively a global constraint or something I can use to achieve what I want and make sure it is implemented efficiently? I am using Gecode as solver.
The following MiniZinc model demonstrates a function to compute the bitwise XOR of two integer variables:
include "globals.mzn";
int: bits = 15;
set of int: Bits = 0 .. bits-1;
set of int: Domain = 0 .. pow(2, bits) - 1;
var Domain: x;
var Domain: y;
% pre-calculate powers of 2: 1, 2, 4, ...
array[Bits] of Domain: twopow = array1d(Bits, [pow(2, i) | i in Bits]);
% test bit in int
function var int: bit_of(var int: num, Bits: idx) =
((num div twopow[idx]) mod 2);
% function to calculate the bitwise XOR of two ints
function var int: bitxor(var int: x, var int: y) =
sum([twopow[i] * ((bit_of(x, i) + bit_of(y, i)) mod 2) | i in Bits]);
constraint y = 0x05;
constraint bitxor(x, y) = 0xA5;
solve satisfy;
output ["\(x) \(y)"];

Ocaml - Check, given a list of transitions, the word is recognized

I created a function that returns a list of transitions. Transitions are of type int * char * int.
for example (0 'E' 1); (1 'A' 2). The valid alphabet for the transitions are A, C, G and T and the char 'E' represents epsilon.
type transition = int * char * int;;
let get_start (a,_,_) = a;;
let get_char (_,a,_) = a;;
let get_end (_,_,a) = a;;
The initial state and the final state are stored in the following variables.
...
let i_strt = ref !state_initial;;
let i_end = ref !state_end;;
exception Out_of_loop;;
let seq = read_line();;(* string to be tested *)
let len_seq = String.length seq -1;;
let lst_trs_length = List.length !aux_transitions -1;; (* aux_transitions -> all transitions*)
let i = ref 0;;
let f = ref 0;;
while !i <= len_seq do
let c_r = seq.[i]in (* c_r = 'A' seq = ACGT*)
try
while !j <= lst_trs_length do
let aux_trs = List.nth !aux_transitions !j in (* 0 'E' 1 -> 1 'A' 2 ....*)
if (get_start aux_trs) = !i_strt then (* *)
let aux_chr = get_char aux_trs in (* 'A' *)
if aux_chr = c_r then(
i_strt := get_end aux_trs; (* i_strt = 1*)
raise Out_of_loop
)
else if aux_chr = 'E' then(
i_strt := get_end aux_trs;
j := -1
);
j := !j+1
done;
with Out_of_loop ->();
i := !i +1
done;
I am trying to use these two cycles to check whether the string "seq" can be recognized or not by the list of transitions taking into account the initial state. I am having trouble writing this function ... I want a function that, given a list of transitions and a string, returns 'true' in case it is recognized or false in the negative case.

Asserting about the return value of a method involving sequences

I'm a beginner with Dafny, and I'm wondering why the assertion just before the print in the Main method is violated. I'm trying to find the rightmost index where an item should be inserted in order to preserve the order in the sequence, which in this specific case is 4.
https://rise4fun.com/Dafny/4lR2
method BinarySearchInsertionHint(a: seq<int>, key: int) returns (r: int)
requires forall i,j :: 0 <= i < j < |a| ==> a[i] <= a[j]
ensures 0 <= r <= |a|
ensures forall i :: 0 <= i < r ==> a[i] <= key
ensures r < |a| ==> forall i :: r <= i < |a| ==> key < a[i]
{
var lo, hi := 0, |a|;
while lo < hi
decreases hi - lo
invariant 0 <= lo <= hi <= |a|
invariant forall i :: 0 <= i < lo ==> a[i] <= key
invariant forall i :: hi <= i < |a| ==> key < a[i]
{
var mid := (lo + hi) / 2;
assert(lo <= mid < hi);
if a[mid] <= key {
lo := mid + 1;
} else if key < a[mid] {
hi := mid;
}
}
assert(lo == hi);
r := lo;
}
method Main() {
var a := [0, 1, 1, 1, 2];
var hint := BinarySearchInsertionHint(a, 1);
assert hint == 4; // assertion violation
print hint;
}
This can indeed be confusing! There are a few things going on here.
First, remember that Dafny reasons about each method separately, using only the specifications of other methods. So in Main, the only thing Dafny will know about BinarySearchInsertionHint is its postconditions. Now it turns out that hint == 4 actually does follow from the postconditions, but it's a little nontrivial to convince Dafny of this.
This brings us to the Second Thing going on here, which is quantifier triggers. The postconditons of BinarySearchInsertionHint use universal quantifiers (forall), which Dafny reasons about using syntactic heuristics for instantiation. Both of the quantifiers in this example are triggered on a[i], which means that they will not be used at value v unless a[v] is "in scope" for the verifier.
You can get the assertion to pass by mentioning a[3] and a[4], which is enough for Dafny to figure out from the postconditions that hint must be 4. Like this:
method Main() {
var a := [0, 1, 1, 1, 2];
var hint := BinarySearchInsertionHint(a, 1);
assert a[3] == 1; // these assertions just "mention" a[3] and a[4]
assert a[4] == 2;
assert hint == 4; // assertion now passes
print hint;
}
You can read more about Dafny's modular verification, incompleteness, and quantifier triggers in the Dafny FAQ.

coin change recurrence solution

Given a value N, if we want to make change for N cents, and we have infinite supply of each of S = { S1, S2, .. , Sm} valued coins, how many ways can we make the change? The order of coins doesn’t matter.There is additional restriction though: you can only give change with exactly K coins.
For example, for N = 4, k = 2 and S = {1,2,3}, there are two solutions: {2,2},{1,3}. So output should be 2.
Solution:
int getways(int coins, int target, int total_coins, int *denomination, int size, int idx)
{
int sum = 0, i;
if (coins > target || total_coins < 0)
return 0;
if (target == coins && total_coins == 0)
return 1;
if (target == coins && total_coins < 0)
return 0;
for (i=idx;i<size;i++) {
sum += getways(coins+denomination[i], target, total_coins-1, denomination, size, i);
}
return sum;
}
int main()
{
int target = 49;
int total_coins = 15;
int denomination[] = {1, 2, 3, 4, 5};
int size = sizeof(denomination)/sizeof(denomination[0]);
printf("%d\n", getways(0, target, total_coins, denomination, size, 0));
}
Above is recursive solution. However i need help with my dynamic programming solution:
Let dp[i][j][k] represent sum up to i with j elements and k coins.
So,
dp[i][j][k] = dp[i][j-1][k] + dp[i-a[j]][j][k-1]
Is my recurrence relation right?
I don't really understand your recurrence relation:
Let dp[i][j][k] represent sum up to i with j elements and k coins.
I think you're on the right track, but I suggest simply dropping the middle dimension [j], and use dp[sum][coinsLeft] as follows:
dp[0][0] = 1 // coins: 0, desired sum: 0 => 1 solution
dp[i][0] = 0 // coins: 0, desired sum: i => 0 solutions
dp[sum][coinsLeft] = dp[sum - S1][coinsLeft-1]
+ dp[sum - S2][coinsLeft-1]
+ ...
+ dp[sum - SM][coinsLeft-1]
The answer is then to be found at dp[N][K] (= number of ways to add K coins to get N cents)
Here's some sample code (I advice you to not look until you've tried to solve it yourself. It's a good exercise):
public static int combinations(int numCoinsToUse, int targetSum, int[] denom) {
// dp[numCoins][sum] == ways to get sum using numCoins
int[][] dp = new int[numCoinsToUse+1][targetSum];
// Any sum (except 0) is impossible with 0 coins
for (int sum = 0; sum < targetSum; sum++) {
dp[0][sum] = sum == 0 ? 1 : 0;
}
// Gradually increase number of coins
for (int c = 1; c <= numCoinsToUse; c++)
for (int sum = 0; sum < targetSum; sum++)
for (int d : denom)
if (sum >= d)
dp[c][sum] += dp[c-1][sum - d];
return dp[numCoinsToUse][targetSum-1];
}
Using your example input:
combinations(2, 4, new int[] {1, 2, 3} ) // gives 2

Generate all compositions of an integer into k parts

I can't figure out how to generate all compositions (http://en.wikipedia.org/wiki/Composition_%28number_theory%29) of an integer N into K parts, but only doing it one at a time. That is, I need a function that given the previous composition generated, returns the next one in the sequence. The reason is that memory is limited for my application. This would be much easier if I could use Python and its generator functionality, but I'm stuck with C++.
This is similar to Next Composition of n into k parts - does anyone have a working algorithm?
Any assistance would be greatly appreciated.
Preliminary remarks
First start from the observation that [1,1,...,1,n-k+1] is the first composition (in lexicographic order) of n over k parts, and [n-k+1,1,1,...,1] is the last one.
Now consider an exemple: the composition [2,4,3,1,1], here n = 11 and k=5. Which is the next one in lexicographic order? Obviously the rightmost part to be incremented is 4, because [3,1,1] is the last composition of 5 over 3 parts.
4 is at the left of 3, the rightmost part different from 1.
So turn 4 into 5, and replace [3,1,1] by [1,1,2], the first composition of the remainder (3+1+1)-1 , giving [2,5,1,1,2]
Generation program (in C)
The following C program shows how to compute such compositions on demand in lexicographic order
#include <stdio.h>
#include <stdbool.h>
bool get_first_composition(int n, int k, int composition[k])
{
if (n < k) {
return false;
}
for (int i = 0; i < k - 1; i++) {
composition[i] = 1;
}
composition[k - 1] = n - k + 1;
return true;
}
bool get_next_composition(int n, int k, int composition[k])
{
if (composition[0] == n - k + 1) {
return false;
}
// there'a an i with composition[i] > 1, and it is not 0.
// find the last one
int last = k - 1;
while (composition[last] == 1) {
last--;
}
// turn a b ... y z 1 1 ... 1
// ^ last
// into a b ... (y+1) 1 1 1 ... (z-1)
// be careful, there may be no 1's at the end
int z = composition[last];
composition[last - 1] += 1;
composition[last] = 1;
composition[k - 1] = z - 1;
return true;
}
void display_composition(int k, int composition[k])
{
char *separator = "[";
for (int i = 0; i < k; i++) {
printf("%s%d", separator, composition[i]);
separator = ",";
}
printf("]\n");
}
void display_all_compositions(int n, int k)
{
int composition[k]; // VLA. Please don't use silly values for k
for (bool exists = get_first_composition(n, k, composition);
exists;
exists = get_next_composition(n, k, composition)) {
display_composition(k, composition);
}
}
int main()
{
display_all_compositions(5, 3);
}
Results
[1,1,3]
[1,2,2]
[1,3,1]
[2,1,2]
[2,2,1]
[3,1,1]
Weak compositions
A similar algorithm works for weak compositions (where 0 is allowed).
bool get_first_weak_composition(int n, int k, int composition[k])
{
if (n < k) {
return false;
}
for (int i = 0; i < k - 1; i++) {
composition[i] = 0;
}
composition[k - 1] = n;
return true;
}
bool get_next_weak_composition(int n, int k, int composition[k])
{
if (composition[0] == n) {
return false;
}
// there'a an i with composition[i] > 0, and it is not 0.
// find the last one
int last = k - 1;
while (composition[last] == 0) {
last--;
}
// turn a b ... y z 0 0 ... 0
// ^ last
// into a b ... (y+1) 0 0 0 ... (z-1)
// be careful, there may be no 0's at the end
int z = composition[last];
composition[last - 1] += 1;
composition[last] = 0;
composition[k - 1] = z - 1;
return true;
}
Results for n=5 k=3
[0,0,5]
[0,1,4]
[0,2,3]
[0,3,2]
[0,4,1]
[0,5,0]
[1,0,4]
[1,1,3]
[1,2,2]
[1,3,1]
[1,4,0]
[2,0,3]
[2,1,2]
[2,2,1]
[2,3,0]
[3,0,2]
[3,1,1]
[3,2,0]
[4,0,1]
[4,1,0]
[5,0,0]
Similar algorithms can be written for compositions of n into k parts greater than some fixed value.
You could try something like this:
start with the array [1,1,...,1,N-k+1] of (K-1) ones and 1 entry with the remainder. The next composition can be created by incrementing the (K-1)th element and decreasing the last element. Do this trick as long as the last element is bigger than the second to last.
When the last element becomes smaller, increment the (K-2)th element, set the (K-1)th element to the same value and set the last element to the remainder again. Repeat the process and apply the same principle for the other elements when necessary.
You end up with a constantly sorted array that avoids duplicate compositions

Resources