Merged PR 8938: example restructuring

This commit is contained in:
David Coe 2020-05-18 18:32:57 +00:00 коммит произвёл Evan Kramer
Родитель bda36db12f
Коммит aaae287b51
78 изменённых файлов: 8813 добавлений и 7224 удалений

335
README.md
Просмотреть файл

@ -1,332 +1,9 @@
# Overview of the AnyLogic SDK for Bonsai
The AnyLogic SDK for Bonsai is an add-in to AnyLogic that allows users to connect their AnyLogic models to the Microsoft Bonsai platform.<url>
# Overview of the Bonsai Connector for AnyLogic
The Bonsai Connector is a library add-in to AnyLogic that allows users to connect their AnyLogic models to the Microsoft Bonsai platform.
# Including the SDK in Your Model
The AnyLogic SDK for Bonsai is an external JAR library that can be included. To add to an existing model, add the **com.anylogic.sdk3.connector-0.0.4.jar** file to your model project, as well as its dependencies:
After downloading the <a href="https://www.anylogic.com/features/artificial-intelligence/microsoft-bonsai/">wrapper</a> from AnyLogic, check out the <a href="wrapper/wrapper model workflow.docx">wrapper model workflow</a> document to learn more about incorporating it with your own model.
There are a number of examples packaged with the connector:
- activation-1.1.1.jar
- aopalliance-repackaged-2.5.0-b32.jar
- com.anylogic.sdk3.connector-0.0.4.jar
- hk2-api-2.5.0-b32.jar
- hk2-locator-2.5.0-b32.jar
- hk2-utils-2.5.0-b32.jar
- jackson-annotations-2.8.4.jar
- jackson-core-2.10.1.jar
- jackson-databind-2.8.4.jar
- jackson-jaxrs-base-2.8.4.jar
- jackson-jaxrs-json-provider-2.8.4.jar
- jackson-jr-objects-2.10.1.jar
- jackson-module-jaxb-annotations-2.8.4.jar
- javassist-3.20.0-GA.jar
- javax.annotation-api-1.2.jar
- javax.inject-2.5.0-b32.jar
- javax.ws.rs-api-2.0.1.jar
- jaxb-api-2.3.0.jar
- jaxb-core-2.3.0.jar
- jaxb-impl-2.3.0.jar
- jersey-client-2.25.1.jar
- jersey-common-2.25.1.jar
- jersey-entity-filtering-2.25.1.jar
- jersey-guava-2.25.1.jar
- jersey-media-json-jackson-2.25.1.jar
- json-20190722.jar
- osgi-resource-locator-1.0.1.jar
Each of these files are located in the <a href="./connector">connector</a> directory.
If you need help for how to add external classes to your model, please visit the <a href="https://help.anylogic.com/index.jsp?topic=%2Fcom.anylogic.help%2Fhtml%2Flibraries%2FAdding+External+Jar+Files+and+Java+Classes.html">Adding External Java Classes</a> section on the AnyLogic help page.
# Connecting Your Model to Bonsai
The AnyLogic SDK for Bonsai includes base functionality for communicating to the Micorsoft Bonsai service, and does not require the user to implement any special logic to do so. The core
The SDK has four core base classes that are used to implement connection to the Bonsai platform.
- ISimulator<Action,Config> interface
- Config class
- Observation class
- Action class
When your simulator connects to the Bonsai platform, it does so by:
1. Using the **ISimulator** interface to register your simulator with the Bonsai platform and receiving a session ID. After starting your simulator, click on the Train button in the Bonsai dashboard and select the name of your simulator to begin training.
2. Upon an *episode start* event, the SDK acquires an initial configuration from the Bonsai brain. This is used by a class derived from **Config** to set initial conditions for your model and map to the values in your Config type in inkling. You can learn more about configuring lessons in inkling [HERE].
3. At each *episode step* in your model the SDK sends the values derived from the **Observation** class. The values in your derived Observation class should match the name and types of variables found in the State type in your inkling for your Bonsai brain. When the brain receives the observation, it also evaluates the reward or terminal conditions associated with your inkling and determines the next best action.
4. During the *episode step* event, the SDK provides the values from a derived **Action** class. These values map to the Action type in your inkling for your Bonsai brain and represent the next step, or action, the brain would like your model to run.
5. If a terminal condition is hit in inkling, or your simulator reaches a halted state, the SDK will fire an *episode finish* event. This is a great place to stop your model and get it ready for a new run.
## The ISimulator<Action,Config> Interface
The ISimulator<Action,Config> interface is used to define the class that will be using to communicate between AnyLogic and the Bonsai platform. The interface requires the following methods to be implemented:
```java
// sends an observation to Bonsai as State
public Observation getObservable();
// fired when a new episode starts.
// Takes a class derived from the base Config class
public void episodeStart(Y config);
// fired when an episode step, or iteration, occurs
// Takes a class derived from the base Action class
public void episodeStep(T action);
// fired when an episode finish event occurs
public void episodeFinish();
// signals the brain that the simulator cannot proceed
public boolean halted();
```
The following is an example of a ModelExecuter class that derives from ISimulator using ModelAction action and ModelConfig config types:
```java
/**
* ModelExecutor
*/
import com.anylogic.sdk3.connector.*;
public class ModelExecutor implements ISimulator<ModelAction, ModelConfig> {
CustomExperiment exp;
/**
* Default constructor
*/
public ModelExecutor() {
}
@Override
public String toString() {
return super.toString();
}
@Override
public Observation getObservable() {
if (exp !=null && exp.root !=null)
return exp.root.getObservation();
else
return new ModelObservation();
}
public void episodeStart(ModelConfig config) {
steps = 0;
traceln("EPISODE START");
exp.engine = exp.createEngine();
// other start up info, like timings
// Create new root object:
exp.root = new Main( exp.engine, null, null );
// TODO Setup parameters of root object here
exp.root.setParametersToDefaultValues();
if(config != null) {
exp.root.set_maxGreenEW((int)config.Max_time_EW);
exp.root.set_maxGreenNS((int)config.Max_time_NS);
}
// ...
// Prepare Engine for simulation:
exp.engine.start( exp.root );
// Start simulation in fast mode:
exp.engine.runFast();
}
int steps = 0;
public void episodeStep(ModelAction action) {
steps += 1;
traceln("STEP NUMBER " + steps);
exp.root.doAction(action.switch_action);
exp.engine.runFast();
}
public boolean halted() {
if (exp !=null && exp.root !=null)
return exp.root.halted;
else
return false;
}
public void episodeFinish() {
traceln("EPISODE FINISH");
exp.engine.stop();
}
}
```
## The Config class
The Config class is used to define the values that the Bonsai brain will use during an episode start event. These allow you to create a machine teaching curriculum for your brain. For more on curriculums, see [here].
An example of a derived Config class is:
```java
import com.anylogic.sdk3.connector.Config;
public class ModelConfig extends Config {
public double arrivalRate;
public double existenceCostPH;
public double resABusyCostPH;
public double resAIdleCostPH;
public double resBBusyCostPH;
public double resBIdleCostPH;
public double relativeProcessCost;
public double relativeMoveCost;
}
```
The values in your Config class should map to the config type values in inkling. For example, using the values above, you would also have:
```
type SimConfig {
arrivalRate: number,
existenceCostPH: number,
resABusyCostPH: number,
resAIdleCostPH: number,
resBBusyCostPH: number,
resBIdleCostPH: number,
relativeProcessCost: number,
relativeMoveCost: number,
}
```
defined in your inkling for your brain in Bonsai.
## The Observation class
The Observation class is used to define the class that will be using to communicate the state of the AnyLogic model to the Bonsai brain. As outlined above, these values are used by the brain to evaluate reward and terminal conditions as well as what action the model should take next. An example of a derived Observation class is:
```java
import com.anylogic.sdk3.connector.Observation;
public class ModelObservation extends Observation {
public double arrivalRate;
public int nResA;
public int nResB;
public double utilResA;
public double utilResB;
public double idleCostResA;
public double idleCostResB;
public double busyCostResA;
public double busyCostResB;
public double processTime;
public double conveyorSpeed;
public double costPerProduct;
}
```
The values in your Observation class should map to the state type values in inkling. For example, using the values above, you would also have:
```
type SimState {
arrivalRate: number<0.5 .. 2.0>,
nResA: Number.Int32<1 .. 20>,
nResB: Number.Int32<1 .. 20>,
utilResA: number,
utilResB: number,
idleCostResA: number<0.1 .. 20>,
idleCostResB: number<0.1 .. 20>,
busyCostResA: number<0.1 .. 20>,
busyCostResB: number<0.1 .. 20>,
processTime: number<1.0 .. 12.0>,
conveyorSpeed: Number.Int32<0 .. 15>,
costPerProduct: number<1.0 .. 15.0>,
}
```
defined in your inkling for your brain in Bonsai.
<b><i>Note</i></b>
> It is a recommended best practice to indicate the ranges of your states in inkling. This will increase the speed of your brain training.
## The Action class
The Action class is used to define the class that will be using to parse the action from the Bonsai brain to be performed in the AnyLogic model. This may include As outlined above, these values are used by the brain to evaluate reward and terminal conditions as well as what action the model should take next. An example of a derived Observation class is:
```java
import com.anylogic.sdk3.connector.Action;
public class ModelAction extends Action {
public int nResA;
public int nResB;
public double processTime;
public double conveyorSpeed;
}
```
The values in your Action class should map to the action type values in inkling. For example, using the values above, you would also have:
```
type Action {
nResA: number<1 .. 20>,
nResB: number<1 .. 20>,
processTime: number<1.0 .. 12.0>,
conveyorSpeed: number<1.0 .. 15.0>,
}
```
defined in your inkling for your brain in Bonsai.
<b><i>Note</i></b>
> It is a recommended best practice to indicate the ranges of your actions in inkling. This will increase the speed of your brain training.
# Configuring a Custom Experiment
Now that you have configured your ModelExecuter, ModelConfig, ModelObservation and ModelAction, it is time to connect them together in a <a href="https://help.anylogic.com/index.jsp?topic=%2Fcom.anylogic.help%2Fhtml%2Fexperiments%2FCustom_Experiment.html">custom experiment</a>.
In this case, our custom experiment will set up the configuration and session information to communicate to the Bonsai platform.
A sample CustomExperiment class:
```java
// our sim object that implements ISimulator is the ModelExecuter class
sim = new ModelExecutor();
sim.exp = this;
// the workspace ID obtained from the Bonsai platform
String workspace = "<BONSAI_WORKSPACE_ID>";
// the access key obtained from the Bonsai platform
String accessKey = "<BONSAI_ACCESS_KEY>";
// this will show as the simulator name in the Bonsai dashboard
String simulatorName = "AnyLogic Pro 8";
// create a SessionConfig class (from the SDK) with your connection information
SessionConfig sc = new SessionConfig(accessKey, workspace, simulatorName);
// create a SimulatorSession class (from the SDK) to communicate with the Bonsai platform
// note the additional ModelAction.class and ModelConfig.class parameters.
// These indicate the derived types of the classes you defined above
SimulatorSession session = new SimulatorSession(sc, sim, ModelAction.class, ModelConfig.class);
// start the session. This registers your simulator with the Bonsai platform
session.startSession();
```
After starting your simulator locally, go to your brain in the Bonsai dashboard. Click the Train button, then select the name of your simulator ("AnyLogic Pro 8" above). It may take several seconds for the brain to connect to your simulator and fire the first episode start event.
## Disposing of local connections to Bonsai
Each session with Bonsai is given a unique ID that is used during communication. If the custom experiment is stopped using the red stop button in AnyLogic, there is not a chance to unregister the simulator from Bonsai. This will result in multiple simulators named "AnyLogic Pro 8" showing up in your dashboard and may cause confusion. If this happens, you can retrieve the session ID from the Bonsai platform by clicking on the simulator and then getting the ID from the URL. For example:
https://preview.bons.ai/workspaces/123456789012345a/simulator/807951236_10.244.48.40/connect
The session ID in the above URL is:
807951236_10.244.48.40
You can manually unregister this simulator by calling:
```java
SessionConfig sc = new SessionConfig(accessKey, workspace, simulatorName);
SimulatorSession session = new SimulatorSession(sc, sim, ModelAction.class, ModelConfig.class);
// unregister a previous session
session.unregister("807951236_10.244.48.40");
// start new session here
```
- <a href="samples/abca">Activity Based Costing</a> - a simplified factory floor model for cost associated with product processing is calculated and analyzed.
- <a href="samples/product-delivery">Product Delivery</a> - simulates product delivery between three manufacturing facilities and fifteen distributors in the USA.

