frex.models.constraints package
Submodules
frex.models.constraints.attribute_constraint module
- class frex.models.constraints.attribute_constraint.AttributeConstraint(attribute_name: str, constraint_type: frex.models.constraints.constraint_type.ConstraintType, constraint_value: int)[source]
Bases:
tuple
A namedtuple to store Constraints that will be applied in a constraint solver.
Create new instance of AttributeConstraint(attribute_name, constraint_type, constraint_value)
- attribute_name: str
Alias for field number 0
- constraint_type: frex.models.constraints.constraint_type.ConstraintType
Alias for field number 1
- constraint_value: int
Alias for field number 2
frex.models.constraints.constraint_solution module
- class frex.models.constraints.constraint_solution.ConstraintSolution(uri: rdflib.term.URIRef, overall_score: int, overall_attribute_values: Dict[str, int], solution_section_sets: Tuple[frex.models.constraints.constraint_solution_section_set.ConstraintSolutionSectionSet, ...], items: Tuple[frex.models.candidate.Candidate, ...])[source]
Bases:
frex.models.domain_object.DomainObject
A constraint solution is the combination of multiple sections, each containing some number of items, that adhere to some number of constraints while maximizing the total score of all items contained in the solution.
- classmethod from_dict(kvs: Optional[Union[dict, list, str, int, float, bool]], *, infer_missing=False) dataclasses_json.api.A
- classmethod from_json(s: Union[str, bytes, bytearray], *, parse_float=None, parse_int=None, parse_constant=None, infer_missing=False, **kw) dataclasses_json.api.A
- items: Tuple[frex.models.candidate.Candidate, ...]
- overall_attribute_values: Dict[str, int]
- overall_score: int
- classmethod schema(*, infer_missing: bool = False, only=None, exclude=(), many: bool = False, context=None, load_only=(), dump_only=(), partial: bool = False, unknown=None) dataclasses_json.mm.SchemaF[dataclasses_json.mm.A]
- solution_section_sets: Tuple[frex.models.constraints.constraint_solution_section_set.ConstraintSolutionSectionSet, ...]
- to_dict(encode_json=False) Dict[str, Optional[Union[dict, list, str, int, float, bool]]]
- to_json(*, skipkeys: bool = False, ensure_ascii: bool = True, check_circular: bool = True, allow_nan: bool = True, indent: Optional[Union[int, str]] = None, separators: Optional[Tuple[str, str]] = None, default: Optional[Callable] = None, sort_keys: bool = False, **kw) str
frex.models.constraints.constraint_solution_section module
- class frex.models.constraints.constraint_solution_section.ConstraintSolutionSection(section_object: frex.models.domain_object.DomainObject, section_score: int, section_attribute_values: Dict[str, int], section_candidates: Tuple[frex.models.candidate.Candidate, ...])[source]
Bases:
object
A portion of a constraint solution consisting of a group of sections. Exactly what a section represents may differ based on the application, but an example of a section is a ‘day’ within a solution that is generated for a week-long meal plan. The constraint section solution then consists of a number of such sections along with information about which of the final item choices are assigned to each section. Sections have their own score, and store the candidates assigned to this section. Values of attributes of the domain objects are also stored, if they were relevant to solving constraints.
- classmethod from_dict(kvs: Optional[Union[dict, list, str, int, float, bool]], *, infer_missing=False) dataclasses_json.api.A
- classmethod from_json(s: Union[str, bytes, bytearray], *, parse_float=None, parse_int=None, parse_constant=None, infer_missing=False, **kw) dataclasses_json.api.A
- classmethod schema(*, infer_missing: bool = False, only=None, exclude=(), many: bool = False, context=None, load_only=(), dump_only=(), partial: bool = False, unknown=None) dataclasses_json.mm.SchemaF[dataclasses_json.mm.A]
- section_attribute_values: Dict[str, int]
- section_candidates: Tuple[frex.models.candidate.Candidate, ...]
- section_object: frex.models.domain_object.DomainObject
- section_score: int
- to_dict(encode_json=False) Dict[str, Optional[Union[dict, list, str, int, float, bool]]]
- to_json(*, skipkeys: bool = False, ensure_ascii: bool = True, check_circular: bool = True, allow_nan: bool = True, indent: Optional[Union[int, str]] = None, separators: Optional[Tuple[str, str]] = None, default: Optional[Callable] = None, sort_keys: bool = False, **kw) str
frex.models.constraints.constraint_solution_section_set module
- class frex.models.constraints.constraint_solution_section_set.ConstraintSolutionSectionSet(sections: Tuple[frex.models.constraints.constraint_solution_section.ConstraintSolutionSection, ...])[source]
Bases:
object
A grouping of constraint solution sections that was solved by the constraint solution.
- classmethod from_dict(kvs: Optional[Union[dict, list, str, int, float, bool]], *, infer_missing=False) dataclasses_json.api.A
- classmethod from_json(s: Union[str, bytes, bytearray], *, parse_float=None, parse_int=None, parse_constant=None, infer_missing=False, **kw) dataclasses_json.api.A
- classmethod schema(*, infer_missing: bool = False, only=None, exclude=(), many: bool = False, context=None, load_only=(), dump_only=(), partial: bool = False, unknown=None) dataclasses_json.mm.SchemaF[dataclasses_json.mm.A]
- sections: Tuple[frex.models.constraints.constraint_solution_section.ConstraintSolutionSection, ...]
- to_dict(encode_json=False) Dict[str, Optional[Union[dict, list, str, int, float, bool]]]
- to_json(*, skipkeys: bool = False, ensure_ascii: bool = True, check_circular: bool = True, allow_nan: bool = True, indent: Optional[Union[int, str]] = None, separators: Optional[Tuple[str, str]] = None, default: Optional[Callable] = None, sort_keys: bool = False, **kw) str
frex.models.constraints.constraint_type module
- class frex.models.constraints.constraint_type.ConstraintType(value)[source]
Bases:
enum.Enum
ConstraintType is a callable Enum for use in the integer programming solver.
- static AM1(x, y)
- static EQ(x, y)
- static EX1(x, y)
- static GEQ(x, y)
- static GRTR(x, y)
- static LEQ(x, y)
- static LESS(x, y)
- static NEQ(x, y)
- __call__(*args)[source]
Either returns an existing member, or creates a new enum class.
This method is used both when an enum class is given a value to match to an enumeration member (i.e. Color(3)) and for the functional API (i.e. Color = Enum(‘Color’, names=’RED GREEN BLUE’)).
When used for the functional API:
value will be the name of the new class.
names should be either a string of white-space/comma delimited names (values will start at start), or an iterator/mapping of name, value pairs.
module should be set to the module this class is being created in; if it is not set, an attempt to find that module will be made, but if it fails the class will not be picklable.
qualname should be set to the actual location this class can be found at in its module; by default it is set to the global scope. If this is not correct, unpickling will fail in some circumstances.
type, if set, will be mixed in as the first base class.
frex.models.constraints.item_constraint module
- class frex.models.constraints.item_constraint.ItemConstraint(constraint_type: frex.models.constraints.constraint_type.ConstraintType, item_a_uri: rdflib.term.URIRef, item_b_uri: rdflib.term.URIRef)[source]
Bases:
tuple
A namedtuple to store Constraints over how items are assigned/selected.
Create new instance of ItemConstraint(constraint_type, item_a_uri, item_b_uri)
- constraint_type: frex.models.constraints.constraint_type.ConstraintType
Alias for field number 0
- item_a_uri: rdflib.term.URIRef
Alias for field number 1
- item_b_uri: rdflib.term.URIRef
Alias for field number 2
frex.models.constraints.section_assignment_constraint module
- class frex.models.constraints.section_assignment_constraint.SectionAssignmentConstraint(constraint_type: frex.models.constraints.constraint_type.ConstraintType, section_a_uri: rdflib.term.URIRef, section_b_uri: rdflib.term.URIRef)[source]
Bases:
tuple
A namedtuple to store Constraints over how items are assigned to sections. The constraints will be applied to all items in each section. e.g., if the constraint type if EQ, then for section_a and section_b, all item assignments must be equal.
Create new instance of SectionAssignmentConstraint(constraint_type, section_a_uri, section_b_uri)
- constraint_type: frex.models.constraints.constraint_type.ConstraintType
Alias for field number 0
- section_a_uri: rdflib.term.URIRef
Alias for field number 1
- section_b_uri: rdflib.term.URIRef
Alias for field number 2
frex.models.constraints.section_constraint_hierarchy module
- class frex.models.constraints.section_constraint_hierarchy.SectionConstraintHierarchy(root_uri: rdflib.term.URIRef, dependency_and: Optional[Tuple[frex.models.constraints.section_constraint_hierarchy.SectionConstraintHierarchy, ...]] = (), dependency_or: Optional[Tuple[frex.models.constraints.section_constraint_hierarchy.SectionConstraintHierarchy, ...]] = ())[source]
Bases:
object
The SectionConstraintHierarchy is used to capture a hierarchy of relations among sections. This primarily is used to capture logical AND / OR operators among relations. This currently only correctly supports hierarchies of sections as trees (?)
- dependency_and: Optional[Tuple[frex.models.constraints.section_constraint_hierarchy.SectionConstraintHierarchy, ...]] = ()
- dependency_or: Optional[Tuple[frex.models.constraints.section_constraint_hierarchy.SectionConstraintHierarchy, ...]] = ()
- classmethod from_dict(kvs: Optional[Union[dict, list, str, int, float, bool]], *, infer_missing=False) dataclasses_json.api.A
- classmethod from_json(s: Union[str, bytes, bytearray], *, parse_float=None, parse_int=None, parse_constant=None, infer_missing=False, **kw) dataclasses_json.api.A
- root_uri: rdflib.term.URIRef
- classmethod schema(*, infer_missing: bool = False, only=None, exclude=(), many: bool = False, context=None, load_only=(), dump_only=(), partial: bool = False, unknown=None) dataclasses_json.mm.SchemaF[dataclasses_json.mm.A]
- to_dict(encode_json=False) Dict[str, Optional[Union[dict, list, str, int, float, bool]]]
- to_json(*, skipkeys: bool = False, ensure_ascii: bool = True, check_circular: bool = True, allow_nan: bool = True, indent: Optional[Union[int, str]] = None, separators: Optional[Tuple[str, str]] = None, default: Optional[Callable] = None, sort_keys: bool = False, **kw) str
frex.models.constraints.section_set_constraint module
- class frex.models.constraints.section_set_constraint.SectionSetConstraint(*, scaling: int = 1)[source]
Bases:
object
A solution section represents some grouping of the items chosen for the solution, used to group together the items to fulfill some goal. An example of the use solution sections would be for a course recommender system. One solution section would handle how to assign various courses to fulfill graduation requirements. A second solution section would be used to choose which courses are assigned to which semester.
- add_hierarchical_section_constraint(*, hierarchy: frex.models.constraints.section_constraint_hierarchy.SectionConstraintHierarchy)[source]
Add constraints based on a hierarchy of logical AND/OR operators that should be enforced. if a hierarchy is set like this, all sections by default will use the hierarchy to determine whether or not to enforce its various constraints.
- Parameters
hierarchy – A SectionConstraintHierarchy of sections that will be applied for the solution sections.
- Returns
- add_item_ordering_dependence_constraint(*, independent_uri: rdflib.term.URIRef, dependent_uri: rdflib.term.URIRef, constraint_type: frex.models.constraints.constraint_type.ConstraintType)[source]
Add a constraint that a particular item is assigned to a section before/after/together with another item. This type of constraint assumes that the section ordering is meaningful and correlate to some temporal sequence (e.g., each section is a day in the week, ordered Mon/Tues/…, and a constraint is added to make sure the ‘order’ of item a comes before item b). The selection of the item specified by the dependent_uri requires this constraint to be satisfied, while the independent_uri item can be successfully selected even if the dependent_uri is not selected.
- Parameters
independent_uri – The URI of the item that can be selected independently of this constraint
dependent_uri – The URI of the item whose ordering must adhere to this constraint
constraint_type – The type of constraint to apply to the ordering
- Returns
- add_required_item_assignment(*, section_uri: rdflib.term.URIRef, item_uri: rdflib.term.URIRef)[source]
Add a requirement that the given item is assigned to the target section.
- Parameters
section_uri – The URI of the section to assign the item to
item_uri – The URI of the item that must be assigned to the target section
- Returns
- add_section_assignment_constraint(*, section_a_uri: rdflib.term.URIRef, section_b_uri: rdflib.term.URIRef, constraint_type: frex.models.constraints.constraint_type.ConstraintType)[source]
Add constraints on how items are assigned to different sections. The main use of this type of constraint is to apply constraints on whether items can be assigned to multiple sections, or forcing items to be applied to multiple sections. Some uses include enforcing that item assignments for different graduation requirements are unique (i.e., for requirements that both can be fulfilled by some class but the class can’t count for both).
- Parameters
section_a_uri – The URI of a section to apply this constraint
section_b_uri – Another URI of a section to apply this constraint
constraint_type – The type of constraint to be applying on the items assigned to section A and B.
- Returns
- add_section_constraint(*, attribute_name: str, constraint_type: frex.models.constraints.constraint_type.ConstraintType, constraint_value: int, target_uri: Optional[rdflib.term.URIRef] = None)[source]
Add a constraint to be applied to each section solution. E.g., a constraint on the cost of all items chosen within each given section. If no target uri is specified, we assume all sections have this constraint
- Parameters
attribute_name – The domain_object’s attribute to apply the constraint to
constraint_type – The type of constraint - i.e. ==, <=, or >=
constraint_value – The value to constraint the solution to
target_uri – The target URI of the section that this constraint should apply to. If none, all sections
will have the constraint applied. :return: self, with a new Constraint added to the section_constraints list
- add_section_count_constraint(*, min_count: Optional[int] = None, max_count: Optional[int] = None, exact_count: Optional[int] = None, target_uri: Optional[rdflib.term.URIRef] = None)[source]
Set constraints on the number of items assigned to sections. If no target URI is specified, it is assumed that the count constraint applies to all sections. This function will check for an exact count first, and if it exists it will only create a constraint for making sure the number of items assigned to the target section is equal to that quantity. Otherwise, both a min and max count of items assigned to a section can be specified.
- Parameters
min_count – The minimum number of items to assign to the target section
max_count – The maximum number of items to assign to the target section
exact_count – An exact number of items to assign to the target section
target_uri – The uri of the section to apply this constraint to, if any
- Returns
- allow_invalid_assignment_to_section(*, target_uri: rdflib.term.URIRef)[source]
Indicate that a section is allowed to have ‘invalid’ items (i.e., items that would return False by the section’s assignment filter) assigned to it. This can increase the time it takes to find a solution, but can allow uses like having a ‘restriction’ between sections.
- Parameters
target_uri – The URI of the section to allow invalid assignments for
- Returns
- property attributes_of_interest
Getter for the attributes of interest property :return:
- get_solution_assignments(*, solver: ortools.sat.python.cp_model.CpSolver, items: Tuple[frex.models.candidate.Candidate, ...]) frex.models.constraints.constraint_solution_section_set.ConstraintSolutionSectionSet [source]
Using a solver that has already solved for the overall constraints, create a constraint solution section set that captures all the sections, the items assigned to each section, and the scores/attribute values associated with those assignments
- Parameters
solver – A constraint solver, which has already been run to obtain a solution
items – A tuple of candidates that was used by the solver to derive the solution
- Returns
A ConstraintSolutionSectionSet object capturing the relevant information for this set of sections
- set_section_assignment_filter(*, target_uri: rdflib.term.URIRef, filter_function: Callable[[...], bool])[source]
Add a filter for sections to determine whether or not each item is allowed to be assigned to it. If no filter is specified for a given section, we assume all items are allowed to be assigned.
- Parameters
target_uri – The URI of the section to set this filter for
filter_function – The filter function that takes anything as input and produces a bool indicating whether
that item is allowed to be assigned to the target section :return:
- set_sections(*, sections: Tuple[frex.models.domain_object.DomainObject, ...])[source]
Set the sections that items will be assigned to. For example, in a course recommender system, these sections could be a tuple of semesters (assign each class to a semester) or a tuple of graduation requirements (assign each class to one or more requirement).
- Parameters
sections – A tuple of domain objects that concrete instances of ‘sections’ to which items should be assigned
- Returns
- setup_section_constraints(*, items: Tuple[frex.models.candidate.Candidate, ...], item_selection: Tuple[ortools.sat.python.cp_model.IntVar, ...], model: <module 'ortools.sat.python.cp_model' from 'c:\\users\\sola\\pycharmprojects\\frex_code\\venv\\lib\\site-packages\\ortools\\sat\\python\\cp_model.py'>)[source]
Convert the various constraints applied to this solution section into a matrix form to feed into the constraint solver.
- Parameters
items – The candidate items being used to assign into the solution
item_selection – Variables manipulated by the solver to determine whether or not each item is chosen
model – The constraint solver model
- Returns