use crate::commodity::CommodityID;
use crate::id::define_id_type;
use crate::process::{FlowDirection, Process};
use crate::region::RegionID;
use crate::units::Dimensionless;
use indexmap::{IndexMap, IndexSet};
use serde_string_enum::DeserializeLabeledStringEnum;
use std::collections::HashMap;
use std::rc::Rc;
define_id_type! {AgentID}
pub type AgentMap = IndexMap<AgentID, Agent>;
pub type AgentCommodityPortionsMap = HashMap<(CommodityID, u32), Dimensionless>;
pub type AgentSearchSpaceMap = HashMap<(CommodityID, u32), Rc<Vec<Rc<Process>>>>;
pub type AgentObjectiveMap = HashMap<u32, ObjectiveType>;
#[derive(Debug, Clone, PartialEq)]
pub struct Agent {
pub id: AgentID,
pub description: String,
pub commodity_portions: AgentCommodityPortionsMap,
pub search_space: AgentSearchSpaceMap,
pub decision_rule: DecisionRule,
pub regions: IndexSet<RegionID>,
pub objectives: AgentObjectiveMap,
}
impl Agent {
pub fn iter_possible_producers_of<'a>(
&'a self,
region_id: &RegionID,
commodity_id: &'a CommodityID,
year: u32,
) -> impl Iterator<Item = &'a Rc<Process>> + use<'a> {
let flows_key = (region_id.clone(), year);
self.search_space[&(commodity_id.clone(), year)]
.iter()
.filter(move |process| {
process.flows[&flows_key][commodity_id].direction() == FlowDirection::Output
})
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum DecisionRule {
Single,
Weighted,
Lexicographical {
tolerance: f64,
},
}
#[derive(Debug, Clone, Copy, PartialEq, DeserializeLabeledStringEnum)]
pub enum ObjectiveType {
#[string = "lcox"]
LevelisedCostOfX,
#[string = "npv"]
NetPresentValue,
}