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

com.github.rinde.rinsim.examples.experiment.ExperimentExample Maven / Gradle / Ivy

/*
 * Copyright (C) 2011-2017 Rinde van Lon, imec-DistriNet, KU Leuven
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.rinde.rinsim.examples.experiment;

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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.github.rinde.rinsim.core.SimulatorAPI;
import com.github.rinde.rinsim.core.model.pdp.DefaultPDPModel;
import com.github.rinde.rinsim.core.model.pdp.Parcel;
import com.github.rinde.rinsim.core.model.pdp.TimeWindowPolicy.TimeWindowPolicies;
import com.github.rinde.rinsim.core.model.pdp.VehicleDTO;
import com.github.rinde.rinsim.core.model.road.RoadModelBuilders;
import com.github.rinde.rinsim.experiment.Experiment;
import com.github.rinde.rinsim.experiment.Experiment.SimulationResult;
import com.github.rinde.rinsim.experiment.ExperimentResults;
import com.github.rinde.rinsim.experiment.MASConfiguration;
import com.github.rinde.rinsim.geom.Point;
import com.github.rinde.rinsim.pdptw.common.AddDepotEvent;
import com.github.rinde.rinsim.pdptw.common.AddParcelEvent;
import com.github.rinde.rinsim.pdptw.common.AddVehicleEvent;
import com.github.rinde.rinsim.pdptw.common.StatsStopConditions;
import com.github.rinde.rinsim.pdptw.common.TimeLinePanel;
import com.github.rinde.rinsim.scenario.Scenario;
import com.github.rinde.rinsim.scenario.StopConditions;
import com.github.rinde.rinsim.scenario.TimeOutEvent;
import com.github.rinde.rinsim.scenario.TimedEventHandler;
import com.github.rinde.rinsim.ui.View;
import com.github.rinde.rinsim.ui.renderers.PDPModelRenderer;
import com.github.rinde.rinsim.ui.renderers.PlaneRoadModelRenderer;
import com.github.rinde.rinsim.util.TimeWindow;
import com.google.common.base.Optional;

/**
 * This example shows how to use the {@link Experiment} class to define and run
 * an experiment. It shows how to construct a {@link Scenario} and
 * {@link MASConfiguration} which are both requirements for an example. The
 * intermediate steps in the example are documented, however, make sure to also
 * read the documentation of each method for extra information about what it
 * does.
 * 

* If this class is run on MacOS it might be necessary to use * -XstartOnFirstThread as a VM argument. * @author Rinde van Lon */ public final class ExperimentExample { // some constants used in the experiment private static final Point RESOLUTION = new Point(800, 700); private static final double VEHICLE_SPEED_KMH = 30d; private static final double MAX_VEHICLE_SPEED_KMH = 50d; private static final Point MIN_POINT = new Point(0, 0); private static final Point MAX_POINT = new Point(8, 4); private static final Point DEPOT_LOC = new Point(5, 2); private static final Point P1_PICKUP = new Point(1, 2); private static final Point P1_DELIVERY = new Point(4, 2); private static final Point P2_PICKUP = new Point(1, 1); private static final Point P2_DELIVERY = new Point(4, 1); private static final Point P3_PICKUP = new Point(1, 3); private static final Point P3_DELIVERY = new Point(4, 3); private static final long M1 = 60 * 1000L; private static final long M4 = 4 * 60 * 1000L; private static final long M5 = 5 * 60 * 1000L; private static final long M7 = 7 * 60 * 1000L; private static final long M10 = 10 * 60 * 1000L; private static final long M12 = 12 * 60 * 1000L; private static final long M13 = 13 * 60 * 1000L; private static final long M18 = 18 * 60 * 1000L; private static final long M20 = 20 * 60 * 1000L; private static final long M25 = 25 * 60 * 1000L; private static final long M30 = 30 * 60 * 1000L; private static final long M40 = 40 * 60 * 1000L; private static final long M60 = 60 * 60 * 1000L; private ExperimentExample() {} /** * It is possible to use the application arguments directly for configuring * the experiment. The '-h' or '--help' argument will show the list of * options. * @param args The arguments supplied to the application. */ public static void main(String[] args) { int uiSpeedUp = 1; final int index = Arrays.binarySearch(args, "speedup"); String[] arguments = args; if (index >= 0) { checkArgument(arguments.length > index + 1, "speedup option requires an integer indicating the speedup."); uiSpeedUp = Integer.parseInt(arguments[index + 1]); checkArgument(uiSpeedUp > 0, "speedup must be a positive integer."); final List list = new ArrayList<>(Arrays.asList(arguments)); list.remove(index + 1); list.remove(index); arguments = list.toArray(new String[] {}); } final Optional results; // Starts the experiment builder. results = Experiment.builder() // Adds a configuration to the experiment. A configuration configures an // algorithm that is supposed to handle or 'solve' a problem specified by // a scenario. A configuration can handle a scenario if it contains an // event handler for all events that occur in the scenario. The scenario // in this example contains four different events and registers an event // handler for each of them. .addConfiguration(MASConfiguration.builder() .addEventHandler(AddDepotEvent.class, AddDepotEvent.defaultHandler()) .addEventHandler(AddParcelEvent.class, AddParcelEvent.defaultHandler()) // There is no default handle for vehicle events, here a non functioning // handler is added, it can be changed to add a custom vehicle to the // simulator. .addEventHandler(AddVehicleEvent.class, CustomVehicleHandler.INSTANCE) .addEventHandler(TimeOutEvent.class, TimeOutEvent.ignoreHandler()) // Note: if you multi-agent system requires the aid of a model (e.g. // CommModel) it can be added directly in the configuration. Models that // are only used for the solution side should not be added in the // scenario as they are not part of the problem. .build()) // Adds the newly constructed scenario to the experiment. Every // configuration will be run on every scenario. .addScenario(createScenario()) // The number of repetitions for each simulation. Each repetition will // have a unique random seed that is given to the simulator. .repeat(2) // The master random seed from which all random seeds for the // simulations will be drawn. .withRandomSeed(0) // The number of threads the experiment will use, this allows to run // several simulations in parallel. Note that when the GUI is used the // number of threads must be set to 1. .withThreads(1) // We add a post processor to the experiment. A post processor can read // the state of the simulator after it has finished. It can be used to // gather simulation results. The objects created by the post processor // end up in the ExperimentResults object that is returned by the // perform(..) method of Experiment. .usePostProcessor(new ExamplePostProcessor()) // Adds the GUI just like it is added to a Simulator object. .showGui(View.builder() .with(PlaneRoadModelRenderer.builder()) .with(PDPModelRenderer.builder()) .with(TimeLinePanel.builder()) .withResolution((int) RESOLUTION.x, (int) RESOLUTION.y) .withAutoPlay() .withAutoClose() // For testing we allow to change the speed up via the args. .withSpeedUp(uiSpeedUp) .withTitleAppendix("Experiments example")) // Starts the experiment, but first reads the command-line arguments // that are specified for this application. By supplying the '-h' option // you can see an overview of the supported options. .perform(System.out, arguments); if (results.isPresent()) { for (final SimulationResult sr : results.get().getResults()) { // The SimulationResult contains all information about a specific // simulation, the result object is the object created by the post // processor, a String in this case. System.out.println( sr.getSimArgs().getRandomSeed() + " " + sr.getResultObject()); } } else { throw new IllegalStateException("Experiment did not complete."); } } /** * Defines a simple scenario with one depot, one vehicle and three parcels. * Note that a scenario is supposed to only contain problem specific * information it should (generally) not make any assumptions about the * algorithm(s) that are used to solve the problem. * @return A newly constructed scenario. */ static Scenario createScenario() { // In essence a scenario is just a list of events. The events must implement // the TimedEvent interface. You are free to construct any object as a // TimedEvent but keep in mind that implementations should be immutable. return Scenario.builder() // Adds one depot. .addEvent(AddDepotEvent.create(-1, DEPOT_LOC)) // Adds one vehicle. .addEvent(AddVehicleEvent.create(-1, VehicleDTO.builder() .speed(VEHICLE_SPEED_KMH) .build())) // Three add parcel events are added. They are announced at different // times and have different time windows. .addEvent( AddParcelEvent.create(Parcel.builder(P1_PICKUP, P1_DELIVERY) .neededCapacity(0) .orderAnnounceTime(M1) .pickupTimeWindow(TimeWindow.create(M1, M20)) .deliveryTimeWindow(TimeWindow.create(M4, M30)) .buildDTO())) .addEvent( AddParcelEvent.create(Parcel.builder(P2_PICKUP, P2_DELIVERY) .neededCapacity(0) .orderAnnounceTime(M5) .pickupTimeWindow(TimeWindow.create(M10, M25)) .deliveryTimeWindow( TimeWindow.create(M20, M40)) .buildDTO())) .addEvent( AddParcelEvent.create(Parcel.builder(P3_PICKUP, P3_DELIVERY) .neededCapacity(0) .orderAnnounceTime(M7) .pickupTimeWindow(TimeWindow.create(M12, M18)) .deliveryTimeWindow( TimeWindow.create(M13, M60)) .buildDTO())) // Signals the end of the scenario. Note that it is possible to stop the // simulation before or after this event is dispatched, that depends on // the stop condition (see below). .addEvent(TimeOutEvent.create(M60)) .scenarioLength(M60) // Adds a plane road model as this is part of the problem .addModel(RoadModelBuilders.plane() .withMinPoint(MIN_POINT) .withMaxPoint(MAX_POINT) .withMaxSpeed(MAX_VEHICLE_SPEED_KMH)) // Adds the pdp model .addModel( DefaultPDPModel.builder() .withTimeWindowPolicy(TimeWindowPolicies.TARDY_ALLOWED)) // The stop condition indicates when the simulator should stop the // simulation. Typically this is the moment when all tasks are performed. // Custom stop conditions can be created by implementing the StopCondition // interface. .setStopCondition(StopConditions.or( StatsStopConditions.timeOutEvent(), StatsStopConditions.vehiclesDoneAndBackAtDepot())) .build(); } enum CustomVehicleHandler implements TimedEventHandler { INSTANCE { @Override public void handleTimedEvent(AddVehicleEvent event, SimulatorAPI sim) { // add you own vehicle to the simulator here } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy