constraint satisfaction in java - java

I am having a problem programming the below problem in java it is a constraint satisfaction problem:
If I have constraints like this:
x1 + x2 > x3
x2 - x4 = 2
x1 + x4 < x5
Each of x1 to x5 are in the domain {0,1,2}
How do I program the different combinations such that I will have a set of tuples as: {(0,0,0), (0,0,1), (0,1,0),(0,1,1),(1,0,0), ......} for each constraint
that is constraint 1 for instant has domain of tuple such as {(0,0,0), (0,0,1), (0,1,0),(0,1,1),(1,0,0),(0,1,2),(2,0,1) ......}
I need the reply in any language but preferably java please.

You could perhaps do this through the use of some helper methods from the google commons collect library. It would look something like this:
I'm assuming that the tuples (0,0,0) etc are tuples of the input to the constraint, (x0, x1, x2) for constraint1, (x2, x4) for constraint2 etc.
So, for constraint1, first we fill a list with all possible combinations:
final List<int[]> allCombos = new ArrayList<int[]>();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
allCombos.add(new int[] {i, j, k});
}
}
}
for (final int[] i : allCombos) {
System.out.println(i[0] + ", " + i[1] + ", " + i[2]);
}
Next, we want to filter so we'll be left with the tuples that are allowed by constraint1:
final List<int[]> constraint1 = ImmutableList.copyOf(Iterables.filter(allCombos, new Predicate<int[]>() {
#Override
public boolean apply(#Nullable final int[] input) {
return input[0] + input[1] > input[2];
}
}));
for (final int[] i : constraint1) {
System.out.println(i[0] + ", " + i[1] + ", " + i[2]);
}
This might need a little explanation.
ImmutableList.copyOf is a method that creates a copy of a given list. To this method, we pass the result of Iterables.filter(), which takes a list (the input to be filtered), and a Predicate, which has an overridden method apply(), where you decide which element of the input list that are supposed to be part of the result list. Here, we basically just code the constraint itself, and the cases where the apply method returns true will be part of the filtered list. (I've chosen to represent the tuples as an array, you could use the filter-strategy with any tuple-representation..)
The result of the last printouts (the filtered list) will be:
0, 1, 0
0, 2, 0
0, 2, 1
1, 0, 0
1, 1, 0
1, 1, 1
1, 2, 0
1, 2, 1
1, 2, 2
2, 0, 0
2, 0, 1
2, 1, 0
2, 1, 1
2, 1, 2
2, 2, 0
2, 2, 1
2, 2, 2
I'll leave it up to you to do the same for the other constraints..

Related

Number of times a value occurs in each column of a 2d-array in Java?

ArrayList<Integer> newArray = new ArrayList<>();
for (int i =0; i < count; i++) {
newArray.add(i);
}
for (int j = 0; j <= 3; j++) {
Collections.shuffle(newArray);
System.out.println(newArray.toString());
}
//Let count equal 4 since we want a square
int[][] counters = new int[count][count];
int numAppear = 0;
int row = 0;
int col = 0;
for (row = 0; row < count; row++) {
for (col = 0; col < count; col++) {
if (newArray.get(row).equals(newArray.get(col))) {
numAppear++;
}
counters[row][col] = numAppear;
System.out.print(counters[row][col]+" ");
}
System.out.println();
}
In the code, I want to find how many times if i visit column j of row i, i appears at index j in the ArrayList for all the shuffles.
Also, I'm trying to print counter array, but i get memory hashes although i tried .toString as well as Arrays.toString
Let's say this is my output for shuffled array:
[3, 1, 2, 0]
[2, 0, 1, 3]
[1, 3, 2, 0]
[0, 1, 2, 3]
Now output for counters[row][col] = numAppear; should look like this:
First row:since row0 = col0 of shuffled array, numAppear = 1.
Third row there's a 2 in (2,2) because in (2,2) of shuffled array, #2 appears twice in the same column but in the previous rows
[1, 1, 1, 1]
[1, 1, 1, 1]
[1, 1, 2, 2]
[1, 2, 3, 2]
Why are you using
'counters[row][col] = numAppear;' ?
If it's just to eventually count it, initialize another int counter before you start iterating through the elements.
Since "numAppear" value persists between matches, I don't see the value in adding the temporary "numAppear" value to an array.
If I understand the goal of your print statement, this might be a viable alternative:
System.out.println("Found a match at row " + row + " and column " + col);
Edit: As for printing the matches, I'd initialize an array list at the outset and iterate through it at the end. e.g.:
ArrayList<String> matchList = new ArrayList<String>();
To add to it:
matchList.add(numAppear);//or whatever you're trying to add
Then at the end:
for (String s : matchList){
System.out.println("Match at: " + s);
}

Generating Power Set of a String Recursively in Java

I'm trying to do recursive implementation of a Power Set generator working off of some pseudocode I was given, but when given a string like "abc", rather than having sets
{}, {a}, {b}, {c}, {a,b}, {a,c}, {b,c}, and {a,b,c},
I get {}, {0}, {1}, {2}, {0,1}, etc.
public static ArrayList GenerateSubsets(String setString) {
ArrayList A = new ArrayList<String>();
ArrayList temp = new ArrayList<String>();
if(setString.length() > 0) {
temp = GenerateSubsets(setString.substring(0,setString.length() - 1));
for(int i = 0; i < temp.size(); i++) {
System.out.println("Temp i: "+temp.get(i));
A.add(temp.get(i));
A.add(temp.get(i) + " " + (setString.length() - 1));
}
return A;
}
else
A.add("");
return A;
}
This is based directly on the pseudocode, why isn't it working correctly?
Edit: This is the test
public static void main(String[] args) {
ArrayList one = GenerateSubsets("abcd");
for(int i = 0; i < one.size(); i++) {
System.out.print(one.get(i)+ ", ");
if(i%5 == 0) {
System.out.println("");
}
}
}
And I get output of (without the line breaks)
,
3, 2, 2 3, 1, 1 3,
1 2, 1 2 3, 0, 0 3, 0 2,
0 2 3, 0 1, 0 1 3, 0 1 2, 0 1 2 3,
Statement (setString.length() - 1) gives you the index of char. And by concatenating it you receive a Power set of indexes. You need use setString.charAt(setString.length()-1) to receive char at given position.

Java- Mapping multi-dimensional arrays to single

I am posting this in relation to another open question i have, however I thought that this deserved it's own question.
Alternate question (for reference): Java Proxy Discovering Bot
Basically, I need to store a very large amount of data and have it accessible very quickly. This would work ideally in an unlimited memory situation:
boolean[][][][] sets = new boolean[256][256][256][256];
boolean get(byte[] a) {
return sets[a[0]][a[1]][a[2]][a[3]];
}
However, this uses around 16gb of ram which is too much for my application. I figure that if using bits instead of booleans (stores as 4 bytes in Java) it would cut the memory usage to around 512MB. However, I can't seem to wrap my head around how to access the bits correctly. For example if you mapped each address something like this: position = a * b * c * d then it would map to the same bit as d * c * b * a etc.
I found this thread covering how to convert 2D arrays into 1D arrays, but I can't seem to wrap my head around how to extend that to a 4D array. Can anyone explain this?
Map a 2D array onto a 1D array C
The solution for 2D -> 1D arrays:
int array[width * height];
int SetElement(int row, int col, int value)
{
array[width * row + col] = value;
}
I am just not sure of how to extend it to 4D -> 1D
int array[256 * 256 * 256 * 256];
int setElement(int a, int b, int c, int d, boolean value)
{
array[?????????] = value;
}
To answer about mapping 4D to 1D, if you visualize, say, a chess board, you can come up with the formula for 2D to 1D by thinking if every row has width elements, and I first go down row number of rows and then move over to col, then I'm at width * row + col. Now imagine a stack of height number of chess boards and carry out the same exercise to extend it to three dimensions. Four dimensions is harder because you can't really visualize it, but by then you can see the pattern.
This program shows the formula for four dimensions. I ran it for very small numbers for posting here, but you can play with the dimensions and see how it works.
class Dim
{
// dimensions
static int d1 = 2 ; // "rows"
static int d2 = 2; // "cols"
static int d3 = 3; // "height"
static int d4 = 2; // the fourth dimension!
public static void main(String[] args) {
for (int i=0; i<d1; i++) {
for (int j=0; j<d2; j++) {
for (int k=0; k<d3; k++) {
for (int m=0; m<d4; m++) {
int oneD = fourDtoOneD(i, j, k, m);
System.out.printf("(%d, %d, %d, %d) -> %d\n", i, j, k, m, oneD);
}
}
}
}
}
static int fourDtoOneD(int i, int j, int k, int m) {
return ((d2*d3*d4) * i) + ((d2*d3) * j) + (d2 * k) + m;
}
}
$ java Dim
(0, 0, 0, 0) -> 0
(0, 0, 0, 1) -> 1
(0, 0, 1, 0) -> 2
(0, 0, 1, 1) -> 3
(0, 0, 2, 0) -> 4
(0, 0, 2, 1) -> 5
(0, 1, 0, 0) -> 6
(0, 1, 0, 1) -> 7
(0, 1, 1, 0) -> 8
(0, 1, 1, 1) -> 9
(0, 1, 2, 0) -> 10
(0, 1, 2, 1) -> 11
(1, 0, 0, 0) -> 12
(1, 0, 0, 1) -> 13
(1, 0, 1, 0) -> 14
(1, 0, 1, 1) -> 15
(1, 0, 2, 0) -> 16
(1, 0, 2, 1) -> 17
(1, 1, 0, 0) -> 18
(1, 1, 0, 1) -> 19
(1, 1, 1, 0) -> 20
(1, 1, 1, 1) -> 21
(1, 1, 2, 0) -> 22
(1, 1, 2, 1) -> 23

Split 1d array into chunks

I am trying to not load my entire tile based map into memory to save RAM client side. The map will be huge and already is requriring 1GB client side (multi-layered map).
I have gotten some perspective on Game Dev SO. I am trying to Load zones/chunks of my game map into memory (i.e. 300x300) and then when the player moves 100 steps shift the array and load 100 new tiles depending on direction. I have tried to work on a scaled version of this and now have a generic question.
I need help when the playerX/Y coordinates are on the perimeter of the map (which causes the chunk to be outside of the map)
Here is what I have come up with so far (note: player is in center of chunk & chunk always odd number sized)... It has the following issues(when the character is on the edge of the map):
change characterX/Y to 0,0 and the bottom left(0,2) coordinate will incorrectly be 7
0, 0, 0
0, 1, 1
7, 1, 8
change characterX/Y to 8,8 and the top right(2,0) coordinate of the chunk will incorrectly be 6
1, 1, 6
1, 1, 0
0, 0, 0
Here is the SSCCE:
public class MapChunkLoad {
public static void main(String[] args) {
short[] groundLayer;
int mapWidth = 9;
int mapHeight = 9;
int chunkWidth = mapWidth / 3; //3
int chunkHeight = mapHeight / 3; //3
int characterX = 8;
int characterY = 8;
String map = "1, 1, 1, 1, 1, 1, 1, 1, 7, " +
"1, 8, 8, 1, 1, 1, 1, 1, 1, " +
"1, 8, 9, 9, 1, 1, 1, 1, 1, " +
"1, 1, 9, 9, 1, 1, 1, 1, 1, " +
"1, 1, 1, 1, 1, 1, 1, 1, 1, " +
"1, 1, 1, 1, 1, 1, 1, 1, 1, " +
"1, 1, 1, 1, 1, 1, 1, 1, 1, " +
"1, 1, 1, 1, 1, 1, 1, 1, 1, " +
"6, 1, 1, 1, 1, 1, 1, 1, 1";
String[] strArr = map.split(", ");
groundLayer = new short[chunkWidth * chunkHeight];
//load chunk into groundLayer
int arrayIndex = 0;
int count = (characterX - (chunkWidth/2)) + ((characterY - (chunkHeight/2)) * mapWidth); //top left tile within chunk
for (int y = 0; y < chunkHeight; y++){
for (int x = 0; x < chunkWidth; x++){
if (count > -1 && count < strArr.length){
groundLayer[arrayIndex] = Short.parseShort(strArr[count]);
System.out.println("arrayIndex[" + arrayIndex + "] = " + strArr[count]);
} else {
groundLayer[arrayIndex] = 0;
System.out.println("arrayIndex[" + arrayIndex + "] = " + 0);
}
arrayIndex++;
count++;
}
count += (mapWidth - chunkWidth);
}
System.out.println("");
//print map grid
int printcount = 0;
for (int y = 0; y < chunkHeight; y++){
for (int x = 0; x < chunkWidth; x++){
if (x == chunkWidth - 1){
System.out.println(groundLayer[printcount]);
} else {
System.out.print(groundLayer[printcount] + ", ");
}
printcount++;
}
}
}
}
Thanks so much for any assistance.
So I think your logic for checking if count is outside the bounds is faulty.
I think it needs to be more complex to account for that your array represents a 2D figure. I suspect for chunks larger than 3x3 you're getting a lot more errors that are really tricky to describe. Consider this map where each square's value is its index.
0 1 2
3 4 5
6 7 8
when in the top right corner (2) your map should look like this
0 0 0
1 2 0
4 5 0
but this will fail because count will in some cases be a valid index when calculating xValue*width+yValue, but you want that to be invalid (mapped to 0). Instead you need to keep track of both the X and Y components of count and make your map display a zero when either of those are out of bounds.
int countX = characterX - (chunkWidth/2);
int countY = characterY - (chunkHeight/2);
int index = countX + (countY*mapWidth)
then later. Instead of checking:
if (count > -1 && count < strArr.length)
check:
if( countX + x >= mapWidth || countY + y >= mapHeight)
EDIT:
As you can imagine this also changes how you count. You will also need a way to break your loop. Something like
if(x == chunkWidth && y == chunkWidth) break;
I would be more specific, but I'm having trouble loading your original post to use as reference.
I think that fixes everything. Leave a comment if you have any questions. Good luck!
I'm not sure if this is what you are looking for, but commonly you'd check for bounds inside your nested for-loop that fills the groundLayer, rather than checking with a count variable. That way will be much more robust. Something like this:
for(int y = 0;y < chunkHeight;y++) {
for(int x = 0;x < chunkWidth;x++) {
//Get the absolute position of the cell.
int cellX = characterX + x - chunkWidth / 2; //Please check if this is correctly lined out.
int cellY = characterY + y - chunkHeight / 2;
if(cellX >= 0 && cellX < mapWidth && cellY >= 0 && cellY < mapHeight) { //Within bounds.
groundLayer[arrayIndex] = Short.parseShort(strArr[cellX + (cellY * mapWidth)]);
} else { //Out of bounds, put down a placeholder.
groundLayer[arrayIndex] = 0;
}
arrayIndex++;
}
}
Let me know if this was what you were looking for, and whether it works!

Find array indices

I'm sure there is a CS term for what I'm trying to accomplish but I'm not sure what it is. I have three arrays, let's call them a, b, and c. I am iterating through every possible combination of the arrays, which would be a*b*c iterations.
I am passing a function an int of the current iteration (such that iteration goes from 0 to a*b*c-1) and the length of a, b, and c. I want that function to be able to print out every unique permutation of indices, calculated from just the iteration count and the lengths of a, b, and c.
This is what I have now:
class Test {
public static void printIndices(int i, int a, int b, int c) {
System.out.println(i%a + ", " + (i+1)%b + ", " + (i+2)%c);
}
public static void main(String[] args) {
int a[] = new int[2];
int b[] = new int[2];
int c[] = new int[3];
int iterations = a.length * b.length * c.length;
for (int i=0; i < iterations; i++){
printIndices(i, a.length, b.length, c.length);
}
}
}
It generates this output:
0, 1, 2
1, 0, 0
0, 1, 1
1, 0, 2
0, 1, 0
1, 0, 1
0, 1, 2
1, 0, 0
0, 1, 1
1, 0, 2
0, 1, 0
1, 0, 1
As you can see there are duplicates. I want the output to be:
0, 0, 0
1, 0, 0
0, 1, 0
1, 1, 0
0, 0, 1
1, 0, 1
0, 1, 1
1, 1, 1
0, 0, 2
1, 0, 2
0, 1, 2
1, 1, 2
(the order is unimportant, as long as every permutation is there with no duplicates).
Obviously my output line is wrong:
System.out.println(i%a + ", " + (i+1)%b + ", " + (i+2)%c);
What are the correct operations to get the output I am looking for?
I understand that this code is a bit silly looking and it's not at all what I'm actually doing, but it demonstrates the case well.
As mentioned in the comments you are looking for the Cartesian product.
Your approach with modular arithmetic almost works. You need only a few modifications to get the correct result:
System.out.println(i%a + ", " + (i/a)%b + ", " + (i/a/b)%c);
See it working online: ideone

Categories