[gecode-users] Help:How to compute Autocorrelation of a v-length sequence
George Rudolph
george.rudolph at citadel.edu
Thu Oct 18 19:41:51 CEST 2007
As stated in the comments below, I need help figuring out
how to express constraints on the autocorrelation of a v-length sequence.
I am sure there is an easier way to rotate a list,
compare two lists for positional matches, count the member of matches,
and constrain the number of matches to be a particular value,
and I need help finding it.
------------- begin code --------------
package citadel;
import static org.gecode.Gecode.*;
import static org.gecode.GecodeEnumConstants.*;
import org.gecode.*;
/**
* Script for computing 2-class association schemes, modified from the Queens
* example. The goal of this script is to generate (v-1)-length sequences with
* the following properties:
* 1. v is prime and v=4t+1, t >=0.
* 2. each sequence has n1 occurrences of lambda1 and n2 occurrences of lambda2.
* 3. the sequence is a palindrome: element 0 and element v-2 have the sane value, element 1 and
* element v-3 have the same value, element 2 and element 4-4 have the same
* value, etc.
* 4. The autocorrelation sequence generated by this sequence is flat. That is,
* if you prepend a 0 to the sequence, and then take the cross-correlation C of
* the extended sequence with rotated copies of itself for all shift values y=1...(v-1),
* then c[i] = 2t-1.
* Since 0 matched with non-zero value is a mismatch, it should be possible
* take the cross-correlation without prepending the 0.
*
* @author George Rudolph
* @version 1.0 Sep 20, 2007
*/
public class AssociationScheme extends Space {
/**
* v is the size or length of the sequence,
* must be prime.
*/
public int v;
/**
* v = 4t + 1, so t = (v-1)/4, t > 0
*/
public int t;
/**
* the number of 1st associates of any element x.
*/
public int n1;
/**
* The number of 2nd associates of any element x.
*/
public int n2;
/**
*
*/
public int lambda1;
public int lambda2;
public VarArray<IntVar> schemeCount;
/**
* @param opt
* Convenience object containing options
* @see citadel.Options#toString()
*/
public AssociationScheme(Options opt) {
super();
v = opt.size;
t = (v - 1) / 4;
n1 = (v - 1) / 2;
n2 = (v - 1) / 2;
lambda1 = 1;
lambda2 = 2;
schemeCount = new VarArray<IntVar>(this, v - 1, IntVar.class, 1, 2);
// in the difference vector, constrain it so that
// the value of position i is the same as the value at position v-i
// for a (v-1)-length array starting at (conceptual) index 1
// TODO: simplify the indexing in this constraint
for (int i = 1; i <= v - 1; i++) {
rel(this, schemeCount.get(i - 1), IRT_EQ, schemeCount
.get(v - 1 - i), opt.icl);
}
// "exactly n1 elements have the value lambda1 in schemeCount"
// "exactly n2 elements have the value lambda2 in schemeCount"
count(this, schemeCount, lambda1, IRT_EQ, n1, opt.icl);
count(this, schemeCount, lambda2, IRT_EQ, n2, opt.icl);
/********************** begin autocorrelation code ***************************/
/** what am I doing wrong below? **/
/* each element of the autocorrelation sequence for schemeCount
// must equal 2t-1 = ((v-1)/2) - 1
// autocorrelation is the cross-correlation of a sequence with a rotated copy
// of itself.
// An autocorrelation sequence is the sequence generated by taking the
// cross-correlation for each rotation--the ith position in the autocorrelation
// sequence is obtained by taking the cross-correlation of schemeCount with a
// copy of schemeCount rotated right i places (mod v).
// But I don't need a second copy of the sequence, I can just manipulate
// the indices. This is what I am trying to do below, but I am not getting
* the results I expect. Invalid solutions are being accepted.
*
* The algorithm is to match schemeCount against a shifted copy of itself using
* the offset y, count the matches as 1, and the mismatches as 0,
* stored in the sequence Intersect0Y, then sum up all
* the 1's in Intersect0Y, and finally, constrain that the sum must be 2t-1
* for *each* shift 1...v-1.
* It works for v=5, but is broken for v=13.
* I suspect it only works for v-5 because of the small space.
*
* If there is an easier way to write this constraint,
* I'm open to suggestions.
*
* 212211112212 is a valid solution for v=13.
*
* Note, really the sequence is 0212211112212,
* so rotated 5 places it looks like 1221202122111,
* but since 0 matched with anything is 10, in this case,
* I'm trying to avoid prepending the 0 to schemeCount,
* which doesn't include it above.
*
*/
for (int y = 1; y < v; y++) {
VarArray<BoolVar> intersectY0 = new VarArray<BoolVar>(this, v - 1,
BoolVar.class);
for (int x = 1; x < v; x++) {
if (x == y) {
continue;
}
int z = ((x - y + v) % v)-1;
eq(this, schemeCount.get(y-1), schemeCount.get(z), intersectY0
.get(x-1), opt.icl);
} // end for x
VarArray<IntVar> pijk = new VarArray<IntVar>(intersectY0);
// exactly 2t-1 elements have the value 1 in pijk
count(this, pijk, 1, IRT_EQ, 2 * t - 1, opt.icl);
} // end for y
/*********************** end autocorrelation code **************************/
branch(this, schemeCount, BVAR_SIZE_MIN, BVAL_MIN);
}
/**
* Copy constructor.
*
* @param share
* @param scheme
*/
public AssociationScheme(Boolean share, AssociationScheme scheme) {
super(share, scheme);
v = scheme.v;
t= (v-1)/4;
n1 = (v - 1) / 2;
n2 = (v - 1) / 2;
lambda1 = 1;
lambda2 = 2;
schemeCount = new VarArray<IntVar>(this, share, scheme.schemeCount);
}
/**
*
* @see org.gecode.Space#toString()
*/
public String toString() {
return schemeCount.toString();
}
/**
* Application startup
*
* @param args
*/
public static void main(String[] args) {
Options opt = new Options();
opt.size = 5;
opt.gui = true;
opt.parse(args);
opt.name = "" + opt.size + "-Schemes";
AssociationScheme schemes = new AssociationScheme(opt);
opt.doSearch(schemes);
}
}
--------------------- end code -------------------
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.ps.uni-sb.de/pipermail/users/attachments/20071018/c0c34fb9/attachment.htm>
More information about the gecode-users
mailing list