All Downloads are FREE. Search and download functionalities are using the official Maven repository.

rinde.sim.pdptw.generator.loc.NormalLocationsGenerator Maven / Gradle / Ivy

The newest version!
package rinde.sim.pdptw.generator.loc;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;

import java.math.RoundingMode;

import org.apache.commons.math3.distribution.NormalDistribution;
import org.apache.commons.math3.random.RandomGenerator;

import rinde.sim.core.graph.Point;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.math.DoubleMath;

public class NormalLocationsGenerator implements LocationsGenerator {

  private final double size;
  private final double bin;
  private final double std;
  private final ImmutableSortedSet probabilities;
  private final ImmutableList probabilitiesList;

  /**
   * @param envSize The size of the environment (in km), the area is defined as
   *          size^2 km2.
   * @param relativeStd This is the size of the standard deviation relative to
   *          envSize.
   * @param binSize Determines the size (in km) of the bins that will be used to
   *          discretize the Normal distribution.
   */
  public NormalLocationsGenerator(double envSize, double relativeStd,
      double binSize) {
    checkArgument(envSize >= 0.15);
    checkArgument(envSize >= 0);
    checkArgument(relativeStd >= 0);
    checkArgument(binSize >= 0);
    size = envSize;
    std = relativeStd;
    bin = binSize;

    // generate discrete approximation of Normal distribution
    final NormalDistribution nd = new NormalDistribution(size / 2d, size * std);
    final int numBins = DoubleMath
        .roundToInt(envSize / binSize, RoundingMode.UP);
    final ImmutableSortedSet.Builder b = ImmutableSortedSet
        .naturalOrder();
    b.add(0d);
    for (int i = 1; i < numBins; i++) {
      b.add(nd.cumulativeProbability(i * binSize));
    }
    b.add(1d);
    probabilities = b.build();
    probabilitiesList = probabilities.asList();
  }

  /**
   * @param numOrders The number of orders for which locations need to be
   *          generated. Note that for each order two locations are generated:
   *          the pickup location and the delivery location.
   */
  @Override
  public ImmutableList generate(int numOrders, RandomGenerator rng) {
    final ImmutableList.Builder b = ImmutableList.builder();
    for (int i = 0; i < numOrders * 2; i++) {
      final double x = sample(rng);
      final double y = sample(rng);
      checkState(x >= 0 && x < size, "Invalid x value %s, %s", i, x);
      checkState(y >= 0 && y < size, "Invalid y value %s, %s", i, y);
      b.add(new Point(x, y));
    }
    return b.build();
  }

  public double[][] getHistogram() {
    final int numProbs = probabilities.size();
    final double[][] histogram = new double[numProbs][2];

    for (int i = 0; i < numProbs; i++) {
      histogram[i][0] = i * bin;
      if (i == numProbs - 1) {
        histogram[i][1] = (1d - probabilitiesList.get(i)) * (1 / bin);
      } else {
        histogram[i][1] = (probabilitiesList.get(i + 1) - probabilitiesList
            .get(i)) * (1 / bin);
      }
    }
    return histogram;
  }

  public double getEnvSize() {
    return size;
  }

  public double getBinSize() {
    return bin;
  }

  public double getRelativeStd() {
    return std;
  }

  private double sample(RandomGenerator rng) {
    final int index = probabilitiesList.indexOf(probabilities.floor(rng
        .nextDouble()));
    final double lb = index * bin;
    return lb + rng.nextDouble() * bin;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy