Exemplo n.º 1
0
  @Override
  protected void initFlow(HierarchicalConfiguration flowCfg) {
    // int node = flowCfg.getInt("[@node]");

    int inLink = flowCfg.getInt("[@inLink]", -1);
    int outLink = flowCfg.getInt("[@outLink]", -1);

    // int next = flowCfg.getInt("[@next]");
    int no = flowCfg.getInt("[@no]", 0);

    Node node;
    Node next;

    if (inLink != -1) {
      Link link = idToLinkMap.get(Id.create(inLink, Link.class));

      node = link.getFromNode();
      next = link.getToNode();
    } else {
      Link link = idToLinkMap.get(Id.create(outLink, Link.class));

      node = link.getToNode();
      next = link.getFromNode();
    }

    int nodeId = Integer.parseInt(node.getId().toString());
    int nextId = Integer.parseInt(next.getId().toString());

    flows[nodeId] = new MATSimFlow(nodeId, inLink, outLink, nextId, no);
  }
Exemplo n.º 2
0
 @Override
 public int compare(final Node n1, final Node n2) {
   double c1 = getCost(n1);
   double c2 = getCost(n2);
   if (c1 < c2) return -1;
   if (c1 > c2) return +1;
   return n1.getId().compareTo(n2.getId());
 }
 /**
  * Returns the data for the given node. Creates a new NodeData if none exists yet.
  *
  * @param n The Node for which to return the data.
  * @return The data for the given Node
  */
 protected DijkstraNodeData getData(final Node n) {
   DijkstraNodeData r = this.nodeData.get(n.getId());
   if (null == r) {
     r = new DijkstraNodeData();
     this.nodeData.put(n.getId(), r);
   }
   return r;
 }
Exemplo n.º 4
0
 public void addLinkNetwork(Node fromNode, Node toNode) {
   Id<Link> linkId = Id.create(network.getLinks().size() * 2, Link.class);
   network.addLink(network.getFactory().createLink(linkId, fromNode, toNode));
   try {
     PrintWriter writer =
         new PrintWriter(new FileWriter(RoutesPathsGenerator.NEW_NETWORK_LINKS_FILE, true));
     writer.println(linkId);
     writer.println(fromNode.getId());
     writer.println(toNode.getId());
     writer.close();
   } catch (IOException e) {
     e.printStackTrace();
   }
 }
Exemplo n.º 5
0
    @Override
    public int compare(final Node n1, final Node n2) {

      double c1 =
          ((LandmarksData) this.roleData.get(n1)).getFromLandmarkTravelTime(this.landmarkIndex);
      double c2 =
          ((LandmarksData) this.roleData.get(n2)).getFromLandmarkTravelTime(this.landmarkIndex);

      if (c1 < c2) {
        return -1;
      }
      if (c1 > c2) {
        return +1;
      }
      return n1.getId().compareTo(n2.getId());
    }
  /**
   * writing the accessibility measures into csv file.
   *
   * <p>Design thoughs:
   *
   * <ul>
   *   <li>yyyy I am not sure why it is meaningful to use zones or nodes for the coordinates.
   *       Accessibility refers directly to coordinates, and maybe directly to zones (if averaged).
   *       --> remove eventually. kai, jul'13
   *       <ul>
   */
  @Override
  public void setZoneAccessibilities(
      ActivityFacility startZone, Node node, Map<Modes4Accessibility, Double> accessibilities) {
    // (this is what, I think, writes the urbansim data, and should thus better not be touched. kai,
    // feb'14)

    try {
      assert (accessibilityDataWriter != null);
      accessibilityDataWriter.write(
          startZone.getId().toString()
              + ","
              + startZone.getCoord().getX()
              + ","
              + startZone.getCoord().getY()
              + ","
              + node.getId()
              + ","
              + node.getCoord().getX()
              + ","
              + node.getCoord().getY());
      for (Modes4Accessibility mode : Modes4Accessibility.values()) {
        accessibilityDataWriter.write("," + accessibilities.get(mode));
      }
      accessibilityDataWriter.newLine();
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(-1);
    }
  }
