Skip to content

CadetCareerProblem โ€“ Generated Data Corrections Methods

fix_generated_data(printing=None)

Fix Generated Data Instance.

This method prepares a synthetic cadetโ€“AFSC instance by populating missing data, generating preferences, updating qualification matrices, and ensuring valid preference and utility structures. It is intended only for generated (synthetic) data instances and should not be used on real-world datasets.

Parameters

printing : bool, optional If True, print progress updates at each step. Defaults to the instance's self.printing.

Notes

This function assumes that no valid AFSC preference or utility data currently exists. It will:

  • Convert utility values to preference ranks
  • Generate fake AFSC preference lists
  • Create separate rated datasets for each SOC
  • Update the qualification matrix based on preferences
  • Remove ineligible cadets from all matrices
  • Normalize preference matrices to eliminate ranking gaps
  • Force first-choice utilities to 100%
  • Convert AFSC preferences to percentile scores
  • Update cadet preference columns
  • Create new utility matrices from cadet columns
  • Rebuild rated eligibility lists
  • Generate random value parameters
  • Perform a final parameter sanity check
Source code in afccp/main.py
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
def fix_generated_data(self, printing=None):
    """
    Fix Generated Data Instance.

    This method prepares a synthetic cadetโ€“AFSC instance by populating missing data, generating preferences,
    updating qualification matrices, and ensuring valid preference and utility structures. It is intended
    **only** for generated (synthetic) data instances and should not be used on real-world datasets.

    Parameters
    ----------
    printing : bool, optional
        If True, print progress updates at each step. Defaults to the instance's `self.printing`.

    Notes
    -----
    This function assumes that no valid AFSC preference or utility data currently exists. It will:

    - Convert utility values to preference ranks
    - Generate fake AFSC preference lists
    - Create separate rated datasets for each SOC
    - Update the qualification matrix based on preferences
    - Remove ineligible cadets from all matrices
    - Normalize preference matrices to eliminate ranking gaps
    - Force first-choice utilities to 100%
    - Convert AFSC preferences to percentile scores
    - Update cadet preference columns
    - Create new utility matrices from cadet columns
    - Rebuild rated eligibility lists
    - Generate random value parameters
    - Perform a final parameter sanity check
    """

    if printing is None:
        printing = self.printing

    # Get "c_pref_matrix" from cadet preferences
    self.convert_utilities_to_preferences(cadets_as_well=True)

    # Generate AFSC preferences for this problem instance
    self.generate_fake_afsc_preferences()

    # Generate rated data (Separate datasets for each SOC)
    self.generate_rated_data()

    # Update qualification matrix from AFSC preferences (treating CFM lists as "gospel" except for Rated/USSF)
    self.update_qualification_matrix_from_afsc_preferences()

    # Removes ineligible cadets from all 3 matrices: degree qualifications, cadet preferences, AFSC preferences
    self.remove_ineligible_choices(printing=printing)

    # Take the preferences dictionaries and update the matrices from them (using cadet/AFSC indices)
    self.update_preference_matrices()  # 1, 2, 4, 6, 7 -> 1, 2, 3, 4, 5 (preference lists need to omit gaps)

    # Force first choice utility values to be 100%
    self.update_first_choice_cadet_utility_to_one(printing=printing)

    # Convert AFSC preferences to percentiles (0 to 1)
    self.convert_afsc_preferences_to_percentiles()  # 1, 2, 3, 4, 5 -> 1, 0.8, 0.6, 0.4, 0.2

    # The "cadet columns" are located in Cadets.csv and contain the utilities/preferences in order of preference
    self.update_cadet_columns_from_matrices()  # We haven't touched "c_preferences" and "c_utilities" until now

    # Update utility matrix from columns (and create final cadet utility matrix)
    self.update_cadet_utility_matrices_from_cadets_data(printing=printing)

    # Modify rated eligibility by SOC, removing cadets that are on "Rated Cadets" list...
    self.modify_rated_cadet_lists_based_on_eligibility(printing=printing)  # ...but not eligible for any rated AFSC

    # Generate fake (random) set of value parameters
    self.generate_random_value_parameters()

    # Sanity check the parameters to make sure it all looks good! (No issues found.)
    self.parameter_sanity_check()

convert_utilities_to_preferences(cadets_as_well=False)

Converts utility matrices to ordinal preference matrices.

