/** Build the weight table, parallelized according to the number of processors */
  public void buildTable() {
    ArrayList<TransitStop> stopVertices;

    LOG.debug("Number of vertices: " + g.getVertices().size());
    stopVertices = new ArrayList<TransitStop>();
    for (Vertex gv : g.getVertices())
      if (gv instanceof TransitStop) stopVertices.add((TransitStop) gv);
    int nStops = stopVertices.size();

    stopIndices = new IdentityHashMap<Vertex, Integer>(nStops);
    for (int i = 0; i < nStops; i++) stopIndices.put(stopVertices.get(i), i);
    LOG.debug("Number of stops: " + nStops);

    table = new float[nStops][nStops];
    for (float[] row : table) Arrays.fill(row, Float.POSITIVE_INFINITY);

    LOG.debug("Performing search at each transit stop.");

    int nThreads = Runtime.getRuntime().availableProcessors();
    LOG.debug("number of threads: " + nThreads);
    ArrayBlockingQueue<Runnable> taskQueue = new ArrayBlockingQueue<Runnable>(nStops);
    ThreadPoolExecutor threadPool =
        new ThreadPoolExecutor(nThreads, nThreads, 10, TimeUnit.SECONDS, taskQueue);
    GenericObjectPool heapPool =
        new GenericObjectPool(new PoolableBinHeapFactory<State>(g.getVertices().size()), nThreads);

    // make one heap and recycle it
    TraverseOptions options = new TraverseOptions();
    options.speed = maxWalkSpeed;
    final double MAX_WEIGHT = 60 * 60 * options.walkReluctance;
    final double OPTIMISTIC_BOARD_COST = options.boardCost;

    // create a task for each transit stop in the graph
    ArrayList<Callable<Void>> tasks = new ArrayList<Callable<Void>>();
    for (TransitStop origin : stopVertices) {
      SPTComputer task =
          new SPTComputer(heapPool, options, MAX_WEIGHT, OPTIMISTIC_BOARD_COST, origin);
      tasks.add(task);
    }
    try {
      // invoke all of tasks.
      threadPool.invokeAll(tasks);
      threadPool.shutdown();
    } catch (InterruptedException e) {
      throw new RuntimeException(e);
    }
    floyd();
  }
예제 #2
0
  public void testTriangle() {
    Coordinate c1 = new Coordinate(-122.575033, 45.456773);
    Coordinate c2 = new Coordinate(-122.576668, 45.451426);

    Vertex v1 = new Vertex("v1", c1, null);
    Vertex v2 = new Vertex("v2", c2, null);

    GeometryFactory factory = new GeometryFactory();
    LineString geometry = factory.createLineString(new Coordinate[] {c1, c2});

    double length = 650.0;

    PlainStreetEdge testStreet =
        new PlainStreetEdge(
            v1, v2, geometry, "Test Lane", length, StreetTraversalPermission.ALL, false);
    testStreet.setBicycleSafetyEffectiveLength(length * 0.74); // a safe street

    Coordinate[] profile =
        new Coordinate[] {
          new Coordinate(0, 0), // slope = 0.1
          new Coordinate(length / 2, length / 20.0),
          new Coordinate(length, 0) // slope = -0.1
        };
    PackedCoordinateSequence elev = new PackedCoordinateSequence.Double(profile);
    testStreet.setElevationProfile(elev);

    double trueLength = ElevationUtils.getLengthMultiplierFromElevation(elev) * length;
    testStreet.setSlopeSpeedEffectiveLength(trueLength); // normalize length

    SlopeCosts costs = ElevationUtils.getSlopeCosts(elev, "test");

    TraverseOptions options = new TraverseOptions(TraverseMode.BICYCLE);
    options.optimizeFor = OptimizeType.TRIANGLE;
    options.speed = 6.0;
    options.walkReluctance = 1;

    options.setTriangleSafetyFactor(0);
    options.setTriangleSlopeFactor(0);
    options.setTriangleTimeFactor(1);
    State startState = new State(v1, options);

    State result = testStreet.traverse(startState);
    double timeWeight = result.getWeight();
    double expectedSpeedWeight = trueLength / options.speed;
    assertEquals(expectedSpeedWeight, timeWeight);

    options.setTriangleSafetyFactor(0);
    options.setTriangleSlopeFactor(1);
    options.setTriangleTimeFactor(0);
    startState = new State(v1, options);
    result = testStreet.traverse(startState);
    double slopeWeight = result.getWeight();
    assertTrue(length * 1.5 / options.speed < slopeWeight);
    assertTrue(length * 1.5 * 10 / options.speed > slopeWeight);

    options.setTriangleSafetyFactor(1);
    options.setTriangleSlopeFactor(0);
    options.setTriangleTimeFactor(0);
    startState = new State(v1, options);
    result = testStreet.traverse(startState);
    double safetyWeight = result.getWeight();
    double slopeSafety = costs.slopeSafetyCost;
    double expectedSafetyWeight = (trueLength * 0.74 + slopeSafety) / options.speed;
    assertTrue(expectedSafetyWeight - safetyWeight < 0.00001);

    final double ONE_THIRD = 1 / 3.0;
    options.setTriangleSafetyFactor(ONE_THIRD);
    options.setTriangleSlopeFactor(ONE_THIRD);
    options.setTriangleTimeFactor(ONE_THIRD);
    startState = new State(v1, options);
    result = testStreet.traverse(startState);
    double averageWeight = result.getWeight();
    assertTrue(
        Math.abs(
                safetyWeight * ONE_THIRD
                    + slopeWeight * ONE_THIRD
                    + timeWeight * ONE_THIRD
                    - averageWeight)
            < 0.00000001);
  }