Exemplo n.º 7
0
  @Override
  public void run(final Network network) {
    super.run(network);

    log.info("Putting landmarks on network...");
    long now = System.currentTimeMillis();
    landmarks = landmarker.identifyLandmarks(landmarkCount, network);
    log.info("done in " + (System.currentTimeMillis() - now) + " ms");

    log.info("Initializing landmarks data");
    for (Node node : network.getNodes().values()) {
      this.nodeData.put(node, new LandmarksData(this.landmarkCount));
    }

    int nOfThreads = this.numberOfThreads;
    if (nOfThreads > this.landmarks.length) {
      nOfThreads = this.landmarks.length;
    }
    if (nOfThreads < 2) {
      nOfThreads = 2; // always use at least two threads
    }
    log.info(
        "Calculating distance from each node to each of the "
            + this.landmarkCount
            + " landmarks using "
            + nOfThreads
            + " threads...");
    now = System.currentTimeMillis();

    ExecutorService executor = Executors.newFixedThreadPool(nOfThreads);
    for (int i = 0; i < this.landmarks.length; i++) {
      executor.execute(new Calculator(i, this.landmarks[i], this.nodeData, this.costFunction));
    }
    executor.shutdown();
    while (!executor.isTerminated()) {
      log.info("wait for landmarks Calculator to finish...");
      try {
        executor.awaitTermination(10, TimeUnit.MINUTES);
      } catch (InterruptedException e) {
        throw new RuntimeException(e);
      }
    }

    for (Node node : network.getNodes().values()) {
      LandmarksData r = getNodeData(node);
      r.updateMinMaxTravelTimes();
    }

    for (Node node : network.getNodes().values()) {
      LandmarksData r = getNodeData(node);
      for (int i = 0; i < this.landmarks.length; i++) {
        if (r.getMinLandmarkTravelTime(i) > r.getMaxLandmarkTravelTime(i)) {
          log.info("Min > max for node " + node.getId() + " and landmark " + i);
        }
      }
    }

    log.info("done in " + (System.currentTimeMillis() - now) + " ms");
  }
Exemplo n.º 8
0
  public static void main(String[] args) {
    MutableScenario scenario =
        (MutableScenario) ScenarioUtils.createScenario(ConfigUtils.createConfig());
    MatsimNetworkReader networkReader = new MatsimNetworkReader(scenario.getNetwork());
    networkReader.readFile(args[0]);

    int numberOfLinks = 0;
    double length = 0.0;
    double length1 = 0.0;
    double length2 = 0.0;
    double length3 = 0.0;
    Node previousNode1 = null;
    Node previousNode2 = null;
    for (Link l : scenario.getNetwork().getLinks().values()) {
      if (previousNode1 != null) {

        if (l.getFromNode().getId() != previousNode2.getId()
            && l.getToNode().getId() != previousNode1.getId()) {
          numberOfLinks++;
          length += l.getLength();
          if (l.getFreespeed() > 24.99) {
            length1 += l.getLength();
          } else if (l.getFreespeed() < 13.88) {
            length3 += l.getLength();

          } else length2 += l.getLength();
        }
      } else {
        numberOfLinks++;
        length += l.getLength();
        if (l.getFreespeed() > 24.99) {
          length1 += l.getLength();
        } else if (l.getFreespeed() < 13.88) {
          length3 += l.getLength();

        } else length2 += l.getLength();
      }
      previousNode1 = l.getFromNode();
      previousNode2 = l.getToNode();
    }
    System.out.println(numberOfLinks);
    System.out.println(length / 1000);
    System.out.println(length1 / 1000);
    System.out.println(length2 / 1000);
    System.out.println(length3 / 1000);
  }
Exemplo n.º 9
0
 public void add() {
   List<Link> links = ((BusLaneAdderPanel) layersPanels.get(PanelIds.ONE)).getLinks();
   Node prevNode = links.get(0).getFromNode();
   for (Link link : links)
     if (!link.getAllowedModes().contains("bus")) {
       exitSave();
       JOptionPane.showMessageDialog(this, "Wrong path, network saved");
     }
   for (int i = 0; i < links.size(); i++) {
     Link link = links.get(i);
     Node node = null;
     if (link.getNumberOfLanes() == 1) {
       Set<String> modes = new HashSet<String>();
       modes.add("bus");
       link.setAllowedModes(modes);
       node = link.getToNode();
     } else {
       Node oldNode = link.getToNode();
       if (i == links.size() - 1 || oldNode.getInLinks().size() + oldNode.getOutLinks().size() > 2)
         node = oldNode;
       else {
         node =
             network
                 .getFactory()
                 .createNode(
                     Id.createNodeId("fl" + oldNode.getId().toString()), oldNode.getCoord());
         network.addNode(node);
       }
       LinkImpl newLink =
           (LinkImpl)
               network
                   .getFactory()
                   .createLink(Id.createLinkId("fl" + link.getId().toString()), prevNode, node);
       Set<String> modes = new HashSet<String>();
       modes.add("car");
       newLink.setAllowedModes(modes);
       newLink.setCapacity(link.getCapacity());
       newLink.setFreespeed(link.getFreespeed());
       newLink.setLength(link.getLength());
       newLink.setNumberOfLanes(link.getNumberOfLanes() - 1);
       newLink.setOrigId(((LinkImpl) link).getOrigId());
       newLink.setType(((LinkImpl) link).getType());
       network.addLink(newLink);
       Set<String> modes2 = new HashSet<String>();
       modes2.add("bus");
       link.setAllowedModes(modes2);
       link.setCapacity(900);
       link.setNumberOfLanes(1);
     }
     prevNode = node;
   }
   ((BusLaneAdderPanel) layersPanels.get(PanelIds.ONE)).clearSelection();
 }
Exemplo n.º 10
0
 NodeClusteringAlgorithm(
     String algorithmName,
     Network network,
     String linkMethodName,
     String[] argTypes,
     Object[] args) {
   this.flowValues = new ArrayList<>();
   this.internalFlowMethodParameterTypes = argTypes;
   this.internalFlowMethod = getLinkGetMethodWithArgTypes(linkMethodName, argTypes);
   NodeCluster.linkMethod = internalFlowMethod;
   NodeCluster.args = args;
   this.internalFlowMethodParameters = args;
   if (argTypes != null || args != null)
     logger.info("Using args " + internalFlowMethodParameters.toString());
   logger = Logger.getLogger("NodeClusterer");
   this.network = network;
   links = new LinkedHashMap<>(network.getLinks().size());
   for (Link l : network.getLinks().values()) {
     links.put(l.getId(), new ClusterLink((Link) l));
   }
   setNodes(new LinkedHashMap<Id, ClusterNode>(network.getNodes().size()));
   leafNodeClusters = new TreeMap<>();
   int i = 0;
   for (Node n : network.getNodes().values()) {
     getNodes().put(n.getId(), new ClusterNode((Node) n));
     leafNodeClusters.put(
         i,
         new NodeCluster(
             getNodes().get(n.getId()),
             this,
             0,
             i,
             internalFlowMethod,
             internalFlowMethodParameters));
     i++;
   }
   this.pointersToClusterLevels = new TreeMap<>();
   this.pointersToClusterLevels.put(0, new ArrayList<>(leafNodeClusters.values()));
   this.setAlgorithmName(algorithmName);
 }
Exemplo n.º 11
0
  private void relaxNode(final Node n, PriorityQueue<Node> pendingNodes) {
    NodeData nData = nodeData.get(n.getId());
    double currTime = nData.getTime();
    double currCost = nData.getCost();
    for (Link l : n.getOutLinks().values()) {
      Node nn = l.getToNode();
      NodeData nnData = nodeData.get(nn.getId());
      if (nnData == null) {
        nnData = new NodeData();
        this.nodeData.put(nn.getId(), nnData);
      }
      double visitCost =
          currCost + tcFunction.getLinkTravelDisutility(l, currTime, PERSON, VEHICLE);
      double visitTime = currTime + ttFunction.getLinkTravelTime(l, currTime, PERSON, VEHICLE);

      if (visitCost < nnData.getCost()) {
        pendingNodes.remove(nn);
        nnData.visit(n.getId(), visitCost, visitTime);
        additionalComputationsHook(l, currTime);
        pendingNodes.add(nn);
      }
    }
  }
Exemplo n.º 12
0
  /*package*/ void addConnectorLinks() {

    QuadTree<Node> quadTree = getNodesQuadTree();
    NetworkFactory factory = network.getFactory();

    /*
     * Try to use the centroid of the polygon. If that does not lie within
     * the polygon, use an interior point.
     */
    for (Entry<Integer, SimpleFeature> entry : zonesMap.entrySet()) {
      int zoneId = entry.getKey();
      SimpleFeature zone = entry.getValue();

      if (SpecialZones.skipZone(zone)) continue;

      Geometry polygon = (Geometry) zone.getDefaultGeometry();
      Point point = polygon.getCentroid();
      if (!polygon.contains(point)) point = polygon.getInteriorPoint();

      /*
       * Convert coordinate from WGS84 to EPSG:28992 (Netherlands Projection)
       */
      Coord wgs84Coord = new Coord(point.getCoordinate().x, point.getCoordinate().y);
      Coord nodeCoord = ct.transform(wgs84Coord);

      Id<Node> nodeId = Id.create(String.valueOf(zoneId), Node.class);
      network.addNode(factory.createNode(nodeId, nodeCoord));

      Node networkConnectorNode = quadTree.getClosest(nodeCoord.getX(), nodeCoord.getY());
      Id<Node> networkConnectorNodeId = networkConnectorNode.getId();

      double length = CoordUtils.calcDistance(nodeCoord, networkConnectorNode.getCoord());

      Id<Link> linkFromId = Id.create(String.valueOf(zoneId) + "from", Link.class);
      Link fromLink = factory.createLink(linkFromId, nodeId, networkConnectorNodeId);
      fromLink.setLength(length);
      fromLink.setCapacity(this.connectorCapacity);
      fromLink.setFreespeed(this.connectorLinkFreeSpeed);
      network.addLink(fromLink);

      Id<Link> linkToId = Id.create(String.valueOf(zoneId) + "to", Link.class);
      Link toLink = factory.createLink(linkToId, networkConnectorNodeId, nodeId);
      toLink.setLength(length);
      toLink.setCapacity(this.connectorCapacity);
      toLink.setFreespeed(this.connectorLinkFreeSpeed);
      network.addLink(toLink);
    }
  }
Exemplo n.º 13
0
  public void calculate(final Network network, final Node origin, final double time) {
    this.origin1 = origin;
    this.dTime = time;

    this.nodeData = new HashMap<Id<Node>, NodeData>((int) (network.getNodes().size() * 1.1), 0.95f);
    NodeData d = new NodeData();
    d.time = time;
    d.cost = 0;
    this.nodeData.put(origin.getId(), d);

    ComparatorCost comparator = new ComparatorCost(this.nodeData);
    PriorityQueue<Node> pendingNodes = new PriorityQueue<Node>(500, comparator);
    relaxNode(origin, pendingNodes);
    while (!pendingNodes.isEmpty()) {
      Node n = pendingNodes.poll();
      relaxNode(n, pendingNodes);
    }
  }
Exemplo n.º 14
0
 public Node createNode(double x, double y) {
   Node node =
       network
           .getFactory()
           .createNode(Id.create("n" + network.getNodes().size(), Node.class), new Coord(x, y));
   network.addNode(node);
   try {
     PrintWriter writer =
         new PrintWriter(new FileWriter(RoutesPathsGenerator.NEW_NETWORK_NODES_FILE, true));
     writer.println(node.getId());
     writer.println(node.getCoord().getX());
     writer.println(node.getCoord().getY());
     writer.close();
   } catch (IOException e) {
     e.printStackTrace();
   }
   return node;
 }
Exemplo n.º 15
0
  private void initMappings(ZoneCollection zones, String zoneIdKey) {
    node2Zone = new ConcurrentHashMap<>();
    zone2Node = new ConcurrentHashMap<>();

    for (Node node : network.getNodes().values()) {
      Coordinate c = new Coordinate(node.getCoord().getX(), node.getCoord().getY());
      Zone zone = zones.get(c);
      if (zone != null) {
        String id = zone.getAttribute(zoneIdKey);
        node2Zone.put(node.getId(), id);

        Collection<Node> nodes = zone2Node.get(id);
        if (nodes == null) {
          nodes = new HashSet<>();
          zone2Node.put(id, nodes);
        }
        nodes.add(node);
      }
    }
  }
  public GeoPosition getNetworkCenter() {
    if (this.networkCenter != null) {
      return this.networkCenter;
    }
    Envelope e = new Envelope();
    for (Node node : this.sc.getNetwork().getNodes().values()) {

      // ignore end nodes
      if (node.getId().toString().contains("en")) continue;

      e.expandToInclude(MGC.coord2Coordinate(node.getCoord()));
    }
    Coord centerC = new CoordImpl((e.getMaxX() + e.getMinX()) / 2, (e.getMaxY() + e.getMinY()) / 2);
    CoordinateTransformation ct2 =
        new GeotoolsTransformation(this.sc.getConfig().global().getCoordinateSystem(), "EPSG:4326");
    centerC = ct2.transform(centerC);
    this.networkCenter = new GeoPosition(centerC.getY(), centerC.getX());

    return this.networkCenter;
  }
  private final void convertStations(OTTDataContainer dataContainer, Network infraNetwork) {
    TransitScheduleFactory factory = scenario.getTransitSchedule().getFactory();

    // get station ids
    Set<Id> stationIds = new HashSet<Id>();
    for (Locomotive locomotive : dataContainer.locomotives.values()) {
      for (StationData stationData : locomotive.trips.values()) {
        stationIds.add(stationData.stationId);
      }
    }

    for (Id stationId : stationIds) {
      Node node = infraNetwork.getNodes().get(stationId);
      if (node != null) {
        TransitStopFacility stopFacility =
            factory.createTransitStopFacility(stationId, node.getCoord(), false);
        stopFacility.setName(node.getId().toString());
        scenario.getTransitSchedule().addStopFacility(stopFacility);
      } else {
        throw new RuntimeException(
            "node id=" + stationId.toString() + " not found in the network. Bailing out.");
      }
    }
  }
Exemplo n.º 18
0
  // iterate over all nodes to find all external nodes
  private static final Set<Id<Node>> getExternalNodes(
      Scenario scenario, Map<Integer, SimpleFeature> zonalShapes) {

    Set<Id<Node>> externalNodes = new TreeSet<Id<Node>>();
    for (Node node : scenario.getNetwork().getNodes().values()) {
      Coord pointCoord = toWGS84CoordinateTransformation.transform(node.getCoord());
      Point point =
          geometryFactory.createPoint(new Coordinate(pointCoord.getX(), pointCoord.getY()));

      SimpleFeature pointZone = null;
      for (SimpleFeature zone : zonalShapes.values()) {
        Geometry polygon = (Geometry) zone.getDefaultGeometry();
        if (polygon.contains(point)) {
          pointZone = zone;
          break;
        }
      }

      // if the point is not contained in any Zone it is an external node.
      if (pointZone == null) externalNodes.add(node.getId());
    }

    return externalNodes;
  }
Exemplo n.º 19
0
 protected double getCost(final Node node) {
   return this.nodeData.get(node.getId()).getCost();
 }
Exemplo n.º 20
0
  /* (non-Javadoc)
   * @see org.matsim.core.api.internal.NetworkRunnable#run(org.matsim.api.core.v01.network.Network)
   */
  @Override
  public void run(Network network) {
    Queue<Node> pendingNodes = new LinkedList<Node>(network.getNodes().values());

    double[] env = NetworkUtils.getBoundingBox(pendingNodes);
    QuadTree<Node> quadTree = new QuadTree<Node>(env[0], env[1], env[2], env[3]);
    for (Node node : pendingNodes) {
      quadTree.put(node.getCoord().getX(), node.getCoord().getY(), node);
    }

    long linkIdCounter = 100000000000L;

    while (!pendingNodes.isEmpty()) {
      Node node = pendingNodes.poll();

      double radius = 30;

      double minx = node.getCoord().getX() - radius;
      double miny = node.getCoord().getY() - radius;
      double maxx = node.getCoord().getX() + radius;
      double maxy = node.getCoord().getY() + radius;

      Set<Node> intersectionNodes = new HashSet<Node>(20);
      quadTree.getRectangle(minx, miny, maxx, maxy, intersectionNodes);

      if (intersectionNodes.size() > 1) {
        Set<Node> sourceNodes = new HashSet<Node>();
        Map<Node, Set<Link>> inLinks = new HashMap<Node, Set<Link>>();
        Set<Node> targetNodes = new HashSet<Node>();
        Map<Node, Set<Link>> outLinks = new HashMap<Node, Set<Link>>();

        for (Node intersectionNode : intersectionNodes) {
          for (Link link : intersectionNode.getInLinks().values()) {
            Node fromNode = link.getFromNode();

            double x = fromNode.getCoord().getX();
            double y = fromNode.getCoord().getY();

            if (!(x > minx && y > miny && x < maxx && y < maxy)) {
              sourceNodes.add(fromNode);

              Set<Link> links = inLinks.get(fromNode);
              if (links == null) {
                links = new HashSet<Link>();
                inLinks.put(fromNode, links);
              }
              links.add(link);
            }
          }

          for (Link link : intersectionNode.getOutLinks().values()) {
            Node toNode = link.getToNode();

            double x = toNode.getCoord().getX();
            double y = toNode.getCoord().getY();

            if (!(x > minx && y > miny && x < maxx && y < maxy)) {
              targetNodes.add(toNode);

              Set<Link> links = outLinks.get(toNode);
              if (links == null) {
                links = new HashSet<Link>();
                outLinks.put(toNode, links);
              }
              links.add(link);
            }
          }
        }

        for (Node intersectionNode : intersectionNodes) {
          network.removeNode(intersectionNode.getId());
          quadTree.remove(
              intersectionNode.getCoord().getX(),
              intersectionNode.getCoord().getY(),
              intersectionNode);
          pendingNodes.remove(intersectionNode);
        }

        NetworkFactory factory = network.getFactory();

        Node centerNode = factory.createNode(node.getId(), centerOfMass(intersectionNodes));
        network.addNode(centerNode);
        quadTree.put(centerNode.getCoord().getX(), centerNode.getCoord().getY(), centerNode);

        for (Node source : sourceNodes) {
          Link newLink =
              factory.createLink(Id.create(linkIdCounter++, Link.class), source, centerNode);
          network.addLink(newLink);
          Set<Link> origLinks = inLinks.get(source);
          assignProps(origLinks, newLink);
        }

        for (Node target : targetNodes) {
          Link newLink =
              factory.createLink(Id.create(linkIdCounter++, Link.class), centerNode, target);
          network.addLink(newLink);
          Set<Link> origLinks = outLinks.get(target);
          assignProps(origLinks, newLink);
        }
      }
    }
  }