127
connector/README.md Normal file
Просмотреть файл

@ -0,0 +1,127 @@
# Bonsai Connector Library
The library will need to be included with your <a href="https://www.anylogic.com/features/artificial-intelligence/microsoft-bonsai/">wrapper</a>. While the <a href="wrapper_model_workflow.pdf">wrapper model workflow</a> outlines what needs to be included in your AnyLogic model, this document describes the classes that are used in the connector library and how they map to your inkling code code for Bonsai.
The Bonsai Connector includes base functionality for communicating to the Microsoft Bonsai service, and does not require the user to implement any special logic to do so. The connector includes three base classes that are used to implement connection to the Bonsai platform.
- Config class
- Observation class
- Action class
When your simulator connects to the Bonsai platform, it does so by:
1. Registering your simulator with the Bonsai platform using the Simulator Name specified in the connector. After starting your simulator, click on the Train button in the Bonsai dashboard and select the name of your simulator to begin training.
2. Upon an *episode start* event, the connector acquires an initial configuration from the Bonsai brain. This is used by a class derived from **Config** to set initial conditions for your model and map to the values in your Config type in inkling. You can learn more about configuring lessons in inkling <a href=
https://docs.microsoft.com/en-us/bonsai/inkling/">here</a>.
3. At each *episode step* in your model the connector sends the values derived from the **Observation** class. The values in your derived Observation class should match the name and types of variables found in the State type in your inkling for your Bonsai brain. When the brain receives the observation, it also evaluates the reward or terminal conditions associated with your inkling and determines the next best action.
4. During the *episode step* event, the connector provides the values from a derived **Action** class. These values map to the Action type in your inkling for your Bonsai brain and represent the next step, or action, the brain would like your model to run.
5. If a terminal condition is hit in inkling, or your simulator reaches a halted state, the connector will fire an *episode finish* event. This is a great place to stop your model and get it ready for a new run.
## The Config class
The Config class is used to define the values that the Bonsai brain will use during an episode start event. These allow you to create a machine teaching curriculum for your brain. For more on curriculums, see [here].
An example of a derived Config class is:
```java
import com.anylogic.sdk3.connector.Config;
public class ModelConfig extends Config {
public double arrivalRate;
public double existenceCostPH;
public double resABusyCostPH;
public double resAIdleCostPH;
public double resBBusyCostPH;
public double resBIdleCostPH;
public double relativeProcessCost;
public double relativeMoveCost;
}
```
The values in your Config class should map to the config type values in inkling. For example, using the values above, you would also have:
```
type SimConfig {
arrivalRate: number,
existenceCostPH: number,
resABusyCostPH: number,
resAIdleCostPH: number,
resBBusyCostPH: number,
resBIdleCostPH: number,
relativeProcessCost: number,
relativeMoveCost: number,
}
```
defined in your inkling for your brain in Bonsai.
## The Observation class
The Observation class is used to define the class that will be using to communicate the state of the AnyLogic model to the Bonsai brain. As outlined above, these values are used by the brain to evaluate reward and terminal conditions as well as what action the model should take next. An example of a derived Observation class is:
```java
import com.anylogic.sdk3.connector.Observation;
public class ModelObservation extends Observation {
public double arrivalRate;
public int nResA;
public int nResB;
public double utilResA;
public double utilResB;
public double idleCostResA;
public double idleCostResB;
public double busyCostResA;
public double busyCostResB;
public double processTime;
public double conveyorSpeed;
public double costPerProduct;
}
```
The values in your Observation class should map to the state type values in inkling. For example, using the values above, you would also have:
```
type SimState {
arrivalRate: number<0.5 .. 2.0>,
nResA: Number.Int32<1 .. 20>,
nResB: Number.Int32<1 .. 20>,
utilResA: number,
utilResB: number,
idleCostResA: number<0.1 .. 20>,
idleCostResB: number<0.1 .. 20>,
busyCostResA: number<0.1 .. 20>,
busyCostResB: number<0.1 .. 20>,
processTime: number<1.0 .. 12.0>,
conveyorSpeed: Number.Int32<0 .. 15>,
costPerProduct: number<1.0 .. 15.0>,
}
```
defined in your inkling for your brain in Bonsai.
> It is a recommended best practice to indicate the ranges of your states in inkling. This will increase the speed of your brain training.
## The Action class
The Action class is used to define the class that will be using to parse the action from the Bonsai brain to be performed in the AnyLogic model. This may include As outlined above, these values are used by the brain to evaluate reward and terminal conditions as well as what action the model should take next. An example of a derived Observation class is:
```java
import com.anylogic.sdk3.connector.Action;
public class ModelAction extends Action {
public int nResA;
public int nResB;
public double processTime;
public double conveyorSpeed;
}
```
The values in your Action class should map to the action type values in inkling. For example, using the values above, you would also have:
```
type Action {
nResA: number<1 .. 20>,
nResB: number<1 .. 20>,
processTime: number<1.0 .. 12.0>,
conveyorSpeed: number<1.0 .. 15.0>,
}
```
defined in your inkling for your brain in Bonsai.
> It is a recommended best practice to indicate the ranges of your actions in inkling. This will increase the speed of your brain training.

