Skip to content

Store agent objectives as a map #543

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 8 additions & 18 deletions src/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use crate::id::{define_id_getter, define_id_type};
use crate::process::ProcessID;
use crate::region::RegionID;
use indexmap::IndexMap;
use serde::Deserialize;
use serde_string_enum::DeserializeLabeledStringEnum;
use std::collections::HashMap;
use std::collections::HashSet;
Expand All @@ -22,6 +21,12 @@ pub type AgentCostLimitsMap = HashMap<u32, AgentCostLimits>;
/// A map of commodity portions for an agent, keyed by commodity and year
pub type AgentCommodityPortionsMap = HashMap<(CommodityID, u32), f64>;

/// A map of objectives for an agent, keyed by commodity and year.
///
/// NB: As we currently only support the "single" decision rule, the only parameter we need for
/// objectives is the type.
pub type AgentObjectiveMap = HashMap<u32, ObjectiveType>;

/// An agent in the simulation
#[derive(Debug, Clone, PartialEq)]
pub struct Agent {
Expand All @@ -40,7 +45,7 @@ pub struct Agent {
/// The regions in which this agent operates.
pub regions: HashSet<RegionID>,
/// The agent's objectives.
pub objectives: Vec<AgentObjective>,
pub objectives: AgentObjectiveMap,
}
define_id_getter! {Agent, AgentID}

Expand Down Expand Up @@ -78,23 +83,8 @@ pub enum DecisionRule {
},
}

/// An objective for an agent with associated parameters
#[derive(Debug, Clone, Deserialize, PartialEq)]
pub struct AgentObjective {
/// Unique agent id identifying the agent this objective belongs to
pub agent_id: AgentID,
/// The year the objective is relevant for
pub year: u32,
/// Acronym identifying the objective (e.g. LCOX)
pub objective_type: ObjectiveType,
/// For the weighted sum decision rule, the set of weights to apply to each objective.
pub decision_weight: Option<f64>,
/// For the lexico decision rule, the order in which to consider objectives.
pub decision_lexico_order: Option<u32>,
}

/// The type of objective for the agent
#[derive(Debug, Clone, PartialEq, DeserializeLabeledStringEnum)]
#[derive(Debug, Clone, Copy, PartialEq, DeserializeLabeledStringEnum)]
pub enum ObjectiveType {
/// Average cost of one unit of output commodity over its lifetime
#[string = "lcox"]
Expand Down
12 changes: 9 additions & 3 deletions src/input/agent.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//! Code for reading in agent-related data from CSV files.
use super::*;
use crate::agent::{
Agent, AgentCommodityPortionsMap, AgentCostLimitsMap, AgentID, AgentMap, DecisionRule,
Agent, AgentCommodityPortionsMap, AgentCostLimitsMap, AgentID, AgentMap, AgentObjectiveMap,
DecisionRule,
};
use crate::commodity::CommodityMap;
use crate::process::ProcessMap;
Expand Down Expand Up @@ -138,6 +139,11 @@ where
invalid_rule => bail!("Invalid decision rule: {}", invalid_rule),
};

ensure!(
decision_rule == DecisionRule::Single,
"Currently only the \"single\" decision rule is supported"
);

let agent = Agent {
id: AgentID(agent_raw.id.into()),
description: agent_raw.description,
Expand All @@ -146,7 +152,7 @@ where
decision_rule,
cost_limits: AgentCostLimitsMap::new(),
regions,
objectives: Vec::new(),
objectives: AgentObjectiveMap::new(),
};

ensure!(
Expand Down Expand Up @@ -183,7 +189,7 @@ mod tests {
decision_rule: DecisionRule::Single,
cost_limits: AgentCostLimitsMap::new(),
regions: HashSet::from(["GBR".into()]),
objectives: Vec::new(),
objectives: AgentObjectiveMap::new(),
};
let expected = AgentMap::from_iter(iter::once(("agent".into(), agent_out)));
let actual = read_agents_file_from_iter(iter::once(agent), &region_ids).unwrap();
Expand Down
4 changes: 2 additions & 2 deletions src/input/agent/commodity_portion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ fn validate_agent_commodity_portions(
#[cfg(test)]
mod tests {
use super::*;
use crate::agent::{Agent, AgentCostLimitsMap, DecisionRule};
use crate::agent::{Agent, AgentCostLimitsMap, AgentObjectiveMap, DecisionRule};
use crate::commodity::{Commodity, CommodityCostMap, CommodityID, CommodityType, DemandMap};
use crate::time_slice::TimeSliceLevel;
use std::rc::Rc;
Expand All @@ -213,7 +213,7 @@ mod tests {
decision_rule: DecisionRule::Single,
cost_limits: AgentCostLimitsMap::new(),
regions: region_ids.clone(),
objectives: Vec::new(),
objectives: AgentObjectiveMap::new(),
},
)]);
let mut commodities = IndexMap::from([(
Expand Down
Loading