Exemplo n.º 21
0
  @Override
  public Path calcLeastCostPath(
      Node fromNode, Node toNode, double starttime, Person person, Vehicle vehicle) {

    List<Node> nodes = new ArrayList<>();
    List<Link> links = new ArrayList<>();
    double travelTime = starttime;
    double travelCost = 0;
    Node currentNode = fromNode;
    if (networkPainter != null) {
      networkPainter.addForegroundPixel(fromNode.getId());
      networkPainter.addForegroundPixel(toNode.getId());
    }
    while (currentNode != toNode) {
      Object[] outLinks = currentNode.getOutLinks().values().toArray();
      // come up witha set of costs based on how much nearer (eucl) the link brings you to your
      // destination,
      // use them as probabilities of selecting the link
      double[] cumulativeWeights = new double[outLinks.length];
      double[] weights = new double[outLinks.length];
      double[] dists = new double[outLinks.length];
      double minCost = Double.POSITIVE_INFINITY;
      double maxCost = 0;
      Link selection = null;
      for (int i = 0; i < outLinks.length; i++) {
        double linkCost =
            CoordUtils.calcEuclideanDistance(
                toNode.getCoord(), ((Link) outLinks[i]).getToNode().getCoord());
        if (((Link) outLinks[i])
            .getToNode()
            .equals(toNode)) { // found destination, stop mucking about
          selection = (Link) outLinks[i];
          break;
        }
        dists[i] = linkCost;
        minCost = Math.min(minCost, linkCost);
        maxCost = Math.max(maxCost, linkCost);
      }
      for (int i = 0; i < outLinks.length; i++) {
        double linkCost = dists[i] - minCost;
        if (links.contains(outLinks[i]) || nodes.contains(((Link) outLinks[i]).getToNode())) {
          linkCost = 1e6 * (maxCost - minCost);
        }
        linkCost = Math.exp(-beta * linkCost);
        linkCost = linkCost == 1 ? 2 : linkCost;
        cumulativeWeights[i] = i > 0 ? cumulativeWeights[i - 1] + linkCost : linkCost;
        weights[i] = linkCost;
      }
      if (selection == null) {
        // sample if the destination has not been found
        double sampleProb =
            MatsimRandom.getRandom().nextDouble() * cumulativeWeights[cumulativeWeights.length - 1];
        for (int i = 0; i < outLinks.length; i++) {
          if (cumulativeWeights[i] >= sampleProb) {
            selection = (Link) outLinks[i];
            links.add(selection);
            nodes.add(currentNode);
            travelCost +=
                travelCosts.getLinkTravelDisutility(selection, travelTime, person, vehicle);
            travelTime += travelTimes.getLinkTravelTime(selection, travelTime, person, vehicle);
            break;
          }
        }
      }
      if (networkPainter != null) {
        networkPainter.addForegroundLine(selection.getId());
        try {
          Thread.sleep(200);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
      currentNode = selection.getToNode();
    }
    if (networkPainter != null) {
      try {
        Thread.sleep(500);
        networkPainter.clearForeground();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    return new Path(nodes, links, travelTime, travelCost);
  }