Двоичные данные
connector/activation-1.1.1.jar

Двоичный файл не отображается.

Двоичные данные
connector/aopalliance-repackaged-2.5.0-b32.jar

Двоичный файл не отображается.

Двоичные данные
connector/com.anylogic.sdk3.connector-0.0.4.jar

Двоичный файл не отображается.

Двоичные данные
connector/hk2-api-2.5.0-b32.jar

Двоичный файл не отображается.

Двоичные данные
connector/hk2-locator-2.5.0-b32.jar

Двоичный файл не отображается.

Двоичные данные
connector/hk2-utils-2.5.0-b32.jar

Двоичный файл не отображается.

Двоичные данные
connector/jackson-annotations-2.8.4.jar

Двоичный файл не отображается.

Двоичные данные
connector/jackson-core-2.10.1.jar

Двоичный файл не отображается.

Двоичные данные
connector/jackson-databind-2.8.4.jar

Двоичный файл не отображается.

Двоичные данные
connector/jackson-jaxrs-base-2.8.4.jar

Двоичный файл не отображается.

Двоичные данные
connector/jackson-jaxrs-json-provider-2.8.4.jar

Двоичный файл не отображается.

Двоичные данные
connector/jackson-jr-objects-2.10.1.jar

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичные данные
connector/javassist-3.20.0-GA.jar

Двоичный файл не отображается.

Двоичные данные
connector/javax.annotation-api-1.2.jar

Двоичный файл не отображается.

Двоичные данные
connector/javax.inject-2.5.0-b32.jar

Двоичный файл не отображается.

Двоичные данные
connector/javax.ws.rs-api-2.0.1.jar

Двоичный файл не отображается.

Двоичные данные
connector/jaxb-api-2.3.0.jar

Двоичный файл не отображается.

Двоичные данные
connector/jaxb-core-2.3.0.jar

Двоичный файл не отображается.

Двоичные данные
connector/jaxb-impl-2.3.0.jar

Двоичный файл не отображается.

Двоичные данные
connector/jersey-client-2.25.1.jar

Двоичный файл не отображается.

Двоичные данные
connector/jersey-common-2.25.1.jar

Двоичный файл не отображается.

Двоичные данные
connector/jersey-entity-filtering-2.25.1.jar

Двоичный файл не отображается.

Двоичные данные
connector/jersey-guava-2.25.1.jar

Двоичный файл не отображается.

Двоичные данные
connector/jersey-media-json-jackson-2.25.1.jar

Двоичный файл не отображается.

Двоичные данные
connector/json-20190722.jar

Двоичный файл не отображается.

Двоичные данные
connector/osgi-resource-locator-1.0.1.jar

Двоичный файл не отображается.

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 163 KiB

После

Ширина:  |  Высота:  |  Размер: 163 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 81 KiB

После

Ширина:  |  Высота:  |  Размер: 81 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 66 KiB

После

Ширина:  |  Высота:  |  Размер: 66 KiB

Двоичные данные
samples/abca/Optimization-Comparison.docx Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -122,15 +122,15 @@ Back in the Bonsai UI, next to **Simulators**, click the **Add sim** button.
This will open a dialog.
<img src="Images/add_sim.png" alt="Add Sim Prompt" width="500" border="1"/>
<img src="../../images/add_sim.png" alt="Add Sim Prompt" width="500" border="1"/>
Select AnyLogic.
<img src="Images/add_sim_al_nozip.png" alt="Add Sim Prompt 2" width="500" border="1"/>
<img src="../../images/add_sim_al_nozip.png" alt="Add Sim Prompt 2" width="500" border="1"/>
Select or drag the zip file containing the exported model.
<img src="Images/add_sim_al_zip.png" alt="Add Sim Prompt 3" width="500" border="1"/>
<img src="../../images/add_sim_al_zip.png" alt="Add Sim Prompt 3" width="500" border="1"/>
Give your simulator a name, then click **Create simulator**.

Двоичные данные
samples/abca/exported.zip