This method transforms the continuous utility values stored in the model's parameters into discrete ordinal preferences used in assignment algorithms. By default, it converts only the AFSC utility matrix (afsc_utility) into the a_pref_matrix. If specified, it also converts the cadet utility matrix (cadet_utility) into the c_pref_matrix.

Parameters

cadets_as_well : bool, optional If True, both cadet and AFSC utility matrices are converted to preference matrices. If False (default), only AFSC utilities are converted.

Returns

None This method updates the instanceโ€™s parameters attribute in-place.

Note

  • The resulting a_pref_matrix ranks cadets for each AFSC from most to least preferred.
  • The optional c_pref_matrix ranks AFSCs for each cadet, using 1-based indexing.
Examples
# Convert only AFSC utility matrix
instance.convert_utilities_to_preferences()

# Convert both AFSC and cadet utility matrices
instance.convert_utilities_to_preferences(cadets_as_well=True)
See Also
Source code in afccp/main.py
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
def convert_utilities_to_preferences(self, cadets_as_well=False):
    """
    Converts utility matrices to ordinal preference matrices.

    This method transforms the continuous utility values stored in the model's parameters
    into discrete ordinal preferences used in assignment algorithms. By default, it converts
    only the AFSC utility matrix (`afsc_utility`) into the `a_pref_matrix`. If specified, it
    also converts the cadet utility matrix (`cadet_utility`) into the `c_pref_matrix`.

    Parameters
    ----------
    cadets_as_well : bool, optional
        If `True`, both cadet and AFSC utility matrices are converted to preference matrices.
        If `False` (default), only AFSC utilities are converted.

    Returns
    -------
    None
        This method updates the instanceโ€™s `parameters` attribute in-place.

    !!! note
        - The resulting `a_pref_matrix` ranks cadets for each AFSC from most to least preferred.
        - The optional `c_pref_matrix` ranks AFSCs for each cadet, using 1-based indexing.

    Examples
    --------
    ```python
    # Convert only AFSC utility matrix
    instance.convert_utilities_to_preferences()

    # Convert both AFSC and cadet utility matrices
    instance.convert_utilities_to_preferences(cadets_as_well=True)
    ```

    See Also
    --------
    - [`convert_utility_matrices_preferences`](../../../../afccp/reference/data/preferences/#data.preferences.convert_utility_matrices_preferences):
      Underlying function that performs the actual matrix transformation.
    - [`parameter_sets_additions`](../../../../afccp/reference/data/adjustments/#data.adjustments.parameter_sets_additions):
      Updates parameter subsets after modifying the preference matrices.
    """

    # Rest of your method code here
    self.parameters = afccp.data.preferences.convert_utility_matrices_preferences(self.parameters,
                                                                                  cadets_as_well)
    self.parameters = afccp.data.adjustments.parameter_sets_additions(self.parameters)

generate_fake_afsc_preferences(fix_cadet_eligibility=False)

Generate Simulated AFSC Preferences using certain known parameters.

This method simulates AFSC (Air Force Specialty Code) preferences for cadets using weighted scores derived from merit, tier objectives, and other cadet/AFSC attributes. It supports scenarios where cadet eligibility should be strictly enforced before generating preferences.

Parameters

fix_cadet_eligibility : bool, optional If True, cadet preferences are regenerated to strictly respect eligibility constraints. If False (default), original eligibility is used as-is when computing preferences.

Returns

None Updates the parameters attribute of the current CadetCareerProblem instance with:

  • afsc_utility: N x M utility matrix
  • a_pref_matrix: AFSCs' ranked preferences over cadets
  • c_pref_matrix: Cadets' ranked preferences over AFSCs
  • afsc_preferences, cadet_preferences: Index-based ranking dictionaries
See Also
Source code in afccp/main.py
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
def generate_fake_afsc_preferences(self, fix_cadet_eligibility=False):
    """
    Generate Simulated AFSC Preferences using certain known parameters.

    This method simulates AFSC (Air Force Specialty Code) preferences for cadets using weighted scores
    derived from merit, tier objectives, and other cadet/AFSC attributes. It supports scenarios where cadet eligibility
    should be strictly enforced before generating preferences.

    Parameters
    ----------
    fix_cadet_eligibility : bool, optional
    If True, cadet preferences are regenerated to strictly respect eligibility constraints.
    If False (default), original eligibility is used as-is when computing preferences.

    Returns
    -------
    None
    Updates the `parameters` attribute of the current `CadetCareerProblem` instance with:

    - `afsc_utility`: N x M utility matrix
    - `a_pref_matrix`: AFSCs' ranked preferences over cadets
    - `c_pref_matrix`: Cadets' ranked preferences over AFSCs
    - `afsc_preferences`, `cadet_preferences`: Index-based ranking dictionaries

    See Also
    --------
    - [`generate_fake_afsc_preferences`](../../../../afccp/reference/data/preferences/#data.preferences.generate_fake_afsc_preferences):
      Underlying utility simulation and preference generation function.
    - [`parameter_sets_additions`](../../../../afccp/reference/data/adjustments/#data.adjustments.parameter_sets_additions):
      Updates parameter subsets and mappings based on the new preference structure.
    """
    self.parameters = afccp.data.preferences.generate_fake_afsc_preferences(
        self.parameters, self.value_parameters, fix_cadet_eligibility=fix_cadet_eligibility)
    self.parameters = afccp.data.adjustments.parameter_sets_additions(self.parameters)

generate_rated_data()

Generate Simulated Rated Board Data for USAFA and ROTC Cadets.

This method generates Order of Merit (OM) data and interest levels for cadets eligible for Rated AFSCs (e.g., Pilot, CSO, RPA, ABM) for each commissioning source. It only generates data if it does not already exist.

Rated OM and interest data (legacy ROTC Rated Board Data) is essential (not the interest matrix, though) for modeling the Air Forceโ€™s Rated board process, allowing simulation and evaluation of Rated cadet assignments.

Returns

None The method updates the internal self.parameters dictionary in-place by adding:

  • ROTC-rated interest matrix (rr_interest_matrix)
  • OM matrices for each Source of Commission (SOC), e.g., ur_om_matrix, rr_om_matrix
Examples
instance = CadetCareerProblem("Random", N=30, M=6, P=6)
instance.generate_rated_data()  # Adds Rated OM and interest matrices
See Also
Source code in afccp/main.py
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
def generate_rated_data(self):
    """
    Generate Simulated Rated Board Data for USAFA and ROTC Cadets.

    This method generates Order of Merit (OM) data and interest levels for cadets eligible for Rated AFSCs
    (e.g., Pilot, CSO, RPA, ABM) for each commissioning source. It only generates data if it does not already exist.

    Rated OM and interest data (legacy ROTC Rated Board Data) is essential (not the interest matrix, though) for
    modeling the Air Forceโ€™s Rated board process, allowing simulation and evaluation of Rated cadet assignments.

    Returns
    -------
    None
    The method updates the internal `self.parameters` dictionary in-place by adding:

    - ROTC-rated interest matrix (`rr_interest_matrix`)
    - OM matrices for each Source of Commission (SOC), e.g., `ur_om_matrix`, `rr_om_matrix`

    Examples
    --------
    ```python
    instance = CadetCareerProblem("Random", N=30, M=6, P=6)
    instance.generate_rated_data()  # Adds Rated OM and interest matrices
    ```

    See Also
    --------
    - [`generate_rated_data`](../../../../afccp/reference/data/preferences/#data.preferences.generate_rated_data):
      Underlying function that constructs the rated OM and interest matrices.
    - [`parameter_sets_additions`](../../../../afccp/reference/data/adjustments/#data.adjustments.parameter_sets_additions):
      Updates relevant parameter sets derived from new OM data.
    """

    # Generate Rated Data
    self.parameters = afccp.data.preferences.generate_rated_data(self.parameters)
    self.parameters = afccp.data.adjustments.parameter_sets_additions(self.parameters)

generate_random_value_parameters(num_breakpoints=24, vp_weight=100, printing=None)

Generate Random Value Parameters for Assignment Problem.

This method initializes a new set of randomly generated value-focused thinking (VFT) parameters for a cadet-AFSC matching problem instance. The generated value parameters include random weights, value functions, and AFSC/cadet preferences, making this method ideal for testing and experimentation.

Parameters:

num_breakpoints (int, optional): Number of breakpoints to use for linearizing value functions. Defaults to 24. vp_weight (int, optional): Scalar weight applied to the overall value parameter set. Defaults to 100. printing (bool, optional): Whether to print progress information. Defaults to the instance attribute.

Returns:

dict: A complete dictionary of randomly generated value parameters for the instance.

Example:
# Generate and assign a new set of value parameters using 30 breakpoints
vp = instance.generate_random_value_parameters(num_breakpoints=30, vp_weight=80)
See Also:
Source code in afccp/main.py
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
def generate_random_value_parameters(self, num_breakpoints=24, vp_weight=100, printing=None):
    """
    Generate Random Value Parameters for Assignment Problem.

    This method initializes a new set of randomly generated value-focused thinking (VFT) parameters
    for a cadet-AFSC matching problem instance. The generated value parameters include random weights,
    value functions, and AFSC/cadet preferences, making this method ideal for testing and experimentation.

    Parameters:
    --------
    num_breakpoints (int, optional): Number of breakpoints to use for linearizing value functions.
        Defaults to 24.
    vp_weight (int, optional): Scalar weight applied to the overall value parameter set.
        Defaults to 100.
    printing (bool, optional): Whether to print progress information. Defaults to the instance attribute.

    Returns:
    --------
    dict: A complete dictionary of randomly generated value parameters for the instance.

    Example:
    --------
    ```python
    # Generate and assign a new set of value parameters using 30 breakpoints
    vp = instance.generate_random_value_parameters(num_breakpoints=30, vp_weight=80)
    ```

    See Also:
    --------
    - [`generate_random_value_parameters`](../../../../afccp/reference/data/generation/#data.generation.generate_random_value_parameters):
      Initializes a value parameter dictionary from scratch with random objective weights and targets.
    - [`condense_value_functions`](../../../../afccp/reference/data/values/#data.values.condense_value_functions):
      Cleans and optimizes value function definitions by removing unused entries.
    - [`value_parameters_sets_additions`](../../../../afccp/reference/data/values/#data.values.value_parameters_sets_additions):
      Adds structured sets and subsets to the value parameter dictionary for optimization logic.
    """

    # Print Statement
    if printing is None:
        printing = self.printing

    # Generate random set of value parameters
    value_parameters = afccp.data.generation.generate_random_value_parameters(
        self.parameters, num_breakpoints=num_breakpoints)

    # Module shorthand
    afccp_vp = afccp.data.values

    # "Condense" the value functions by removing unnecessary zeros
    value_parameters = afccp_vp.condense_value_functions(self.parameters, value_parameters)

    # Add indexed sets and subsets of AFSCs and AFSC objectives
    value_parameters = afccp_vp.value_parameters_sets_additions(self.parameters, value_parameters)

    # Weight of the value parameters as a whole
    value_parameters['vp_weight'] = vp_weight

    # Set value parameters to instance attribute
    if self.mdl_p["set_to_instance"]:
        self.value_parameters = value_parameters

    # Save new set of value parameters to dictionary
    if self.mdl_p["add_to_dict"]:
        self._save_new_value_parameters_to_dict(value_parameters)

    return value_parameters

generate_example_castle_value_curves(num_breakpoints: int = 10)

Generate and Store Example CASTLE Value Curves.

This method creates example concave value curves for each CASTLE-level AFSC and stores the breakpoint information in the instance's parameters dictionary under the key 'castle_q'.

These curves represent marginal utility of inventory over a range of potential quantities for use in CASTLE sustainment simulations.

Parameters:

num_breakpoints (int, optional): Number of breakpoints to use for the concave curve. Defaults to 10.

Returns:

None

Example:
instance.generate_example_castle_value_curves(num_breakpoints=15)
q = instance.parameters['castle_q']
See Also:
Source code in afccp/main.py
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
def generate_example_castle_value_curves(self, num_breakpoints: int = 10):
    """
    Generate and Store Example CASTLE Value Curves.

    This method creates example concave value curves for each CASTLE-level AFSC and stores the breakpoint
    information in the instance's `parameters` dictionary under the key `'castle_q'`.

    These curves represent marginal utility of inventory over a range of potential quantities for use in
    CASTLE sustainment simulations.

    Parameters:
    --------
    num_breakpoints (int, optional): Number of breakpoints to use for the concave curve.
        Defaults to 10.

    Returns:
    --------
    None

    Example:
    --------
    ```python
    instance.generate_example_castle_value_curves(num_breakpoints=15)
    q = instance.parameters['castle_q']
    ```

    See Also:
    --------
    - [`generate_realistic_castle_value_curves`](../../../../afccp/reference/data/generation/#data.generation.generate_realistic_castle_value_curves):
      Generates concave breakpoint utility functions for CASTLE AFSCs.
    """

    # Create "q" dictionary containing breakpoint information for castle value curves
    q = afccp.data.generation.generate_realistic_castle_value_curves(
        self.parameters, num_breakpoints=num_breakpoints)

    # Save "q" dictionary for castle to parameters
    self.parameters['castle_q'] = q