Skip to content

Commit

Permalink
adding ability to specify probability split returns voxelsA vs voxelsB
Browse files Browse the repository at this point in the history
  • Loading branch information
Jannetty committed Sep 19, 2024
1 parent 4db2077 commit cae8cb1
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 39 deletions.
86 changes: 53 additions & 33 deletions src/arcade/potts/env/location/PottsLocation.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import arcade.core.env.location.Location;
import arcade.core.env.location.LocationContainer;
import arcade.core.util.Utilities;
import arcade.potts.util.PottsEnums.Direction;
import arcade.potts.util.PottsEnums.Region;
import static arcade.potts.util.PottsEnums.Direction;
import static arcade.potts.util.PottsEnums.Region;

Expand Down Expand Up @@ -42,6 +40,8 @@ public abstract class PottsLocation implements Location {

/** Relative padding for selecting maximum diameter. */
private static final double DIAMETER_RATIO = 0.9;

private static final double DEFAULT_SPLIT_PROBABILITY = 0.5;

Check failure on line 44 in src/arcade/potts/env/location/PottsLocation.java

View workflow job for this annotation

GitHub Actions / checkstyle

[checkstyle] src/arcade/potts/env/location/PottsLocation.java#L44 <com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocVariableCheck>

Missing a Javadoc comment.
Raw output
/github/workspace/./src/arcade/potts/env/location/PottsLocation.java:44:5: error: Missing a Javadoc comment. (com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocVariableCheck)

/** List of voxels for the location. */
final ArrayList<Voxel> voxels;
Expand Down Expand Up @@ -269,7 +269,7 @@ public void update(int id, int[][][] ids, int[][][] regions) {
* @return a location with the split voxels
*/
public Location split(MersenneTwisterFast random) {
return split(random, null, null);
return split(random, null, null, DEFAULT_SPLIT_PROBABILITY);
}

/**
Expand All @@ -281,7 +281,22 @@ public Location split(MersenneTwisterFast random) {
* @return a location with the split voxels
*/
public Location split(MersenneTwisterFast random, ArrayList<Integer> offsetPercents) {
return split(random, offsetPercents, null);
return split(random, offsetPercents, null, DEFAULT_SPLIT_PROBABILITY);
}

/**
* Splits the location voxels into two lists at the point specified by
* offsetPercents and along the specified direction.
*
* @param random the seeded random number generator
* @param offsetPercents the percentage offset in each direction for the split point
* @param direction the direction of the split
* @return a location with the split voxels
*/
public Location split(MersenneTwisterFast random,
ArrayList<Integer> offsetPercents,
Direction direction) {
return split(random, offsetPercents, direction, DEFAULT_SPLIT_PROBABILITY);
}

/**
Expand All @@ -296,14 +311,17 @@ public Location split(MersenneTwisterFast random, ArrayList<Integer> offsetPerce
* @param random the seeded random number generator
* @param offsetPercents the percentage offset in each direction for the split point
* @param direction the direction of the split, or null if using shortest diameter
* @param splitProbability The probability to decide which group to keep.
* @return a location with the split voxels
*/
public Location split(MersenneTwisterFast random,
ArrayList<Integer> offsetPercents,
Direction direction) {
ArrayList<Integer> offsetPercents,
Direction direction,
Double splitProbability) {
Voxel splitpoint;
boolean shouldBalance;

double probability = splitProbability;

// Case 1: If offsetPercents are provided, don't balance the voxels
if (offsetPercents != null) {
splitpoint = getSplitpoint(offsetPercents);
Expand All @@ -317,8 +335,8 @@ public Location split(MersenneTwisterFast random,
splitpoint = getSplitpoint();
shouldBalance = true; // This can be changed if needed
}
return performSplit(random, splitpoint, direction, shouldBalance);

return performSplit(random, splitpoint, direction, shouldBalance, probability);
}

/**
Expand All @@ -333,32 +351,34 @@ public Location split(MersenneTwisterFast random,
* @param splitpoint the voxel that determines where the split occurs
* @param direction the direction of the split (can be null)
* @param shouldBalance indicates whether voxels should be balanced
* @param splitProbability indicates the probability voxelsA are returned vs voxelsB.
* Determines which voxels are kept in the original location.
* @return a {@code Location} containing the split voxels that are not
* assigned to the current location
*/
Location performSplit(MersenneTwisterFast random,
Voxel splitpoint, Direction direction,
boolean shouldBalance) {
// Initialize lists of split voxels
ArrayList<Voxel> voxelsA = new ArrayList<>();
ArrayList<Voxel> voxelsB = new ArrayList<>();

// Perform the split along the specified direction
if (direction == null) {
direction = getDirection(random);
}
splitVoxels(direction, voxels, voxelsA, voxelsB, splitpoint, random);

// Only balance if 'shouldBalance' is true
if (shouldBalance) {
connectVoxels(voxelsA, voxelsB, this, random);
balanceVoxels(voxelsA, voxelsB, this, random);
}

// Select one split to keep for this location and return the other
return (random.nextDouble() < 0.5)
? separateVoxels(voxelsA, voxelsB, random)
: separateVoxels(voxelsB, voxelsA, random);
Voxel splitpoint, Direction direction,
boolean shouldBalance, double splitProbability) {
// Initialize lists of split voxels
ArrayList<Voxel> voxelsA = new ArrayList<>();
ArrayList<Voxel> voxelsB = new ArrayList<>();
// Perform the split along the specified direction
if (direction == null) {
direction = getDirection(random);
}
splitVoxels(direction, voxels, voxelsA, voxelsB, splitpoint, random);
// Only balance if 'shouldBalance' is true
if (shouldBalance) {
connectVoxels(voxelsA, voxelsB, this, random);
balanceVoxels(voxelsA, voxelsB, this, random);
}
// Use the user-specified or default probability to determine the split
return (random.nextDouble() < splitProbability)
? separateVoxels(voxelsA, voxelsB, random)
: separateVoxels(voxelsB, voxelsA, random);
}

/**
Expand All @@ -381,7 +401,7 @@ public Voxel getCenter() {

return new Voxel(x, y, z);
}

/**
* Gets the center voxel where location will split if no offset percents specified.
* <p>
Expand All @@ -394,7 +414,7 @@ public Voxel getCenter() {
public Voxel getSplitpoint() {
return getCenter();
}

/**
* Calculates and returns the voxel at specified percentage offset from
* the boundaries of the location.
Expand Down
14 changes: 8 additions & 6 deletions test/arcade/potts/env/location/PottsLocationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1315,10 +1315,11 @@ public void split_noOffsets_callsPerformSplit() {
any(MersenneTwisterFast.class),
any(Voxel.class),
any(Direction.class),
anyBoolean()
anyBoolean(),
anyDouble()
); spy.split(randomDoubleZero);
verify(spy).getSplitpoint();
verify(spy).performSplit(eq(randomDoubleZero), Mockito.any(Voxel.class), eq(null), eq(true));
verify(spy).performSplit(eq(randomDoubleZero), Mockito.any(Voxel.class), eq(null), eq(true), eq(0.5));
}

@Test
Expand All @@ -1331,18 +1332,19 @@ public void split_withOffsets_callsPerformSplit() {
any(MersenneTwisterFast.class),
any(Voxel.class),
any(Direction.class),
anyBoolean()
anyBoolean(),
anyDouble()
);
spy.split(randomDoubleZero, offsets);
verify(spy).getSplitpoint(offsets);
verify(spy).performSplit(eq(randomDoubleZero), Mockito.any(Voxel.class), eq(null), eq(false)); }
verify(spy).performSplit(eq(randomDoubleZero), Mockito.any(Voxel.class), eq(null), eq(false), eq(0.5)); }

@Test
public void performSplit_noOffsets_splitsVoxelsCorrectly() {
PottsLocation location = new PottsLocationMock(voxelListAB);
MersenneTwisterFast random = new MersenneTwisterFast(12345);
Voxel splitpoint = location.getSplitpoint();
PottsLocation splitLocation = (PottsLocation) location.performSplit(random, splitpoint, null, true);
PottsLocation splitLocation = (PottsLocation) location.performSplit(random, splitpoint, null, true, .5);
assertNotNull(splitLocation);
assertTrue(location.voxels.size() > 0);
assertTrue(splitLocation.voxels.size() > 0);
Expand All @@ -1360,7 +1362,7 @@ public void performSplit_withOffsets_splitsVoxelsCorrectly() {
location.add(4, 4, 4);
ArrayList<Integer> offsets = new ArrayList<>(Arrays.asList(33, 33, 33)); // 33% offsets
Voxel splitpoint = location.getSplitpoint(offsets);
PottsLocation splitLocation = (PottsLocation) location.performSplit(random, splitpoint, null, false);
PottsLocation splitLocation = (PottsLocation) location.performSplit(random, splitpoint, null, false, .5);
assertNotNull(splitLocation);
assertTrue(location.voxels.size() > 0);
assertTrue(splitLocation.voxels.size() > 0);
Expand Down

0 comments on commit cae8cb1

Please sign in to comment.