Двоичный файл не отображается.

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Двоичные данные
samples/abca/model/AnyLogic model logo dark.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.6 KiB

Двоичные данные
samples/abca/model/Bonsai.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 50 KiB

Двоичные данные
samples/abca/model/activation-1.1.1.jar

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/hk2-api-2.5.0-b32.jar

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/hk2-locator-2.5.0-b32.jar

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/hk2-utils-2.5.0-b32.jar

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/jackson-annotations-2.8.4.jar

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/jackson-core-2.10.1.jar

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/jackson-databind-2.8.4.jar

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/jackson-jaxrs-base-2.8.4.jar

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/jackson-jr-objects-2.10.1.jar

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/javassist-3.20.0-GA.jar

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/javax.annotation-api-1.2.jar

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/javax.inject-2.5.0-b32.jar

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/javax.ws.rs-api-2.0.1.jar

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/jaxb-api-2.3.0.jar

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/jaxb-core-2.3.0.jar

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/jaxb-impl-2.3.0.jar

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/jersey-client-2.25.1.jar

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/jersey-common-2.25.1.jar

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/jersey-guava-2.25.1.jar

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичные данные
samples/abca/model/json-20190722.jar

Двоичный файл не отображается.

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,148 @@
# Product Delivery Overview
This model simulates product delivery in USA. The supply chain includes three manufacturing facilities and fifteen distributors that order random amounts of the product – between 500 and 1000, uniformly distributed – each 1 to 2 days (uniformly distributed). There is a fleet of trucks in each manufacturing facility. When a manufacturing facility receives an order from a distributor, it checks the number of products in storage. If the required amount is available, it sends a loaded truck to the distributor. Otherwise, the order waits until the factory produces the sufficient number of products. Orders are queued in FIFO order.
### Complexity
- The demand coming from each distribution center should be varied:
- Seasonal change
- Sudden disruptions/surge in demand
### Observation space
- Inventory level at each manufacturing location
- Number of trucks, number of idle vs busy trucks, utilization of fleet at each location
- Whether manufacturing facility is open or not
- Average waiting time for orders placed at each manufacturer
- Average waiting time for all manufacturing facilities
### Action space
- Production rate of each facility
- Number of trucks in each facility
- If a facility should stay open or not
### Reward
- The reward is driven by minimizing the cost of average wait time across the system.
# Create a Brain
To start a new brain for this model:
1. Create an account or sign into Bonsai.
2. Click **Create brain** button in the top left, then select **Empty brain** in the dialog.
3. Name your new brain (e.g., “product-delivery”).
4. Click **Create Brain**. This will create a new brain for you.
Copy the contents of <a href="product_delivery.ink">product_delivery.ink</a> in to the *Teach* tab for your new brain.
Do not click Train yet.
# Understanding the Model
The Product Delivery model is made up of many components. The table below outlines how these components work together:
| Component | Description |
|----------|:-------------|
| Main agent | The primary agent that sets up the scenario. |
| Simulation: Main | The visual simulation. This does not run training with Bonsai. |
| CustomExperiment | The custom experiment is used to connect the AnyLogic model with the Bonsai platform using the <a href="../../connector">AnyLogic Library for Bonsai</a>. |
| ModelExecuter | Implements the ISimulator interface and handles the episode events from Bonsai. |
| ModelConfig | Implements the base Config class to set variables in the model for use of machine teaching in Bonsai. |
| ModelObservation | The state related information for the model to pass to the Bonsai platform. |
| ModelAction | The action from the Bonsai platform. For example, set variable *x* to value *v*. |
Open the CustomExperiment and enter your workspace and access keys for connecting to the Bonsai platform. These can be obtained from [link].
Example CustomExperiment:
```java
sim = new ModelExecutor();
sim.exp = this;
// bonsai workspace
String workspace = "<your workspace here>";
// access key, generated from https://beta.bons.ai/brains/accounts/settings
String accessKey = "<your access key here>";
String simulatorName = "AnyLogic - ABCA";
SessionConfig sc = new SessionConfig(accessKey, workspace, simulatorName);
SimulatorSession session = new SimulatorSession(sc, sim, ModelAction.class, ModelConfig.class);
session.startSession();
```
Once you have entered your workspace and access keys, you are ready to run the model.
# Running the Model
To run the model, right click on **CustomExperiment** then click the **Run** button. You will see text in the console about registering with the Bonsai platform. Once registration is complete (it will only take a few seconds), go back to the Bonsai dashboard where you created your brain.
Click the **Train** button. The simulator with the name matching your simulator will appear (in the example above, this is called *AnyLogic - ABCA*). Click the name of your simulator.
If this is the first start of your brain it may take a few minutes for the brain to generate the appropriate parameters and connect to the simulator. Once the connection is made you will see your first episodeStart event fire in the ModelExecuter handler.
You may decide to let your training run for a bit, particularly across multiple episode start events, to get an understanding of how the model behaves under various configuration parameters provided by the brain. You will also want to make sure your number of iterations stay below 1000, or the brain will struggle to learn. If needed, you can implement custom logic in the **halted()** method in ModelExecuter to help drive behavior. Halted indicates to the brain that the simulator has reached a state that it cannot progress from.
After you have tested locally, stop your model. Then click **Stop Training** in the Bonsai dashboard for the brain.
# Export Your Model
After you have confirmed your model can connect to the platform locally, it's time to scale your model.
AnyLogic Professional users can export their model by going to **File** > **Export...** > **to standalone Java application** in the menu bar.
Select CustomExperiment in the dialog and the directory where the exported files will reside.
If you need additional assistance with exporting a model, please see the <a href="https://help.anylogic.com/index.jsp?topic=%2Fcom.anylogic.help%2Fhtml%2Fstandalone%2FExport_Java_Application.html">Exporting a model as a standalone Java application</a> topic in the AnyLogic Help topics.
If you are not able to export your model to a standalone Java application you may use the example <a href="exported.zip">exported.zip</a> file to use for scaling.
# Scale Your Model
Once you have exported your model, you can zip the entire contents of the folder that contains the exported application.
For example, if your folder structure is:
```
Product Delivery Export
└─── lib
| |── AnyLogic Model End User Agreement.pdf
| └── ... jar files ...
|─── Product Delivery_linux.sh
|─── ... jar files ...
└─── readme.txt
```
Then you only need to zip the parent **Product Delivery** folder.
Back in the Bonsai dashboard, next to **Simulators**, click the **Add sim** button.
This will open a dialog.
<img src="../../images/add_sim.png" alt="Add Sim Prompt" width="500" border="1"/>
Select AnyLogic.
<img src="../../images/add_sim_al_nozip.png" alt="Add Sim Prompt 2" width="500" border="1"/>
Select or drag the zip file containing the exported model.
<img src="../../images/add_sim_al_zip.png" alt="Add Sim Prompt 3" width="500" border="1"/>
Give your simulator a name, then click **Create simulator**.
After the simulator is created you will see the new simulator appear under the **Simulators** section.
Now click the *Teach* tab.
In the simulator definition, just after the open brackets, add a package</a> statement using the name of the simulator you gave during the Add Simulator dialog above.
```
simulator Simulator(action: Action, config: SimConfig): SimState {
package "<simulator_name>"
}
```
Now click **Train**. Since you indicated the package name you do not need to select a simulator from the dropdown like you did when you started locally.
In a few minutes time you will see several simulators connect to and train your brain.
# Using Bonsai Assessment with Your Model
Starting an Assessment session is similar to starting a training session. Start your CustomExperiment class and wait for it to register. In the Bonsai UI, using your already-trained brain, click the **Assessment** button. Then select the name of your simulator.

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Двоичные данные
samples/product-delivery/model/AnyLogic model logo dark.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.6 KiB

