package com.plectix.simulator.simulationclasses.probability;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import com.plectix.simulator.simulationclasses.probability.WeightedItemWithId.WeightFunction;
import com.plectix.simulator.simulator.ThreadLocalData;
public class TestWeightedItemSelector {
int numberOfWeightedItems = 100;
int numberOfUpdates = 100;
int numberOfSelection = 1000000;
private static final double DEVIATION_GRAPH = 0.01;
private static final int FREQUENCY_REMOVED1 = 5;
private static final int FREQUENCY_REMOVED2 = 3;
List<WeightedItemWithId> weightedItemList = new ArrayList<WeightedItemWithId>();
// List<Integer> counts = new ArrayList<Integer>();
SkipListSelector<WeightedItemWithId> weightedItemSelector;
@Before
public void setUp() throws Exception {
weightedItemSelector = new SkipListSelector<WeightedItemWithId>();
for (int i = 0; i < numberOfWeightedItems; i++) {
weightedItemList.add(new WeightedItemWithId(i,
numberOfWeightedItems, WeightFunction.LINEAR));
}
shuffleAndUpdate();
}
@Test
public void testRandom() {
processSelection();
if (!equiprobability())
fail("Bad Randomize or very small operation factors!");
}
@Test
public void testRemoveRecalculationAndRandom() {
assignOtherWeight();
removeSomeItems(FREQUENCY_REMOVED1);
resetCounts();
shuffleAndUpdate();
processSelection();
if (!equiprobability())
fail("Bad Recalculation");
}
private void removeSomeItems(int k) {
for (int i = 0; i < numberOfWeightedItems; i++) {
WeightedItemWithId item = weightedItemList.get(i);
if (item.getId() % k == 0) {
item.remove();
}
}
}
private void resetCounts() {
for (int i = 0; i < numberOfWeightedItems; i++) {
weightedItemList.get(i).resetCount();
}
}
private void assignOtherWeight() {
for (int i = 0; i < numberOfWeightedItems; i++) {
WeightedItemWithId item = weightedItemList.get(i);
if (item.getId() % 5 == 0)
item.setWeightFunction(WeightFunction.LOGARITHM);
if (item.getId() % 7 == 1)
item.setWeightFunction(WeightFunction.PARABOLA);
}
}
private void shuffleAndUpdate() {
for (int i = 0; i < numberOfUpdates; i++) {
// Collections.shuffle(weightedItemList);
weightedItemSelector.updatedItems(weightedItemList);
}
}
private void processSelection() {
for (int i = 0; i < numberOfSelection; i++) {
WeightedItemWithId item = weightedItemSelector.select();
item.incrementCount();
}
}
private boolean equiprobability() {
double min = -1;
double max = -1;
for (int i = 0; i < numberOfWeightedItems; i++) {
if (weightedItemList.get(i).getWeight() != 0) {
if (weightedItemList.get(i).getCount()
/ weightedItemList.get(i).getWeight() > max
|| max == -1) {
max = weightedItemList.get(i).getCount()
/ weightedItemList.get(i).getWeight();
} else {
if (weightedItemList.get(i).getCount()
/ weightedItemList.get(i).getWeight() < min
|| min == -1)
min = weightedItemList.get(i).getCount()
/ weightedItemList.get(i).getWeight();
}
}
}
if (max == -1 || min == -1)
fail("List is empty!");
return testDeviationGraph(max - min);
}
// test deviation between graphs 1)expected and 2)empirical distribution
private boolean testDeviationGraph(double p) {
return Math.abs(p) < DEVIATION_GRAPH * numberOfSelection
/ numberOfWeightedItems;
}
// we can delete this class and leave only this method
@Test
public void testSelectorCompare() throws Exception {
TestSelector testSelector = new TestSelector();
ThreadLocalData.getRandom().setSeed(0);
weightedItemSelector = new SkipListSelector<WeightedItemWithId>();
testSelector.setUp(weightedItemSelector, numberOfWeightedItems,
numberOfUpdates, numberOfSelection, WeightFunction.LINEAR);
if (!testSelector.testRandom()) {
System.out.println("Bad Randomize or very small operation factors! It must very rarely occurence");
System.out.println("see permitRandom in TestSelector if works different from time to time");
}
if (!testSelector.testRemoveRecalculationAndRandom(FREQUENCY_REMOVED1)) {
fail("Bad Recalculation and Random after remove and set logariphm ");
}
if (!testSelector.testRemoveAssigneSineAndRandom(FREQUENCY_REMOVED2)) {
fail("Bad Recalculation and Random after remove and set Sine and Parabola ");
}
if(!testSelector.boundaryTest()){
fail("Boundary test failed ");
}
}
}