Loading a problem from the rddlrepository.#
This basic example illustrates how to load a problem from the rddlrepository.
First install and import the required packages:
%pip install --quiet --upgrade pip
%pip install --quiet git+https://github.com/pyrddlgym-project/rddlrepository.git
Note: you may need to restart the kernel to use updated packages.
Note: you may need to restart the kernel to use updated packages.
Import the required packages:
from rddlrepository.core.manager import RDDLRepoManager
Listing available contexts, domains and instances.#
Problems in rddlrepository are grouped into contexts:
manager = RDDLRepoManager(rebuild=True)
manager.list_contexts()
['arcade',
'ippc2011',
'ippc2014',
'ippc2018',
'ippc2023',
'gym',
'mycontext',
'or',
'rddlsim',
'standalone']
As you can infer from the names, contexts of the form ippcxxxx
refer to domains in prior years’ international planning competitions, gym
refers to RDDL implementations of domains from the original OpenAI gym, and so on.
To list all the domains in a given context, e.g. ippc2014
:
manager.list_problems_by_context('ippc2014')
['AcademicAdvising_MDP_ippc2014',
'AcademicAdvising_POMDP_ippc2014',
'CrossingTraffic_MDP_ippc2014',
'CrossingTraffic_POMDP_ippc2014',
'Elevators_MDP_ippc2014',
'Elevators_POMDP_ippc2014',
'SkillTeaching_MDP_ippc2014',
'SkillTeaching_POMDP_ippc2014',
'Tamarisk_MDP_ippc2014',
'Tamarisk_POMDP_ippc2014',
'Traffic_MDP_ippc2014',
'Traffic_POMDP_ippc2014',
'TriangleTireworld_MDP_ippc2014',
'TriangleTireworld_POMDP_ippc2014',
'Wildfire_MDP_ippc2014',
'Wildfire_POMDP_ippc2014']
To list all the instances in a given domain, e.g. Wildfire_MDP_ippc2014
:
info = manager.get_problem('Wildfire_MDP_ippc2014')
info.list_instances()
['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
As you can see, there are 10 instances available for the Wildfire domain, ranging from 1 to 10.
Loading domains and instances.#
Now that you understand how to extract information about domains and instances, let’s load the actual domain and instance RDDL specification, as well as the default visualizer object assigned to the domain:
print(info.get_domain())
print(info.get_instance('1'))
print(info.get_visualizer())
C:\Python\lib\site-packages\rddlrepository\archive\competitions\IPPC2014\Wildfire\MDP\domain.rddl
C:\Python\lib\site-packages\rddlrepository\archive\competitions\IPPC2014\Wildfire\MDP\instance1.rddl
<class 'rddlrepository.archive.competitions.IPPC2014.Wildfire.MDP.WildfireViz.WildfireVisualizer'>
This provides the paths to the domain and instance RDDL files on the system, as well as the Visualizer
instance that can be passed to the pyRDDLGym environment.
Finally, let’s inspect the content of the domain specification:
with open(info.get_domain()) as file:
print(file.read())
///////////////////////////////////////////////////////////////////////////////
//
// A boolean version of the wildfire fighting domain.
//
// Author: Zhenyu Yu (fry3721@gmail.com)
//
// General reference:
//
// Karafyllidis, I., & Thanailakis, A. (1997).
// A model for predicting forest fire spreading using gridular automata.
// Ecological Modelling, 99(1), 87-97.
// http://www.dpi.inpe.br/gilberto/cursos/st-society-2013/Kara1997.pdf
//
// In a general wildfire scenario, its spread is mostly determined by
// the weather (i.e. wind), terrain slope, and fuel type (i.e. grass, wood).
// In this scenario, a map is represented with grids, size of n*n.
// Each grid has some attributes, including fuel type, terrain elevation.
// Furthermore, the fuel type and terrain elevation will affect the fire
// spreading speed. Some fuel type is more easily on fire than other,
// and higher grids are always easier to catch fire. Cell features and
// effects of wind are not modeled in this simplified version.
//
// In this version, whether a cell would be on fire is determined by its
// neighbor grids, and the fire spreading law is simplified with this function
//
// p(burning(xi, yj)=true) = 1 / (1 + exp(4.5 - k))
//
// where k is the number of neighbors on fire.
//
// The decision task to a emergency manager is to control the fire
// and keep it away from important targets.
//
// Modified for competition and translation purposes by Scott Sanner.
//
///////////////////////////////////////////////////////////////////////////////
domain wildfire_mdp {
types {
x_pos : object;
y_pos : object;
};
pvariables {
// Action costs and penalties
COST_CUTOUT : {non-fluent, real, default = -5 }; // Cost to cut-out fuel from a cell
COST_PUTOUT : {non-fluent, real, default = -10 }; // Cost to put-out a fire from a cell
PENALTY_TARGET_BURN : {non-fluent, real, default = -100 }; // Penalty for each target cell that is burning
PENALTY_NONTARGET_BURN : {non-fluent, real, default = -5 }; // Penalty for each non-target cell that is burning
// Topology of the cells (can be any neighborhood topology, not necessarily rectangular)
NEIGHBOR(x_pos, y_pos, x_pos, y_pos) : { non-fluent, bool, default = false };
// High value cells that should be protected from fire
TARGET(x_pos, y_pos) : {non-fluent, bool, default = false };
// State fluents
burning(x_pos, y_pos) : { state-fluent, bool, default = false }; // cell currently on fire
out-of-fuel(x_pos, y_pos) : { state-fluent, bool, default = false }; // cell does not have fuel to burn (i.e., cut-out or already burned)
// Action fluents
put-out(x_pos, y_pos) : { action-fluent, bool, default = false }; // actions to put-out out the fire
cut-out(x_pos, y_pos) : { action-fluent, bool, default = false }; // cut-out out the fuel
};
cpfs {
burning'(?x, ?y) =
if ( put-out(?x, ?y) ) // Intervention to put out fire?
then false
// Modification: targets can only start to burn if at least one neighbor is on fire
else if (~out-of-fuel(?x, ?y) ^ ~burning(?x, ?y)) // Ignition of a new fire? Depends on neighbors.
then [if (TARGET(?x, ?y) ^ ~(exists_{?x2: x_pos, ?y2: y_pos} (NEIGHBOR(?x, ?y, ?x2, ?y2) ^ burning(?x2, ?y2))))
then false
else Bernoulli( 1.0 / (1.0 + exp[4.5 - (sum_{?x2: x_pos, ?y2: y_pos} (NEIGHBOR(?x, ?y, ?x2, ?y2) ^ burning(?x2, ?y2)))]) ) ]
else
burning(?x, ?y); // State persists
// Modification: only allow non-target cells to be cut-out (cannot remove fuel from targets, e.g., housing)
out-of-fuel'(?x, ?y) = out-of-fuel(?x, ?y) | burning(?x,?y) | (~TARGET(?x, ?y) ^ cut-out(?x, ?y));
};
reward =
[sum_{?x: x_pos, ?y: y_pos} [ COST_CUTOUT*cut-out(?x, ?y) ]]
+ [sum_{?x: x_pos, ?y: y_pos} [ COST_PUTOUT*put-out(?x, ?y) ]]
// Modification: if a target is out-of-fuel, it was burnt so still penalize (since it could not have been cut-out)
+ [sum_{?x: x_pos, ?y: y_pos} [ PENALTY_TARGET_BURN*[ (burning(?x, ?y) | out-of-fuel(?x, ?y)) ^ TARGET(?x, ?y) ]]]
+ [sum_{?x: x_pos, ?y: y_pos} [ PENALTY_NONTARGET_BURN*[ burning(?x, ?y) ^ ~TARGET(?x, ?y) ]]];
}