Двоичные данные
samples/product-delivery/model/Bonsai.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 50 KiB

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Двоичные данные
samples/product-delivery/model/cache/giscache поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
samples/product-delivery/model/cache/giscache.p поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
samples/product-delivery/model/cache/giscache.t поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
samples/product-delivery/model/database/db.lck Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,5 @@
#HSQL Database Engine 2.4.1
#Sun May 17 21:12:08 CDT 2020
tx_timestamp=0
modified=yes
version=2.4.1

Просмотреть файл

@ -0,0 +1,105 @@
SET DATABASE UNIQUE NAME HSQLDB6B2845B5DD
SET DATABASE GC 0
SET DATABASE DEFAULT RESULT MEMORY ROWS 0
SET DATABASE EVENT LOG LEVEL 0
SET DATABASE TRANSACTION CONTROL LOCKS
SET DATABASE DEFAULT ISOLATION LEVEL READ COMMITTED
SET DATABASE TRANSACTION ROLLBACK ON CONFLICT TRUE
SET DATABASE TEXT TABLE DEFAULTS ''
SET DATABASE SQL NAMES FALSE
SET DATABASE SQL REFERENCES FALSE
SET DATABASE SQL SIZE TRUE
SET DATABASE SQL TYPES FALSE
SET DATABASE SQL TDC DELETE TRUE
SET DATABASE SQL TDC UPDATE TRUE
SET DATABASE SQL CONCAT NULLS TRUE
SET DATABASE SQL UNIQUE NULLS TRUE
SET DATABASE SQL CONVERT TRUNCATE TRUE
SET DATABASE SQL AVG SCALE 0
SET DATABASE SQL DOUBLE NAN TRUE
SET FILES WRITE DELAY 500 MILLIS
SET FILES BACKUP INCREMENT TRUE
SET FILES CACHE SIZE 10000
SET FILES CACHE ROWS 50000
SET FILES SCALE 32
SET FILES LOB SCALE 32
SET FILES DEFRAG 0
SET FILES NIO TRUE
SET FILES NIO SIZE 256
SET FILES LOG TRUE
SET FILES LOG SIZE 50
CREATE USER SA PASSWORD DIGEST 'd41d8cd98f00b204e9800998ecf8427e'
ALTER USER SA SET LOCAL TRUE
CREATE SCHEMA PUBLIC AUTHORIZATION DBA
SET SCHEMA PUBLIC
CREATE MEMORY TABLE PUBLIC.AL_CONFIGURATION(PROPERTY_NAME VARCHAR(255) NOT NULL,PROPERTY_VALUE VARCHAR(16777216),UNIQUE(PROPERTY_NAME))
CREATE MEMORY TABLE PUBLIC.AL_GROUPS(GROUP_NAME VARCHAR(255) NOT NULL PRIMARY KEY,DESCRIPTION VARCHAR(16777216))
CREATE MEMORY TABLE PUBLIC.AL_TABLES(TABLE_NAME VARCHAR(255) NOT NULL PRIMARY KEY,GROUP_NAME VARCHAR(255),DESCRIPTION VARCHAR(16777216))
CREATE MEMORY TABLE PUBLIC.AL_CUSTOM_TYPE(TABLE_NAME VARCHAR(255),COLUMN_NAME VARCHAR(255),TYPE VARCHAR(255),NAME VARCHAR(255))
CREATE MEMORY TABLE PUBLIC.AL_VIEWS(VIEW_NAME VARCHAR(255) NOT NULL,VIEW_DEFINITION VARCHAR(16777216),IS_VALID BOOLEAN,UNIQUE(VIEW_NAME))
CREATE MEMORY TABLE PUBLIC.AL_SELECTED_LOG_OBJECTS(NAME VARCHAR(255) NOT NULL,TYPE VARCHAR(255),UNIQUE(NAME))
CREATE MEMORY TABLE PUBLIC.AL_DB_OBJECTS(NAME VARCHAR(255) NOT NULL,TYPE VARCHAR(255),USAGE VARCHAR(255),UNIQUE(NAME))
CREATE MEMORY TABLE PUBLIC.DISTRIBUTORS(AL_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,CITY VARCHAR(16777216))
ALTER TABLE PUBLIC.DISTRIBUTORS ALTER COLUMN AL_ID RESTART WITH 15
CREATE MEMORY TABLE PUBLIC.MANUFACTURING_CENTERS(AL_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,CITY VARCHAR(16777216))
ALTER TABLE PUBLIC.MANUFACTURING_CENTERS ALTER COLUMN AL_ID RESTART WITH 3
ALTER SEQUENCE SYSTEM_LOBS.LOB_ID RESTART WITH 1
SET DATABASE DEFAULT INITIAL SCHEMA PUBLIC
GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.SQL_IDENTIFIER TO PUBLIC
GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.YES_OR_NO TO PUBLIC
GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.TIME_STAMP TO PUBLIC
GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CARDINAL_NUMBER TO PUBLIC
GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CHARACTER_DATA TO PUBLIC
GRANT DBA TO SA
SET SCHEMA SYSTEM_LOBS
INSERT INTO BLOCKS VALUES(0,2147483647,0)
SET SCHEMA PUBLIC
INSERT INTO AL_CONFIGURATION VALUES('VERSION','7.2.0')
INSERT INTO AL_TABLES VALUES('distributors',NULL,'')
INSERT INTO AL_TABLES VALUES('manufacturing_centers',NULL,'')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('agents_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('library_blocks_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('agent_parameters_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('library_block_parameters_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('agent_movement_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('agent_movement_stats_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('agent_messages_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('events_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('flowchart_entries_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('flowchart_process_states_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('flowchart_stats_time_in_state_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('resource_unit_states_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('resource_unit_task_stats_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('resource_pool_task_stats_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('resource_pool_utilization_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('resource_unit_utilization_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('fluid_units_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('fluid_storages_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('fluid_rates_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('fluid_utilization_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('statechart_transitions_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('agent_statechart_states_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('agent_statechart_stats_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('agent_type_statechart_stats_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('statistics_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('datasets_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('histograms_log','VIEW')
INSERT INTO AL_SELECTED_LOG_OBJECTS VALUES('trace_log','VIEW')
INSERT INTO DISTRIBUTORS VALUES(0,'Madison')
INSERT INTO DISTRIBUTORS VALUES(1,'Cedar Rapids')
INSERT INTO DISTRIBUTORS VALUES(2,'Memphis')
INSERT INTO DISTRIBUTORS VALUES(3,'St.Louis')
INSERT INTO DISTRIBUTORS VALUES(4,'Peoria')
INSERT INTO DISTRIBUTORS VALUES(5,'Dayton')
INSERT INTO DISTRIBUTORS VALUES(6,'Evansville')
INSERT INTO DISTRIBUTORS VALUES(7,'Topeka')
INSERT INTO DISTRIBUTORS VALUES(8,'Knoxville')
INSERT INTO DISTRIBUTORS VALUES(9,'Richmond')
INSERT INTO DISTRIBUTORS VALUES(10,'Charleston')
INSERT INTO DISTRIBUTORS VALUES(11,'Harrisburg')
INSERT INTO DISTRIBUTORS VALUES(12,'Norfolk')
INSERT INTO DISTRIBUTORS VALUES(13,'Linkoln')
INSERT INTO DISTRIBUTORS VALUES(14,'Tulsa')
INSERT INTO MANUFACTURING_CENTERS VALUES(0,'Chicago')
INSERT INTO MANUFACTURING_CENTERS VALUES(1,'Pittsburg')
INSERT INTO MANUFACTURING_CENTERS VALUES(2,'Nashville')

Двоичные данные
samples/product-delivery/model/sim_layout.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 193 KiB

Просмотреть файл

@ -0,0 +1,185 @@
inkling "2.0"
using Number
using Math
#what the simulator sends
type SimState {
Chicago_is_open: Number.Int8<0..1>,
Pittsburg_is_open: Number.Int8<0..1>,
Nashville_is_open: Number.Int8<0..1>,
Chicago_util_trucks: number<0..1>,
Pittsburg_util_trucks: number<0..1>,
Nashville_util_trucks: number<0..1>,
Chicago_inventory_level: number<0..30000>,
Pittsburg_inventory_level: number<0..30000>,
Nashville_inventory_level: number<0..30000>,
Chicago_orders_queueing: number<0 .. 100>,
Pittsburg_orders_queueing: number<0 .. 100>,
Nashville_orders_queueing: number<0 .. 100>,
Chicago_production_rate: number<50 .. 80>,
Pittsburg_production_rate: number<50 .. 80>,
Nashville_production_rate: number<50 .. 80>,
# technically, all of the following can be 'infinity' if no products completed yet
# we set them to -1, as an indicator. otherwise 0 is the minimum value
Chicago_average_turnaround: number<-1 .. 500>,
Pittsburg_average_turnaround: number<-1 .. 500>,
Nashville_average_turnaround: number<-1 .. 500>,
Chicago_cost_per_product: number<-1 .. 4000000>,
Pittsburg_cost_per_product: number<-1 .. 4000000>,
Nashville_cost_per_product: number<-1 .. 4000000>,
overall_average_turnaround: number<-1 .. 500>,
overall_average_cost_per_product: number<-1 .. 4000000>,
#based on model time
time: number<0 .. 800>
}
#what the brain sees during training
type ObservationState {
Chicago_is_open: Number.Int8<0..1>,
Pittsburg_is_open: Number.Int8<0..1>,
Nashville_is_open: Number.Int8<0..1>,
Chicago_util_trucks: number<0..1>,
Pittsburg_util_trucks: number<0..1>,
Nashville_util_trucks: number<0..1>,
Chicago_inventory_level: number<0..30000>,
Pittsburg_inventory_level: number<0..30000>,
Nashville_inventory_level: number<0..30000>,
Chicago_orders_queueing: number<0 .. 100>,
Pittsburg_orders_queueing: number<0 .. 100>,
Nashville_orders_queueing: number<0 .. 100>,
Chicago_production_rate: number<50 .. 80>,
Pittsburg_production_rate: number<50 .. 80>,
Nashville_production_rate: number<50 .. 80>,
# technically, all of the following can be 'infinity' if no products completed yet
# we set them to -1, as an indicator. otherwise 0 is the minimum value
Chicago_average_turnaround: number<-1 .. 500>,
Pittsburg_average_turnaround: number<-1 .. 500>,
Nashville_average_turnaround: number<-1 .. 500>,
Chicago_cost_per_product: number<-1 .. 4000000>,
Pittsburg_cost_per_product: number<-1 .. 4000000>,
Nashville_cost_per_product: number<-1 .. 4000000>,
overall_average_turnaround: number<-1 .. 500>,
overall_average_cost_per_product: number<-1 .. 4000000>,
}
type Action {
Chicago_is_open: number<0..1>,
Pittsburg_is_open: number<0..1>,
Nashville_is_open: number<0..1>,
Chicago_num_trucks: number<1..3>,
Pittsburg_num_trucks: number<1..3>,
Nashville_num_trucks: number<1..3>,
Chicago_production_rate: number<50..80>,
Pittsburg_production_rate: number<50..80>,
Nashville_production_rate: number<50..80>,
}
type AnyLogicAction {
Chicago_is_open: number,
Pittsburg_is_open: number,
Nashville_is_open: number,
Chicago_num_trucks: number,
Pittsburg_num_trucks: number,
Nashville_num_trucks: number,
Chicago_production_rate: number,
Pittsburg_production_rate: number,
Nashville_production_rate: number
}
type Config {
Chicago_is_open: Number.Int8,
Pittsburg_is_open: Number.Int8,
Nashville_is_open: Number.Int8,
}
function Reward(obs: SimState) {
# return a harsh penalty if all sites are closed
if ( obs.Chicago_is_open + obs.Pittsburg_is_open + obs.Nashville_is_open == 0 )
{
return -1
}
# scale approx range of turnaround times [2 days, 2 weeks] / [48 hours, 336 hours] to [1, -1]
var turnaround_points = ((obs.overall_average_turnaround - 48) / (336 - 48)) * (-1 - 1) + 1
# scale approx range of cpp [200k, 3.8 mil] to [1, -1]
# but first scale down cpp to an easier to write value
var cpp = obs.overall_average_cost_per_product / 100000
# now scale from [2, 38] to [1, -1]
var cpp_points = ((cpp - 2) / (38 - 2)) * (-1 - 1) + 1
# weight both points equally
return (turnaround_points + cpp_points) / 2
}
function Terminal(obs: SimState)
{
return obs.time >= 720
}
function TranslateBonsaiActiontoAnyLogicAction(a: Action) : AnyLogicAction
{
return
{
Chicago_is_open: Math.Floor(a.Chicago_is_open+.5),
Pittsburg_is_open: Math.Floor(a.Pittsburg_is_open+.5),
Nashville_is_open: Math.Floor(a.Nashville_is_open+.5),
Chicago_num_trucks: Math.Floor(a.Chicago_num_trucks+.5),
Pittsburg_num_trucks: Math.Floor(a.Pittsburg_num_trucks+.5),
Nashville_num_trucks: Math.Floor(a.Nashville_num_trucks+.5),
Chicago_production_rate: Math.Floor(a.Chicago_production_rate+.5),
Pittsburg_production_rate: Math.Floor(a.Pittsburg_production_rate+.5),
Nashville_production_rate: Math.Floor(a.Nashville_production_rate+.5),
}
}
simulator Simulator(action: Action, config: Config): SimState {
#package "<simulator_name>"
}
graph (input: ObservationState): Action {
concept optimize(input): Action {
curriculum {
source Simulator
reward Reward
terminal Terminal
action TranslateBonsaiActiontoAnyLogicAction
lesson vary {
scenario {
Chicago_is_open: Number.Int8<0,1,>,
Pittsburg_is_open: Number.Int8<0,1,>,
Nashville_is_open: Number.Int8<0,1,>,
}
}
}
}
output optimize
}