00001
00002
00003
00004
00005 #include <obox.h>
00006 #include <stdio.h>
00007 #include <osys.h>
00008
00009
00010 #include <ALL.H>
00011 #include <OGAMESET.H>
00012 #include <OMATH.H>
00013 #include <OSTR.h>
00014 #include <OLINALG.H>
00015
00016
00017 #include <GAMEDEF.H>
00018 #include <OPSCHOOL.H>
00019 #include <OPEERSCH.H>
00020 #include <OSCHLRES.H>
00021 #include <ODEPTRES.H>
00022 #include <OFINANCE.H>
00023 #include <OINFO.H>
00024 #include <ODEPT.H>
00025 #include <OSTUDENT.H>
00026 #include <OLIBTECH.H>
00027 #include <OATHLETI.H>
00028 #include <OSTUOFF.H>
00029 #include "OEnroll.h"
00030
00031
00032
00033 #define PREFERENCE_DB "STUPREF"
00034 #define APP_YIELD_DB "APPYIELD"
00035 #define PREFERENCE_DB2 "STUPREF2"
00036 #define TALENT_DB "STTALENT"
00037
00038
00039
00040 #if(GAME_VERSION>=200)
00041 short TRADIT_COUNT = 0;
00042
00043 #define MAX_TRADITION_COUNT 5
00044 #define MAX_NONTRA_COUNT 5
00045 #define MAX_MASTER_COUNT 3
00046 #define MAX_DOCTOR_COUNT 3
00047
00048 const RECORD_SEPARATOR_LEN = 2;
00049 static char *RECORD_SEPARATOR = "\r\n";
00050 const FIELD_SEPARATOR_LEN = 1;
00051 static char *FIELD_SEPARATOR = "\t";
00052
00053 static char *export_num(int value) {
00054 static char num_str[20];
00055 return itoa( value, num_str, 10 );
00056 }
00057
00058 static char *export_num(double value) {
00059 static char num_str[20];
00060 return gcvt( value, 7, num_str );
00061 }
00062
00063 static char *export_percent(double value) {
00064 static char num_str[20];
00065 return gcvt( value*0.01, 7, num_str );
00066 }
00067
00068 #define WRITE_FIELD_SEPARATOR(f) f->file_write(FIELD_SEPARATOR, FIELD_SEPARATOR_LEN)
00069 #define WRITE_STR_FIELD(f,s) { f->file_write(s, strlen(s)); }
00070 #define WRITE_NUM_FIELD(f,n) { char *s=export_num(n); f->file_write(s, strlen(s)); }
00071 #define WRITE_PERCENT_FIELD(f,n) { char *s=export_percent(n); f->file_write(s, strlen(s)); }
00072 #define WRITE_RECORD_SEPARATOR(f) f->file_write(RECORD_SEPARATOR, RECORD_SEPARATOR_LEN)
00073 #endif
00074
00075
00076 const float EnrollRes::apps_latency[MAX_STUDENT_LEVEL] = { .4f, .4f, .5f, .6f, .7f };
00077
00078
00079 const float EnrollRes::yield_latency[MAX_STUDENT_LEVEL] = {
00080 .9f, .5f, .5f, .5f, .5f
00081 };
00082
00083
00084 const float EnrollRes::aidMinMultipliers[PRIORITY_LEVEL_COUNT] = {
00085 1, 1.05f, 1.10f
00086 };
00087
00088
00089 EnrollRes::EnrollRes() {
00090 }
00091
00092
00093 static bool is_minority_group(char group) {
00094 return group == MINORITY_MALE || group == MINORITY_FEMALE;
00095 }
00096
00097 static bool is_male_group(char group) {
00098 return group == MINORITY_MALE || group == NONMINORITY_MALE;
00099 }
00100
00101
00104
00105 if ( fraction > 0 && fraction < fraction_merit_top - .005f )
00106 fraction = fraction_merit_top + .005f;
00107 else if ( fraction > 1 + .005f - fraction_merit_top )
00108 fraction = (1 - .005f - fraction_merit_top) ;
00109 }
00110
00111
00112
00113
00116
00117 memset(this, 0, sizeof(EnrollRes));
00118
00119 load_db_student_pref();
00120 load_db_student_pref2();
00121 load_db_app_yield();
00122 load_db_student_talent();
00123
00124 #if(GAME_VERSION>=200)
00125 distance_learner_acceptance = 1;
00126 #endif
00127
00128
00129 s_lower_bound = 0.5f;
00130 s_upper_bound = 1.5f;
00131 s_slope = 5.0f;
00132
00133 chance_avg = 1.0f;
00134 chance_sd = 1.0f;
00135
00136 fraction_merit_top = 0.025f;
00137 }
00138
00139
00140
00141
00143
00144 }
00145
00146
00147
00148
00152
00153 PreferenceRec *prefRec;
00154 Database *dbPreference = game_set.open_db(PREFERENCE_DB);
00155
00156 int db_count = (short) dbPreference->rec_count();
00157
00158 err_when( db_count != PREFERECNE_COUNT * 2 );
00159
00160
00161
00162
00163
00164
00165 memset( preference_array, 0, sizeof(preference_array));
00166
00167 for( int i=0 ; i<db_count ; i++ ) {
00168
00169 prefRec = (PreferenceRec*) dbPreference->read(i+1);
00170
00171 for( int j=0 ; j<INSTITU_SEGMENT_COUNT; j++ ) {
00172 preference_array[i/2][j].average = (float) m.atof( prefRec->value[j], 9 );
00173 preference_array[i/2][j].weight = (float) m.atof( prefRec->weight, 9 );
00174 }
00175
00176 i++;
00177
00178 prefRec = (PreferenceRec*) dbPreference->read(i+1);
00179
00180 for( j=0 ; j<INSTITU_SEGMENT_COUNT; j++ )
00181 preference_array[i/2][j].deviation = (float) m.atof( prefRec->value[j], 9 );
00182
00183 preference_array[i/2][j].tmp_fuzzy_value = 0.0f;
00184 }
00185 }
00186
00187
00188
00189
00193
00194 PreferenceRec2 *prefRec;
00195 Database *dbPreference = game_set.open_db(PREFERENCE_DB2);
00196 String tmpStr;
00197
00198 int db_count = (short) dbPreference->rec_count();
00199
00200 err_when( db_count != PREFERECNE_COUNT2 * (SCHOOL_CONTROL_COUNT + MAX_STUDENT_LEVEL - 1) );
00201
00202
00203 err_when( NON_MINORITY != 0 );
00204 err_when( PUBLIC != 1 || PRIVATE != 0 );
00205
00206
00207
00208 memset( preference_array2, 0, sizeof(preference_array2));
00209
00210
00211
00212 int i, j, arrSL;
00213 char control = PRIVATE;
00214
00215 for( i=0; i<PREFERECNE_COUNT2*SCHOOL_CONTROL_COUNT; i++ ) {
00216 if ( i >= PREFERECNE_COUNT2 ) {
00217 control = PUBLIC;
00218 j = i - PREFERECNE_COUNT2;
00219 }
00220 else {
00221 j = i;
00222 }
00223
00224 prefRec = (PreferenceRec2*) dbPreference->read(i+1);
00225
00226 m.rtrim_fld(tmpStr, prefRec->weight[0], 9);
00227 if ( strcmp(tmpStr, "") != 0 )
00228 preference_array2[control][NON_MINORITY][j].apps_ratio = (float) m.atof( prefRec->weight[0], 9 );
00229 else
00230 preference_array2[control][NON_MINORITY][j].apps_ratio = -1.0f;
00231
00232 m.rtrim_fld(tmpStr, prefRec->weight[1], 9);
00233 if ( strcmp(tmpStr, "") != 0 )
00234 preference_array2[control][MINORITY][j].apps_ratio = (float) m.atof( prefRec->weight[1], 9 );
00235 else
00236 preference_array2[control][MINORITY][j].apps_ratio = -1.0f;
00237
00238 m.rtrim_fld(tmpStr, prefRec->weight[2], 9);
00239 if ( strcmp(tmpStr, "") != 0 )
00240 preference_array2[control][NON_MINORITY][j].yield_rate = (float) m.atof( prefRec->weight[2], 9 );
00241 else
00242 preference_array2[control][NON_MINORITY][j].yield_rate = -1.0f;
00243
00244 m.rtrim_fld(tmpStr, prefRec->weight[3], 9);
00245 if ( strcmp(tmpStr, "") != 0 )
00246 preference_array2[control][MINORITY][j].yield_rate = (float) m.atof( prefRec->weight[3], 9 );
00247 else
00248 preference_array2[control][MINORITY][j].yield_rate = -1.0f;
00249
00250 }
00251
00252
00253
00254 for( i=0, arrSL=-1; i<PREFERECNE_COUNT2 * (MAX_STUDENT_LEVEL - 1); i++ ) {
00255 j = i % PREFERECNE_COUNT2;
00256
00257 if ( j==0 ) {
00258 arrSL++; err_when(arrSL == MAX_STUDENT_LEVEL-1);
00259 }
00260
00261 prefRec = (PreferenceRec2*) dbPreference->read(PREFERECNE_COUNT2*SCHOOL_CONTROL_COUNT + i+1);
00262
00263
00264 #if(GAME_VERSION>=200)
00265 if ( i == 63 ) {
00266 preference_array2_sls[arrSL][PRIVATE][NON_MINORITY][0] = 0.1;
00267 preference_array2_sls[arrSL][PRIVATE][MINORITY][0] = 0.1;
00268 preference_array2_sls[arrSL][PUBLIC][NON_MINORITY][0] = 0.1;
00269 preference_array2_sls[arrSL][PUBLIC][MINORITY][0] = 0.1;
00270 }
00271 else
00272 if ( i == 75 ) {
00273 preference_array2_sls[arrSL][PRIVATE][NON_MINORITY][12] = -1.0f;
00274 preference_array2_sls[arrSL][PRIVATE][MINORITY][12] = -1.0f;
00275 preference_array2_sls[arrSL][PUBLIC][NON_MINORITY][12] = -1.0f;
00276 preference_array2_sls[arrSL][PUBLIC][MINORITY][12] = -1.0f;
00277 }
00278 else
00279 if ( i == 78 ) {
00280 preference_array2_sls[arrSL][PRIVATE][NON_MINORITY][15] = 0.5;
00281 preference_array2_sls[arrSL][PRIVATE][MINORITY][15] = 0.5;
00282 preference_array2_sls[arrSL][PUBLIC][NON_MINORITY][15] = -1.0f;
00283 preference_array2_sls[arrSL][PUBLIC][MINORITY][15] = -1.0f;
00284 }
00285 else
00286 if ( i == 79 ) {
00287 preference_array2_sls[arrSL][PRIVATE][NON_MINORITY][16] = -1.0f;
00288 preference_array2_sls[arrSL][PRIVATE][MINORITY][16] = -1.0f;
00289 preference_array2_sls[arrSL][PUBLIC][NON_MINORITY][16] = 0.3;
00290 preference_array2_sls[arrSL][PUBLIC][MINORITY][16] = 0.3;
00291 }
00292 else {
00293 #endif
00294 m.rtrim_fld(tmpStr, prefRec->weight[0], 9);
00295 preference_array2_sls[arrSL][PRIVATE][NON_MINORITY][j]
00296 = ( strcmp(tmpStr, "") != 0 ) ? (float) m.atof( prefRec->weight[0], 9 ) : -1.0f;
00297
00298 m.rtrim_fld(tmpStr, prefRec->weight[1], 9);
00299 preference_array2_sls[arrSL][PRIVATE][MINORITY][j]
00300 = ( strcmp(tmpStr, "") != 0 ) ? (float) m.atof( prefRec->weight[1], 9 ) : -1.0f;
00301
00302 m.rtrim_fld(tmpStr, prefRec->weight[2], 9);
00303 preference_array2_sls[arrSL][PUBLIC][NON_MINORITY][j]
00304 = ( strcmp(tmpStr, "") != 0 ) ? (float) m.atof( prefRec->weight[2], 9 ) : -1.0f;
00305
00306 m.rtrim_fld(tmpStr, prefRec->weight[3], 9);
00307 preference_array2_sls[arrSL][PUBLIC][MINORITY][j]
00308 = ( strcmp(tmpStr, "") != 0 ) ? (float) m.atof( prefRec->weight[3], 9 ) : -1.0f;
00309 #if(GAME_VERSION>=200)
00310 }
00311 #endif
00312 }
00313 #if(GAME_VERSION>=200)
00314
00315
00316 preference_array2_sls[3][PRIVATE][NON_MINORITY][21] = 0.4;
00317 preference_array2_sls[3][PRIVATE][MINORITY][21] = 0.4;
00318 preference_array2_sls[3][PUBLIC][NON_MINORITY][21] = 0.6;
00319 preference_array2_sls[3][PUBLIC][MINORITY][21] = 0.6;
00320 #endif
00321 }
00322
00323
00324
00325
00329
00330 AppYieldRec *appRec;
00331 Database *dbAppYield = game_set.open_db(APP_YIELD_DB);
00332 int varOffset, stuSubSeg, stuSeg, iSeg, i=0;
00333
00334 int db_count = (short) dbAppYield->rec_count();
00335
00336 err_when( db_count != STUDENT_SEGMENT_COUNT * STUDENT_SUBSEGMENT_COUNT * APP_YIELD_VAR_COUNT);
00337
00338
00339
00340 memset( app_yield_array, 0, sizeof(app_yield_array));
00341
00342 for ( varOffset=0; varOffset<APP_YIELD_VAR_COUNT; varOffset++ )
00343 for ( stuSubSeg=0; stuSubSeg<STUDENT_SUBSEGMENT_COUNT; stuSubSeg++ )
00344 for ( stuSeg=0; stuSeg<STUDENT_SEGMENT_COUNT; stuSeg++ ) {
00345 appRec = (AppYieldRec*) dbAppYield->read(i+1);
00346 i++;
00347 for ( iSeg=0; iSeg<INSTITU_SEGMENT_COUNT; iSeg++ ) {
00348 app_yield_array[stuSubSeg][stuSeg][iSeg][varOffset]
00349 = (short) m.atoi( appRec->count[iSeg], 9 );
00350 err_when(app_yield_array[stuSubSeg][stuSeg][iSeg][varOffset] < 0);
00351 }
00352 }
00353
00354 #ifdef DEBUG_
00355 debug_msg("----- begin enroll: app_yield -----");
00356
00357 for ( stuSubSeg=0; stuSubSeg<STUDENT_SUBSEGMENT_COUNT; stuSubSeg++ )
00358 for ( stuSeg=0; stuSeg<STUDENT_SEGMENT_COUNT; stuSeg++ ) {
00359 char str[100] = "";
00360 for ( iSeg=0; iSeg<INSTITU_SEGMENT_COUNT; iSeg++ ) {
00361 sprintf(str, "%s, %d", str, app_yield_array[stuSubSeg][stuSeg][iSeg].apps);
00362 }
00363 debug_msg(str);
00364 }
00365 debug_msg("----- end enroll: app_yield -----");
00366 #endif
00367 }
00368
00369
00370
00371
00375
00376
00377 static float income_growth[STUDENT_SUBSEGMENT_COUNT][STUDENT_SEGMENT_COUNT];
00378 static float income_growth_last2[STUDENT_SUBSEGMENT_COUNT][STUDENT_SEGMENT_COUNT];
00379
00380 void EnrollRes::load_db_student_talent() {
00381 #define TALENT_VAR_PROPERTIES_COUNT 3 // mean, sd, count
00382
00383 TalentRec *talentRec;
00384 Database *dbPreference = game_set.open_db(TALENT_DB);
00385
00386 int db_count = (short) dbPreference->rec_count();
00387
00388 err_when( db_count != STUDENT_SUBSEGMENT_COUNT * TALENT_INCOME_VAR_COUNT * TALENT_VAR_PROPERTIES_COUNT);
00389
00390
00391
00392 memset( talent_array, 0, sizeof(talent_array));
00393
00394 int var, subSeg, seg, i=1;
00395
00396 for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ )
00397 for ( var=0; var<TALENT_INCOME_VAR_COUNT; var++ ) {
00398
00399 talentRec = (TalentRec*) dbPreference->read(i++);
00400
00401 for ( seg=0; seg<STUDENT_SEGMENT_COUNT; seg++ ) {
00402 talent_array[subSeg][seg][var].average
00403 = (float) m.atof( talentRec->seg[seg], 9 );
00404 }
00405
00406
00407 talentRec = (TalentRec*) dbPreference->read(i++);
00408
00409 for ( seg=0; seg<STUDENT_SEGMENT_COUNT; seg++ ) {
00410 talent_array[subSeg][seg][var].variance
00411 = (float) m.atof( talentRec->seg[seg], 9 );
00412 }
00413
00414
00415
00416 i++;
00417 }
00418
00419
00420
00421
00422
00423
00424 const float INCOME_UPDATE = math.safe_pow(1.04f, 10);
00425
00426 for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
00427 for ( var=0; var<TALENT_VAR_COUNT; var++ )
00428 for ( seg=0; seg<STUDENT_SEGMENT_COUNT; seg++ ) {
00429 talent_array[subSeg][seg][var].variance
00430 = math.safe_pow(talent_array[subSeg][seg][var].variance, 2);
00431 }
00432
00433 for ( seg=0; seg<STUDENT_SEGMENT_COUNT; seg++ ) {
00434 talent_array[subSeg][seg][INCOME].average
00435 *= INCOME_UPDATE;
00436 talent_array[subSeg][seg][INCOME].variance
00437
00438 = math.safe_pow(talent_array[subSeg][seg][var].variance / 10, 2);
00439 }
00440 }
00441
00442
00443
00444
00445
00446 for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
00447 for ( seg=0; seg<STUDENT_SEGMENT_COUNT; seg++ ) {
00448 income_growth[subSeg][seg] = math.get_random_snd(0.015f, PSCH_SD(.0025f));
00449 income_growth_last2[subSeg][seg] = 0;
00450 }
00451 }
00452 }
00453
00454
00455
00456
00460
00461
00462
00463
00464 int subSeg, seg;
00465 float inflationRate = (float) finance.inflation_rate / 100.0f;
00466
00467 for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
00468 for ( seg=0; seg<STUDENT_SEGMENT_COUNT; seg++ ) {
00469 float lastValue = income_growth[subSeg][seg];
00470
00471 income_growth[subSeg][seg] = math.time_variation(lastValue, income_growth_last2[subSeg][seg], 0.9908f, -0.6314f, 0.003202690f);
00472 income_growth_last2[subSeg][seg] = lastValue;
00473
00474 talent_array[subSeg][seg][INCOME].average *= (1+inflationRate+income_growth[subSeg][seg]);
00475 }
00476 }
00477 }
00478
00479
00480
00481
00488
00489
00490
00491
00492
00493
00494 PeerSchool* player = school_res.player_peer_school;
00495 float prefArray[PREFERECNE_COUNT];
00496 int i, j;
00497
00498 for (j=0, i=0; j<PREFERECNE_COUNT; j++, i++) {
00499 if ( j == 10 )
00500 i++;
00501
00502 prefArray[j] = player->pref_vars_array[i];
00503 }
00504
00505 err_when( PREFERECNE_COUNT != 20 );
00506
00507
00508 Preference *prefPtr;
00509
00510 for (j=0; j<PREFERECNE_COUNT; j++)
00511 for (i=0; i<INSTITU_SEGMENT_COUNT; i++) {
00512 prefPtr = (enroll_res.preference_array[j]) + i;
00513
00514 prefPtr->tmp_fuzzy_value = (float) exp(-math.safe_pow(( math.safe_divide((prefPtr->average-prefArray[j]), prefPtr->deviation) ), 2));
00515 }
00516
00517
00518 bool isPlayerSchoolPublic = player_school.is_public();
00519 float tmpSumOfSum = 0.0f;
00520
00521 for (i=0; i<INSTITU_SEGMENT_COUNT; i++) {
00522 float tmpSum = 0.0f;
00523
00524 for (j=0; j<NON_FINANCIAL_PREFERECNE_COUNT; j++) {
00525 prefPtr = (enroll_res.preference_array[j]) + i;
00526
00527 tmpSum += prefPtr->tmp_fuzzy_value * prefPtr->weight;
00528
00529 }
00530
00531 err_when(tmpSum==0);
00532
00533 for (j=NON_FINANCIAL_PREFERECNE_COUNT; j<PREFERECNE_COUNT; j+=2) {
00534 prefPtr = (enroll_res.preference_array[j]) + i;
00535
00536 if ( isPlayerSchoolPublic )
00537 prefPtr++;
00538
00539 tmpSum += prefPtr->tmp_fuzzy_value * prefPtr->weight;
00540 }
00541 pref_weight_array[i] = tmpSum;
00542 tmpSumOfSum += tmpSum;
00543
00544 err_when(tmpSumOfSum==0);
00545 }
00546
00547
00548 for (i=0; i<INSTITU_SEGMENT_COUNT; i++)
00549 pref_weight_array[i] /= tmpSumOfSum;
00550 }
00551
00552
00553
00554
00565
00566 float appYield[APP_YIELD_VAR_COUNT], totalMatrics=0;
00567 int varOffset, stuSubSeg, stuSeg, iSeg, i=0;
00568
00569
00570
00571
00572 for ( stuSubSeg=0; stuSubSeg<STUDENT_SUBSEGMENT_COUNT; stuSubSeg++ )
00573 for ( stuSeg=0; stuSeg<STUDENT_SEGMENT_COUNT; stuSeg++ ) {
00574 memset(appYield, 0, sizeof(appYield));
00575 for ( varOffset=0; varOffset<APP_YIELD_VAR_COUNT; varOffset++ ) {
00576
00577 for ( iSeg=0; iSeg<INSTITU_SEGMENT_COUNT; iSeg++ ) {
00578 appYield[varOffset] += (enroll_res.app_yield_array[stuSubSeg][stuSeg][iSeg][varOffset] * pref_weight_array[iSeg]);
00579
00580 err_when(appYield[varOffset] < 0);
00581 }
00582 }
00583
00584 err_when( appYield[MATRICS] < 0.000001f || appYield[OFFERS] < 0.000001f );
00585
00586 err_when( appYield[MATRICS] > appYield[OFFERS] );
00587
00588
00589 enroll_data_sl1[stuSubSeg][stuSeg].apps_ratio = float(appYield[APPS]) / appYield[MATRICS];
00590 enroll_data_sl1[stuSubSeg][stuSeg].yield_rate = float(appYield[MATRICS]) / appYield[OFFERS];
00591 enroll_data_sl1[stuSubSeg][stuSeg].fraction_matrics = appYield[MATRICS];
00592
00593 totalMatrics += appYield[MATRICS];
00594 }
00595
00596
00597 err_when(totalMatrics <= 0);
00598
00599 for ( stuSubSeg=0; stuSubSeg<STUDENT_SUBSEGMENT_COUNT; stuSubSeg++ )
00600 for ( stuSeg=0; stuSeg<STUDENT_SEGMENT_COUNT; stuSeg++ ) {
00601 enroll_data_sl1[stuSubSeg][stuSeg].fraction_matrics /= totalMatrics;
00602 }
00603 }
00604
00605
00606
00607
00608
00609 void EnrollRes::set_app_yield(float appMultipler, float yieldMultiplier) {
00610 int stuSubSeg, stuSeg;
00611
00612 for ( stuSubSeg=0; stuSubSeg<STUDENT_SUBSEGMENT_COUNT; stuSubSeg++ )
00613 for ( stuSeg=0; stuSeg<STUDENT_SEGMENT_COUNT; stuSeg++ ) {
00614 enroll_data_sl1[stuSubSeg][stuSeg].apps_ratio *= appMultipler;
00615 enroll_data_sl1[stuSubSeg][stuSeg].yield_rate *= yieldMultiplier;
00616 }
00617 }
00618
00619
00620
00621
00622 float PeerSchool::pref_vars_average_array[PREFERECNE_COUNT2];
00623 float PeerSchool::pref_vars_average_array_last[PREFERECNE_COUNT2];
00624
00625
00633
00634 if ( this != school_res.player_peer_school ) {
00635 calc_student_pref_vars_array_peer();
00636 return;
00637 }
00638
00639 memcpy( pref_vars_array_last, pref_vars_array, sizeof(pref_vars_array) );
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650 int studentEnrollCount[MAX_STUDENT_LEVEL];
00651 int i;
00652
00653 for ( i=0; i<MAX_STUDENT_LEVEL; i++ ) {
00654 studentEnrollCount[i] = enroll_res.student_count[i];
00655 percent_female_sl[i] = (char) enroll_res.student_female_percent[i];
00656 percent_minority_sl[i] = (char) enroll_res.student_minority_percent[i];
00657 }
00658
00659 pref_vars_array[0] = prestige;
00660
00661 pref_vars_array[1] = (float) athletics_office.ncaa_level_value;
00662 pref_vars_array[2] = float(student_life_staff_salaries+student_life_other_expense)/(full_time_undergrad+part_time_undergrad);
00663 pref_vars_array[3] = percent_traditional_ug_in_residence_halls / 100.0f;
00664 pref_vars_array[4] = percent_get_bacc_in_5_year / 100.0f;
00665
00666 pref_vars_array[5] = enroll_res.applications_rate[UG_TRADITION];
00667 pref_vars_array[6] = enroll_res.cur_yield_rate[UG_TRADITION];
00668 pref_vars_array[7] = float(studentEnrollCount[1]) / float(studentEnrollCount[0]+studentEnrollCount[1]);
00669
00670 float tmpCount = 0;
00671
00672 pref_vars_array[8] = float(studentEnrollCount[0]+studentEnrollCount[1]) / enroll_res.total_student_count;
00673 pref_vars_array[9] = float(studentEnrollCount[4]) / enroll_res.total_student_count;
00674
00675
00676 pref_vars_array[10] = float(percent_instate_freshmen) / 100;
00677
00678 for (i = 0, tmpCount = 0; i<MAX_STUDENT_LEVEL; i++)
00679 tmpCount += float(studentEnrollCount[i]) * percent_female_sl[i] / 100;
00680
00681 pref_vars_array[11] = float(tmpCount) / enroll_res.total_student_count;
00682
00683 for (i = 0, tmpCount = 0; i<MAX_STUDENT_LEVEL; i++)
00684 tmpCount += studentEnrollCount[i] * percent_minority_sl[i] / 100;
00685
00686 pref_vars_array[12] = float(tmpCount) / enroll_res.total_student_count;
00687 pref_vars_array[13] = doc_time_to_degree;
00688 pref_vars_array[14] = sponsored_research_rating;
00689 pref_vars_array[15] = (float) finance.tuition_rate;
00690
00691 pref_vars_array[16] = pref_vars_array[15];
00692 pref_vars_array[17] = percent_ug_students_on_aid / 100.0f;
00693 pref_vars_array[18] = pref_vars_array[17];
00694 pref_vars_array[19] = institutional_aid_per_fte;
00695 pref_vars_array[20] = institutional_aid_per_fte;
00696
00697 err_when( PREFERECNE_COUNT2 != 21 );
00698
00699 for (i=0; i<PREFERECNE_COUNT2; i++)
00700 err_when( pref_vars_array[i] < 0 );
00701
00702 }
00703
00704
00705
00706
00716
00717 memcpy( pref_vars_array_last, pref_vars_array, sizeof(pref_vars_array) );
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727 pref_vars_array[0] = prestige;
00728 pref_vars_array[1] = (float) athletics_office.ncaa_level_value;
00729 #if(GAME_VERSION>=200)
00730 pref_vars_array[2] = math.safe_divide( float(student_life_staff_salaries+student_life_other_expense), (float)full_time_undergrad+part_time_undergrad );
00731 #else
00732 pref_vars_array[2] = float(student_life_staff_salaries+student_life_other_expense)/(full_time_undergrad+part_time_undergrad);
00733 #endif
00734 pref_vars_array[3] = percent_traditional_ug_in_residence_halls / 100.0f;
00735 pref_vars_array[4] = percent_get_bacc_in_5_year / 100.0f;
00736
00737 pref_vars_array[5] = ug_applications_rate;
00738 pref_vars_array[6] = ug_yield_rate / 100.0f;
00739 #if(GAME_VERSION>=200)
00740 pref_vars_array[7] = math.safe_divide( (float)part_time_undergrad, (float)full_time_undergrad+part_time_undergrad );
00741 #else
00742 pref_vars_array[7] = part_time_undergrad/float(full_time_undergrad+part_time_undergrad);
00743 #endif
00744
00745 int studentEnrollCount[MAX_STUDENT_LEVEL];
00746 studentEnrollCount[0] = full_time_undergrad;
00747 studentEnrollCount[1] = part_time_undergrad;
00748 studentEnrollCount[2] = enrollment_masters;
00749 studentEnrollCount[3] = enrollment_doctoral;
00750 studentEnrollCount[4] = non_degree_seeking;
00751
00752 float studentCount = 0.0f;
00753 int i, tmpCount=0;
00754 for (i=0; i<MAX_STUDENT_LEVEL; i++)
00755 studentCount += (float) studentEnrollCount[i];
00756
00757 #if(GAME_VERSION>=200)
00758 pref_vars_array[8] = math.safe_divide( (int)(full_time_undergrad+part_time_undergrad), (int)studentCount );
00759 pref_vars_array[9] = math.safe_divide( (int)non_degree_seeking, (int)studentCount );
00760 #else
00761 pref_vars_array[8] = (full_time_undergrad+part_time_undergrad) / studentCount;
00762 pref_vars_array[9] = non_degree_seeking / studentCount;
00763 #endif
00764
00765
00766 pref_vars_array[10] = percent_instate_freshmen;
00767
00768 for (i=0; i<MAX_STUDENT_LEVEL; i++)
00769 tmpCount += studentEnrollCount[i] * percent_female_sl[i] / 100;
00770
00771 #if(GAME_VERSION>=200)
00772 pref_vars_array[11] = math.safe_divide( (int)tmpCount, (int)studentCount );
00773 #else
00774 pref_vars_array[11] = tmpCount / studentCount;
00775 #endif
00776
00777 for (i=0, tmpCount = 0; i<MAX_STUDENT_LEVEL; i++)
00778 tmpCount += studentEnrollCount[i] * percent_minority_sl[i] / 100;
00779
00780 #if(GAME_VERSION>=200)
00781 pref_vars_array[12] = math.safe_divide( (int)tmpCount, (int)studentCount );
00782 #else
00783 pref_vars_array[12] = tmpCount / studentCount;
00784 #endif
00785 pref_vars_array[13] = doc_time_to_degree;
00786 pref_vars_array[14] = sponsored_research_rating;
00787 pref_vars_array[15] = (float) tuition_rate;
00788
00789 pref_vars_array[16] = pref_vars_array[15];
00790 pref_vars_array[17] = percent_ug_students_on_aid / 100.0f;
00791 pref_vars_array[18] = pref_vars_array[17];
00792 pref_vars_array[19] = institutional_aid_per_fte;
00793 pref_vars_array[20] = institutional_aid_per_fte;
00794
00795 err_when( PREFERECNE_COUNT2 != 21 );
00796
00797 for (i=0; i<PREFERECNE_COUNT2; i++)
00798 err_when( pref_vars_array[i] < 0 );
00799 }
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809 void PeerSchool::calc_student_pref_vars_average_array() {
00810 memcpy( pref_vars_average_array_last, pref_vars_average_array, sizeof(pref_vars_average_array) );
00811
00812 float sum;
00813 short psCount = school_res.peer_school_count;
00814
00815
00816
00817 for (int var=0; var<PREFERECNE_COUNT2; var++) {
00818 sum = 0.0f;
00819
00820 for (int i=0; i<psCount; i++) {
00821 PeerSchool *ps = &(school_res.peer_school_array[i]);
00822
00823 if ( ps != school_res.player_peer_school )
00824
00825 sum += ps->pref_vars_array[var];
00826 }
00827
00828 pref_vars_average_array[var] = sum / psCount;
00829 }
00830 }
00831
00832
00833
00834
00847
00848 const int sl = 0;
00849 float prefVarsArray[PREFERECNE_COUNT2];
00850 int i, j;
00851
00852
00853
00854
00855
00856
00857 PeerSchool* player = school_res.player_peer_school;
00858 memcpy(prefVarsArray, player->pref_vars_array, sizeof(prefVarsArray));
00859
00860 for (i=0; i<PREFERECNE_COUNT2; i++) {
00861
00862
00863 if ( i < PREFERECNE_COUNT2 - 4 )
00864 prefVarsArray[i] = math.safe_divide(prefVarsArray[i], PeerSchool::pref_vars_average_array[i]);
00865 else
00866 prefVarsArray[i] = math.safe_divide(player->pref_vars_array_last[i], PeerSchool::pref_vars_average_array_last[i]);
00867 }
00868
00869
00870
00871 bool isPublic = player_school.is_public();
00872 float finalRatio[MINORITY_GROUP_COUNT];
00873 float tmpRatio;
00874 float tmp, sign;
00875
00876 for (j=0; j<MINORITY_GROUP_COUNT; j++) {
00877 finalRatio[j] = 1;
00878
00879 for (i=0; i<PREFERECNE_COUNT2; i++) {
00880 sign = (pref_special_case(i))? -1.0f: 1.0f;
00881
00882
00883 tmp = enroll_res.preference_array2[isPublic][j][i].apps_ratio;
00884
00885 if ( tmp <= 0.0 || prefVarsArray[i] == 0)
00886 tmpRatio = 1.0f;
00887 else
00888 tmpRatio = math.safe_pow(prefVarsArray[i], sign * tmp);
00889
00890
00891 finalRatio[j] *= tmpRatio;
00892
00893 }
00894
00895 if ( !(1+ (float) exp(-s_slope*(finalRatio[j]-1))) )
00896 finalRatio[j] = 1;
00897 else
00898 finalRatio[j] = s_lower_bound+(s_upper_bound-s_lower_bound)/(1+ (float) exp(-s_slope*(finalRatio[j]-1)));
00899
00900 err_when( finalRatio[j] < 0 );
00901 }
00902
00903
00904
00905 int minorGroup, stuSubSeg, stuSeg;
00906 EnrollDataSL1* ed;
00907
00908 total_applications[sl] = 0;
00909
00910 finalRatio[MINORITY] *= app_multiplier[sl];
00911 finalRatio[NON_MINORITY] *= app_multiplier[sl];
00912
00913
00914
00915
00916
00917 for ( stuSubSeg=0; stuSubSeg<STUDENT_SUBSEGMENT_COUNT; stuSubSeg++ ) {
00918 if ( is_minority_group(stuSubSeg) )
00919 minorGroup = MINORITY;
00920 else
00921 minorGroup = NON_MINORITY;
00922
00923 for ( stuSeg=0; stuSeg<STUDENT_SEGMENT_COUNT; stuSeg++ ) {
00924 ed = &enroll_data_sl1[stuSubSeg][stuSeg];
00925
00926 ed->applications
00927 = int( (1.0f-apps_latency[sl]) * math.get_random_snd(chance_avg, PSCH_SD(chance_sd), true)
00928 * finalRatio[minorGroup] * ed->base_apps
00929
00930 + apps_latency[sl] * ed->applications + 0.5);
00931
00932 err_when(ed->applications < 0);
00933 total_applications[sl] += ed->applications;
00934 }
00935 }
00936 }
00937
00938
00939 void EnrollRes::calc_enroll_matriculations() {
00940 const int sl = 0;
00941
00942 float prefVarsArray[PREFERECNE_COUNT2];
00943 int i, j;
00944
00945
00946
00947
00948
00949
00950 PeerSchool* player = school_res.player_peer_school;
00951 memcpy(prefVarsArray, player->pref_vars_array, sizeof(prefVarsArray));
00952
00953 for (i=0; i<PREFERECNE_COUNT2; i++) {
00954
00955
00956 prefVarsArray[i] = math.safe_divide(prefVarsArray[i], PeerSchool::pref_vars_average_array[i]);
00957 }
00958
00959
00960
00961 bool isPublic = player_school.is_public();
00962 float finalRatio[MINORITY_GROUP_COUNT];
00963 float tmpRatio;
00964 float tmp, sign;
00965
00966 for (j=0; j<MINORITY_GROUP_COUNT; j++) {
00967 finalRatio[j] = 1;
00968
00969 for (i=0; i<PREFERECNE_COUNT2; i++) {
00970 sign = (pref_special_case(i))? -1.0f: 1.0f;
00971
00972
00973
00974 tmp = enroll_res.preference_array2[isPublic][j][i].yield_rate;
00975
00976 if ( tmp <= 0.0 )
00977 tmpRatio = 1;
00978 else if ( prefVarsArray[i] == 0 )
00979 tmpRatio = 0.75f;
00980 else {
00981 if ( i < PREFERECNE_COUNT2 - 4 )
00982 tmpRatio = (float) math.safe_pow(prefVarsArray[i], sign * tmp);
00983 else if ( i < PREFERECNE_COUNT2 - 2 )
00984 tmpRatio = (float) math.safe_pow(math.safe_divide(fraction_on_aid[j], prefVarsArray[i]), sign * tmp);
00985 else
00986 tmpRatio = (float) math.safe_pow(math.safe_divide(float(average_aid[j]), prefVarsArray[i]), sign * tmp);
00987 }
00988
00989 if ( tmpRatio < -100 || tmpRatio > 100 )
00990 tmpRatio = 1;
00991
00992
00993 finalRatio[j] *= tmpRatio;
00994 }
00995
00996 if ( !(1+ (float) exp(-s_slope*(finalRatio[j]-1))) )
00997 finalRatio[j] = 1;
00998 else
00999 finalRatio[j] = s_lower_bound+(s_upper_bound-s_lower_bound)/(1+ (float) exp(-s_slope*(finalRatio[j]-1)));
01000 }
01001
01002
01003
01004 int minorGroup, stuSubSeg, stuSeg;
01005 EnrollDataSL1* ed; {
01006
01007
01008
01009
01010
01011
01012 total_matrics[sl] = 0;
01013 matrics_top_athletes = 0; male_matrics_top_athletes = 0;
01014
01015 for ( stuSubSeg=0; stuSubSeg<STUDENT_SUBSEGMENT_COUNT; stuSubSeg++ ) {
01016 if ( is_minority_group(stuSubSeg) )
01017 minorGroup = MINORITY;
01018 else
01019 minorGroup = NON_MINORITY;
01020
01021 for ( stuSeg=0; stuSeg<STUDENT_SEGMENT_COUNT; stuSeg++ ) {
01022 ed = &enroll_data_sl1[stuSubSeg][stuSeg];
01023
01024 ed->yield_rate
01025 = (1.0f-yield_latency[sl]) * math.get_random_snd(chance_avg, PSCH_SD(chance_sd), true)
01026 * yield_multiplier[sl] * finalRatio[minorGroup] * ed->base_yield_rate
01027 + yield_latency[sl] * ed->yield_rate;
01028
01029
01030
01031 ed->yield_rate = max(0.0f, min(1.0f, ed->yield_rate));
01032
01033
01034
01035 ed->matrics = int(ed->yield_rate * ed->offers+ 0.5);
01036
01037
01038 total_matrics[sl] += ed->matrics;
01039 }
01040
01041
01042
01043 matrics_top_athletes += enroll_data_sl1[stuSubSeg][3].matrics;
01044
01045 if(is_male_group(stuSubSeg))
01046 male_matrics_top_athletes += enroll_data_sl1[stuSubSeg][3].matrics;
01047 }
01048 }
01049
01050 #if(GAME_VERSION>=200)
01051
01052 if( (!info.prerun_year || info.prerun_year && info.game_year > 1 ) && total_matrics[sl] >= 10 ) {
01053 int oldTotalMatrics = total_matrics[sl];
01054 int targetIntake = target_student_intake[sl];
01055
01056 total_matrics[sl] = 0;
01057 matrics_top_athletes = 0; male_matrics_top_athletes = 0;
01058
01059 for ( stuSubSeg=0; stuSubSeg<STUDENT_SUBSEGMENT_COUNT; stuSubSeg++ ) {
01060 if ( is_minority_group(stuSubSeg) )
01061 minorGroup = MINORITY;
01062 else
01063 minorGroup = NON_MINORITY;
01064
01065 for ( stuSeg=0; stuSeg<STUDENT_SEGMENT_COUNT; stuSeg++ ) {
01066 ed = &enroll_data_sl1[stuSubSeg][stuSeg];
01067
01068 ed->yield_rate = ed->yield_rate * targetIntake / oldTotalMatrics;
01069
01070
01071
01072 ed->yield_rate = max(0.0f, min(1.0f, ed->yield_rate));
01073
01074
01075
01076 ed->matrics = int(ed->yield_rate * ed->offers+ 0.5);
01077
01078
01079 total_matrics[sl] += ed->matrics;
01080 }
01081
01082
01083
01084 matrics_top_athletes += enroll_data_sl1[stuSubSeg][3].matrics;
01085
01086 if(is_male_group(stuSubSeg))
01087 male_matrics_top_athletes += enroll_data_sl1[stuSubSeg][3].matrics;
01088 }
01089 }
01090 #endif
01091
01092 for ( stuSubSeg=0; stuSubSeg<STUDENT_SUBSEGMENT_COUNT; stuSubSeg++ ) {
01093 for ( stuSeg=0; stuSeg<STUDENT_SEGMENT_COUNT; stuSeg++ ) {
01094 ed = &enroll_data_sl1[stuSubSeg][stuSeg];
01095
01096 if ( total_matrics[sl] > 0 )
01097 ed->fraction_matrics = float(ed->matrics) / total_matrics[sl];
01098 else
01099 ed->fraction_matrics = 0;
01100 }
01101 }
01102 }
01103
01104
01105
01106
01107
01112
01113
01114 const int sl = 0;
01115 int stuSubSeg, stuSeg;
01116 EnrollDataSL1* ed;
01117 float sum=0;
01118 total_offers[sl] = 0;
01119
01120
01121 int targetIntake = target_student_intake[sl];
01122
01123
01124 for ( stuSubSeg=0; stuSubSeg<STUDENT_SUBSEGMENT_COUNT; stuSubSeg++ )
01125 for ( stuSeg=0; stuSeg<STUDENT_SEGMENT_COUNT; stuSeg++ ) {
01126 ed = &enroll_data_sl1[stuSubSeg][stuSeg];
01127 sum += ed->yield_rate * ed->applications;
01128 }
01129
01130
01131 if ( sum <= targetIntake ) {
01132
01133
01134 for ( stuSubSeg=0; stuSubSeg<STUDENT_SUBSEGMENT_COUNT; stuSubSeg++ )
01135 for ( stuSeg=0; stuSeg<STUDENT_SEGMENT_COUNT; stuSeg++ ) {
01136 ed = &enroll_data_sl1[stuSubSeg][stuSeg];
01137 ed->offers = ed->applications;
01138 total_offers[sl] += ed->offers;
01139 }
01140 }
01141 else {
01142
01143
01144 const int size = STUDENT_SUBSEGMENT_COUNT*STUDENT_SEGMENT_COUNT;
01145
01146 DiagonalMatrix mQ(size);
01147 ColumnVector mQdiag(size);
01148 DiagonalMatrix I(size); I = 1;
01149 Matrix mA = I;
01150 RowVector vA(size);
01151 ColumnVector vc(size);
01152 ColumnVector vb(size+1);
01153 ColumnVector vtmp(1); vtmp(1) = targetIntake;
01154 ColumnVector vOffers(size);
01155
01156 const int K_FACTOR = 5;
01157 int i=1;
01158
01159
01160 for ( stuSubSeg=0; stuSubSeg<STUDENT_SUBSEGMENT_COUNT; stuSubSeg++ )
01161 for ( stuSeg=0; stuSeg<STUDENT_SEGMENT_COUNT; stuSeg++ ) {
01162 ed = &enroll_data_sl1[stuSubSeg][stuSeg];
01163 mQdiag(i) = ed->applications;
01164 vA(i) = ed->yield_rate;
01165 vc(i) = - ed->util - K_FACTOR;
01166 i++;
01167 }
01168
01169
01170 vb = mQdiag & vtmp;
01171 mA &= vA;
01172 mA *= -1; vb *= -1;
01173
01174 for (i=1; i<=size; i++)
01175 mQdiag(i) = 2 * K_FACTOR / max(mQdiag(i), 0.001);
01176 mQ.set_diagonal(mQdiag);
01177
01178
01179 if ( !LinearAlgebra::quadratic_prog(vc,mQ,mA,vb,vOffers) ) {
01180 vOffers = 0;
01181 }
01182
01183
01184 int offs;
01185 i =1;
01186
01187 for ( stuSubSeg=0; stuSubSeg<STUDENT_SUBSEGMENT_COUNT; stuSubSeg++ )
01188 for ( stuSeg=0; stuSeg<STUDENT_SEGMENT_COUNT; stuSeg++ ) {
01189 offs = enroll_data_sl1[stuSubSeg][stuSeg].offers = int( vOffers(i++) +0.5);
01190 total_offers[sl] += offs;
01191 }
01192 }
01193
01194
01195
01196
01197
01198 }
01199
01200
01201
01202
01211
01212
01213 const int sl = 0;
01214
01215
01216
01217
01218
01219 float x = 60, lastDeviate, deviate;
01220 float inc = x / 100.f;
01221
01222
01223
01224
01225
01226 if ( calc_need_aid(x+inc) > calc_need_aid(x-inc) )
01227 inc *= -1;
01228
01229 deviate = calc_need_aid(x);
01230
01231 do {
01232 x += inc;
01233 lastDeviate = deviate;
01234 deviate = calc_need_aid(x);
01235 }
01236 while ( deviate < lastDeviate && deviate > 0 );
01237
01238 need_upper = x;
01239 need_lower = need_upper - max_aid;
01240
01241
01242
01243
01244
01245 adjust_fraction_merit_aid(fraction_sl1_offered_merit_aid);
01246
01247
01248 x = 5;
01249 inc = x / 100.f;
01250
01251 if ( calc_merit_aid(x+inc, fraction_sl1_offered_merit_aid)
01252 > calc_merit_aid(x-inc, fraction_sl1_offered_merit_aid) )
01253 inc *= -1;
01254
01255 deviate = calc_merit_aid(x, fraction_sl1_offered_merit_aid);
01256
01257 do {
01258 x += inc;
01259 lastDeviate = deviate;
01260 deviate = calc_merit_aid(x, fraction_sl1_offered_merit_aid);
01261 }
01262 while ( deviate < lastDeviate && deviate > 0 );
01263
01264 merit_lower[sl] = x;
01265
01266
01267 x = 6;
01268 inc = x / 100.f;
01269
01270 if ( calc_merit_aid(x+inc, fraction_merit_top)
01271 > calc_merit_aid(x-inc, fraction_merit_top) )
01272 inc *= -1;
01273
01274 deviate = calc_merit_aid(x, fraction_merit_top);
01275
01276 do {
01277 x += inc;
01278 lastDeviate = deviate;
01279 deviate = calc_merit_aid(x, fraction_merit_top);
01280 }
01281 while ( deviate < lastDeviate && deviate > 0 );
01282
01283 merit_upper[sl] = x;
01284 }
01285
01286
01287
01288
01293
01294
01295 const int sl = 0;
01296 PeerSchool* player = school_res.player_peer_school;
01297
01298
01299
01300
01301
01302 const float frOfTradUGsWithNeed = max(player->percent_freshmen_with_need, (float)(player->freshmen_offered_aid)) / 100.0f;
01303
01304
01305
01306
01307 float deviate = 0, cdfTmp;
01308
01309 float aidMinMultiplier;
01310 int subSeg, seg;
01311
01312 Talent *talentPtr;
01313
01314 for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
01315 if ( subSeg == NONMINORITY_MALE || subSeg == NONMINORITY_FEMALE )
01316 aidMinMultiplier = 1.0f;
01317 else
01318 aidMinMultiplier = aidMinMultipliers[minority_aid_special];
01319
01320 for ( seg=0; seg<STUDENT_SEGMENT_COUNT; seg++ ) {
01321
01322 talentPtr = &(enroll_res.talent_array[subSeg][seg][INCOME]);
01323
01324 cdfTmp = math.get_random_gamma_CDF( aidMinMultiplier * talentPtr->average,
01325 PSCH_SD(talentPtr->variance), aid );
01326 deviate += cdfTmp * enroll_data_sl1[subSeg][seg].fraction_matrics;
01327 }
01328 }
01329
01330 return math.safe_pow(deviate - frOfTradUGsWithNeed, 2);
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346 }
01347
01348
01349
01350
01355
01356
01357 const int sl = 0;
01358
01359
01360
01361
01362 float deviate = 0, cdfTmp;
01363
01364 float aidMinMultiplier;
01365 int subSeg, seg;
01366 EnrollDataSL1 *ed;
01367
01368
01369 for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
01370 if ( subSeg == NONMINORITY_MALE || subSeg == NONMINORITY_FEMALE )
01371 aidMinMultiplier = 1.0f;
01372 else
01373 aidMinMultiplier = aidMinMultipliers[minority_aid_special];
01374
01375 for ( seg=0; seg<STUDENT_SEGMENT_COUNT; seg++ ) {
01376 ed = &enroll_data_sl1[subSeg][seg];
01377
01378 cdfTmp = 1 - math.get_random_gamma_CDF( aidMinMultiplier * ed->util,
01379 PSCH_SD(ed->util_variance), aid );
01380
01381 deviate += cdfTmp * enroll_data_sl1[subSeg][seg].fraction_matrics;
01382 }
01383 }
01384
01385 return math.safe_pow(deviate - base, 2);
01386
01387
01388
01389
01390
01391
01392 }
01393
01394
01395
01396
01402
01403
01404 const int sl = 0;
01405
01406
01407
01408
01409
01410 const float admMinMultipliers[PRIORITY_LEVEL_COUNT] = {
01411 1.0f, 2.0f, 3.0f
01412 };
01413
01414 int subSeg, seg, var;
01415 float admMinMultiplier;
01416 EnrollDataSL1 *ed;
01417
01418
01419
01420 for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
01421 if ( subSeg == NONMINORITY_MALE || subSeg == NONMINORITY_FEMALE )
01422 admMinMultiplier = 1.0f;
01423 else
01424 admMinMultiplier = admMinMultipliers[minority_offers_special];
01425
01426 for ( seg=0; seg<STUDENT_SEGMENT_COUNT; seg++ ) {
01427 ed = &enroll_data_sl1[subSeg][seg];
01428 ed->util = ed->util_variance = 0.0f;
01429
01430 for ( var=0; var<TALENT_VAR_COUNT; var++ ) {
01431 ed->util += float(offers_priority[var]) / MAX_TALENT_PRIORITY_LEVEL * admMinMultiplier * enroll_res.talent_array[subSeg][seg][var].average;
01432 ed->util_variance += math.safe_pow(offers_priority[var] / MAX_TALENT_PRIORITY_LEVEL,2) * enroll_res.talent_array[subSeg][seg][var].variance;
01433 }
01434 }
01435 }
01436 }
01437
01438
01439
01440
01442
01443
01444 if ( player_school.doctoral_program_intensity == 0 ) {
01445 target_student_intake[DOCTOR] = 0;
01446 return;
01447 }
01448
01449 int i,j;
01450 int targetTotal = 0;
01451 CourseArray* courArr;
01452 Department* deptPtr;
01453
01454 for ( i=department_array.size(); i>0; i-- ) {
01455 if ( department_array.is_deleted(i) )
01456 continue;
01457
01458 deptPtr = department_array[i];
01459
01460 int totalBreakoutSections = 0;
01461 courArr = &(department_array[i]->course_array);
01462
01463 for (j=courArr->size(); j>0; j--) {
01464 if ( courArr->operator[](j)->teaching_method == BREAKOUT_LAB )
01465 totalBreakoutSections++;
01466 }
01467
01468 targetTotal += (int) max(deptPtr->doctors_per_research_dollar * deptPtr->total_research_dollar_direct * 1000,
01469 deptPtr->init_doctor_count + deptPtr->breakout_section_by_doctor * (totalBreakoutSections - deptPtr->init_breakout_section_count));
01470 }
01471
01472 target_student_intake[DOCTOR] = max(0, targetTotal - student_count[DOCTOR]);
01473
01474 if ( target_student_intake[DOCTOR] > 3000 )
01475 target_student_intake[DOCTOR] = 3000;
01476
01477
01478
01479 err_when(targetTotal < 0);
01480
01481
01482
01483 if( info.prerun_year==1 ) {
01484 EnrollData* edSL;
01485 int sl=3;
01486
01487
01488 float studentGenderPct[STUDENT_SUBSEGMENT_COUNT];
01489
01490 err_when(GENDER_ETHNIC_TYPE_COUNT != STUDENT_SUBSEGMENT_COUNT);
01491 float femalePercent = student_female_percent[sl] / 100.0f;
01492 float minorityPercent = student_minority_percent[sl] / 100.0f;
01493
01494
01495 studentGenderPct[MINORITY_FEMALE] = femalePercent*minorityPercent;
01496 studentGenderPct[NONMINORITY_FEMALE] = femalePercent*(1.0f - minorityPercent);
01497 studentGenderPct[MINORITY_MALE] = (1.0f - femalePercent)*minorityPercent;
01498 studentGenderPct[NONMINORITY_MALE] = (1.0f - femalePercent)*(1.0f - minorityPercent);
01499
01500 for ( int subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
01501
01502 edSL = &enroll_data_sls[sl-1][subSeg];
01503
01504 edSL->base_apps
01505
01506 = int(edSL->apps_ratio * studentGenderPct[subSeg] * target_student_intake[sl] + 0.5);
01507 }
01508 }
01509 }
01510
01511
01512
01513
01515
01516 const int VAR_COUNT = 3;
01517 float input[VAR_COUNT];
01518 int i;
01519
01520 err_when(UG_TRADITION != 0);
01521 err_when(sl>=MAX_STUDENT_LEVEL);
01522
01523 if ( sl == DISTANCE_LEARN ) {
01524 float in=0;
01525
01526 for (int m=THIS_MONTH; m>=THIS_MONTH-info.graph_month_passed+1; m--)
01527 in += library_tech_office.tech_utilization_history[m];
01528
01529
01530 in = math.single_response_func(0.0f, 1.5f, 10.0f, 5.0f, in/100);
01531
01532
01533
01534 app_multiplier[sl] = player_school.latency_func(0.25f, app_multiplier[sl], in);
01535
01536 }
01537 else {
01538
01539
01540
01541 memset(input, 0, sizeof(input));
01542
01543
01544 input[0] = school_res.player_peer_school->prestige;
01545
01546
01547
01548 input[1] = player_school.satisfaction_overall[THIS_MONTH];
01549
01550
01551 int totalTargetIntake = 0;
01552
01553 for (i=0; i<MAX_STUDENT_LEVEL; i++)
01554 totalTargetIntake += target_student_intake[i];
01555
01556
01557 input[2] = max(1000.0f, float(finance.projected_expense_array[AC_ENROLLMENT_MANAGEMENT].this_year.total)) / totalTargetIntake;
01558
01559 if ( input[2] == 0 )
01560 input[2] = 1;
01561
01562 input[2] *= (float) finance.cost_rise_policy_array[PL_ENROLLMENT_MANAGEMENT].penalty_multiplier1;
01563
01564
01565 float weight[VAR_COUNT] = { 0.35f, 0.3f, 0.35f };
01566 float newValue = 0;
01567 for (i=0; i<VAR_COUNT; i++)
01568 newValue += input[i] * weight[i];
01569
01570
01571
01572
01573 app_multiplier[sl] = max(0.7f,min(1.3f, player_school.latency_func(0.8f, app_multiplier[sl], newValue)));
01574 }
01575
01576
01577
01578
01579 float weight[VAR_COUNT] = { 0.35f, 0.5f, 0.15f};
01580 float newValue = 0;
01581
01582 for (i=0; i<VAR_COUNT; i++)
01583 newValue += input[i] * weight[i];
01584
01585
01586
01587
01588 yield_multiplier[sl] = max(0.7f,min(1.3f, player_school.latency_func(0.80f, yield_multiplier[sl], newValue)));
01589
01590 }
01591
01592
01593
01594
01598
01599
01600 const int sl = UG_TRADITION;
01601
01602
01603
01604
01605
01606
01607 char subSeg, seg;
01608 int newStudentCount, i, t, aid=0;
01609
01610
01611 float talentArr[TALENT_VAR_COUNT];
01612 int maleCount=0, femaleCount=0;
01613
01614 avg_athletic_talent_male_matrics = 0;
01615 avg_athletic_talent_female_matrics = 0;
01616
01617 for ( subSeg=0; subSeg<