Skip to content

Commit

Permalink
Merge pull request #77 from CurricularAnalytics/development
Browse files Browse the repository at this point in the history
Merge Development
  • Loading branch information
haydenfree authored Jan 16, 2020
2 parents aa1d934 + a236c87 commit d7fddac
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 229 deletions.
16 changes: 8 additions & 8 deletions docs/src/degreeplans.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ In order to be considered *minimally feasible*, a degree plan $P$ for a curricul

The Curricular Analytics Toolbox also allows you to create customized degree plans according to various user-specifed criteria. These features make use of the [JuMP](https://github.com/JuliaOpt/JuMP.jl) domain-specific language for specifying optimization problems in Julia, and calls the [Gurobi](https://www.gurobi.com) solver in order to solve the optimzaton problems. In order to use these features you must first install JuMP and Gurobi. For installation instructions see [Additional Requirements](@ref) in the Installation section.

A brief overview of how we have structured the degree plan creation process as an optimzation problem is provided next. Assume a curriculum consisting of $n$ courses is organized over $m$ terms. The degree plan creation process involves a partitioning of the $n$ courses in a curriculum into $m$ disjoint sets. Thus, we can represent a degree plan an $n \times m$ binary-valued assignment matrix $x$, where
A brief overview of how we have structured the degree plan creation process as an optimization problem is provided next. Assume a curriculum consisting of $n$ courses is organized over $m$ terms. The degree plan creation process involves a partitioning of the $n$ courses in a curriculum into $m$ disjoint sets. Thus, we can represent a degree plan an $n \times m$ binary-valued assignment matrix $x$, where

```math
x_{ij} = \left\{
Expand All @@ -37,7 +37,7 @@ The two conditions required for a degree plan to be minimally feasible can be ex
\mbox{Constraint 1:} \ \ \sum_{j=1}^m x_{ij} = 1, \ \ \ \ i = 1 \ldots n.
```

If we let $T_i$ denote the term that course $i$ is assigned to, i.e., $T_i = j \iff x_{ij} = 1$, then the second condition, which requires the assignment to satisfy all requisites, yeilds three constraints depending upon the requisite type. That is, if course $a$ is a *requisite* for course $b$, then:
If we let $T_i$ denote the term that course $i$ is assigned to, i.e., $T_i = j \iff x_{ij} = 1$, then the second condition, which requires the assignment to satisfy all requisites, yields three constraints depending upon the requisite type. That is, if course $a$ is a *requisite* for course $b$, then:

```math
\mbox{Constraint 2 (prerequisite):} \ \ T_a \ < \ T_b, \\
Expand All @@ -51,7 +51,7 @@ Note that $T_i$ can be obtained from the assignment matrix using:
T_i = \sum_{j=1}^m j \cdot x_{ij}.
```

In order to guide the optimzation algorithms towards reasonable soluations, additional constraints are required. In partciular, it is necessarey to specify the maximum number of terms you would like the degree plan to contain, denoted $\alpha$, as well as the minimum and maximum number of credit hours allowed in each term, denoted $\beta$ and $\gamma$ respectively. If we let $c_i$ denote the number of credit hours associated with course $i$, and $\theta_j$ the number of credit hours in term $j$, then
In order to guide the optimization algorithms towards reasonable solutions, additional constraints are required. In particular, it is necessarFurthemore, this toolbox supports a multi-objectivey to specify the maximum number of terms you would like the degree plan to contain, denoted $\alpha$, as well as the minimum and maximum number of credit hours allowed in each term, denoted $\beta$ and $\gamma$ respectively. If we let $c_i$ denote the number of credit hours associated with course $i$, and $\theta_j$ the number of credit hours in term $j$, then

```math
\theta_j = \sum_{i=1}^n c_i \cdot x_{ij}, \ \ \ \ j = 1, \ldots, m,
Expand All @@ -67,15 +67,15 @@ In order to guide the optimzation algorithms towards reasonable soluations, addi

### Objective Functions

A number of different objective functions have been defined for use in creating degree plans optimized around particular criteria. Furthemore, this toolbox supports a multi-objetive framework, allowing more than one of these objective functions to be simultaneously applied while creating degree plans.
A number of different objective functions have been defined for use in creating degree plans optimized around particular criteria. Furthermore, this toolbox supports a multi-objective framework, allowing more than one of these objective functions to be simultaneously applied while creating degree plans.

For a single objective function $f(x)$, the optimzation problem can be stated as:
```math
\min f(x), \\
\mbox{subject to: Constraints} \ \ 1-7.
```

For multiple objective functions $f_1(x), f(_2(x), \ldots$ the mulit-objective optimzation problem can be stated as:
For multiple objective functions $f_1(x), f(_2(x), \ldots$ the multi-objective optimization problem can be stated as:
```math
\min \left\{ f_1(x), \ f_2(x), \ldots \right\}, \\
\mbox{subject to: Constraints} \ \ 1-7.
Expand Down Expand Up @@ -107,16 +107,16 @@ Let $-1 \leq \aleph_{ij} \leq 1$ denote the toxic impact that course $i$ has on
f(x) = \min \left( \sum_{t=1}^m \sum_{i=1}^n \sum_{j=1}^n \aleph_{ij} \cdot x_{it} \cdot x_{jt} \right).
```

The `optimize_plan` function in the toolbox implements the optimziation problems described above.
The `optimize_plan` function in the toolbox implements the optimization problems described above.

```julia
optimize_plan(c::Curriculum, term_count::Int, min_cpt::Int, max_cpt::Int, obj_order::Array{String, 1}; diff_max_cpt::Array{UInt, 1}, fix_courses::Dict, consec_courses::Dict, term_range::Dict, prior_courses::Array{Term, 1})
```

Using the curriculum `c` supplied as input, returns a degree plan optimzed according to the various
Using the curriculum `c` supplied as input, returns a degree plan optimized according to the various
optimization criteria that have been specified as well as the objective functions that have been selected.

If an optimzied plan cannot be constructed (i.e., the constraints are such that an optimal solution is infeasible),
If an optimized plan cannot be constructed (i.e., the constraints are such that an optimal solution is infeasible),
`nothing` is returned, and the solver returns a message indicating that the problems is infeasible. In these cases,
you may wish to experiment with the constraint values.

Expand Down
4 changes: 2 additions & 2 deletions src/CurricularAnalytics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export Degree, AA, AS, AAS, BA, BS, System, semester, quarter, Requisite, pre, c
reachable_from_subgraph, reachable_to, reachable_to_subgraph, reach, reach_subgraph, isvalid_curriculum,
extraneous_requisites, blocking_factor, delay_factor, centrality, complexity, dead_ends, courses_from_vertices,
compare_curricula, similarity, homology, isvalid_degree_plan, print_plan, visualize, metric_histogram, metric_boxplot,
show_homology, basic_metrics, basic_statistics, read_csv, create_degree_plan, bin_packing, bin_packing2, find_min_terms,
show_homology, basic_metrics, basic_statistics, read_csv, create_degree_plan, bin_filling, find_min_terms,
add_lo_requisite!, update_plan, write_csv, find_min_terms, balance_terms, requisite_distance, balance_terms_opt,
find_min_terms_opt, read_Opt_Config, optimize_plan, json_to_julia, julia_to_json, init_opt

Expand Down Expand Up @@ -371,7 +371,7 @@ function complexity(c::Curriculum)
return c.metrics["complexity"] = curric_complexity, course_complexity
end

# Find all fo the longest paths in a curriculum.
# Find all the longest paths in a curriculum.
"""
longest_paths(c::Curriculum)
Expand Down
2 changes: 1 addition & 1 deletion src/DataTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ mutable struct Course
this.metrics = Dict{String, Any}()
this.metadata = Dict{String, Any}()
this.learning_outcomes = learning_outcomes
this.vertex_id = Dict{Int, Int}()
this.vertex_id = Dict{Int, Int}() # curriculum id -> vertex id
return this
end
end
Expand Down
20 changes: 10 additions & 10 deletions src/DegreePlanAnalytics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,28 +76,28 @@ function basic_metrics(plan::DegreePlan)

# Degree plan metrics based upon the distance between requsites and the classes that require them.
"""
requisite_distance(DegreePlan, course::Int)
requisite_distance(DegreePlan, course::Course)
For a given degree plan `plan` and course `course`, this function computes the total distance between `course` and
each of its requisites.
For a given degree plan `plan` and target course `course`, this function computes the total distance between `course` and
all of its requisites.
# Arguments
Required:
- `plan::DegreePlan` : a valid degree plan (see [Degree Plans](@ref)).
- `course::Int` : the vertex ID of a course in the curriclum graph `plan.curriculum.graph`.
- `course::Course` : the target course.
The distance between a course a requisite is given by the number of terms that separate
the course from its requisite in the degree plan. If we let ``T_i^p`` denote the term in degree plan ``p`` that course ``c_i``
appears in, then for a degree plan with underlying curriculum graph ``G_c = (V,E)``, the requisite distance for course
``c_i`` in degree plan ``p``, denoted ``rd_{v_i}^p``, is:
The distance between a target course and one of its requisites is given by the number of terms that separate the target
course from the particular requisite in the degree plan. To compute the requisite distance, we sum this distance over all
requisites. That is, if let ``T_i^p`` denote the term in degree plan ``p`` that course ``c_i`` appears in, then for a
degree plan with underlying curriculum graph ``G_c = (V,E)``, the requisite distance for course ``c_i`` in degree plan ``p``,
denoted ``rd_{v_i}^p``, is:
```math
rd_{v_i}^p = \\sum{(v_i, v_j) \\in E} (T_i - T_j).
```
In general, it is desirable for a course and its requisites to appear as close together as possible in a degree plan.
The requisite distance metric computed by this function will be stored in the associated `Course` data object.
The requisite distance metric computed by this function is stored in the associated `Course` data object.
"""
function requisite_distance(plan::DegreePlan, course::Course)
distance = 0
Expand Down
Loading

0 comments on commit d7fddac

Please sign in to comment.