00001
00002
00003
00004
00005 #include <OMATH.H>
00006 #include <OSYS.H>
00007 #include <OGAMESET.H>
00008
00009 #include <OSCHLRES.H>
00010 #include <OPEERSCH.H>
00011 #include <OSTUDENT.H>
00012 #include <ODEPT.H>
00013 #include <OCHANCE.H>
00014
00015
00016 #include <OPSCHOOL.H>
00017 #include <OINVEST.H>
00018 #include <OATHLETI.H>
00019 #include <OFACILIT.H>
00020 #include <ODEVELOP.H>
00021 #include <OOPT.H>
00022
00023 #include <OLinAlg.h>
00024 #if(GAME_VERSION>=200)
00025 #include <OQUADPRG.H>
00026 #endif
00027 #include <OFINANCE.H>
00028 #include <OCHANCE.H>
00029
00030 #include <OSTUOFF.H>
00031 #include <OLIBTECH.H>
00032
00033 #ifdef DEBUG
00034
00035
00036 #endif
00037
00038 #define DEBUG_VC
00039 #ifdef DEBUG_VC
00040 #include <STDIO.H>
00041 #endif
00042 #include <OLOG.H>
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 const int percent_spons_research_for_AY_fac = 20;
00063
00064 const float percent_of_sponsored_research_for_other_salaries = 40.00;
00065
00066
00067
00068
00069
00070
00071 static void print_vector(const ColumnVector &xNames) {
00072 #ifdef DEBUG_VC
00073 char s[300];
00074 sprintf(s, "%f, %f, %f, %f, %f, %f, %f, %f, %f",
00075 xNames(1),xNames(2),xNames(3),
00076 xNames(4),xNames(5),xNames(6),
00077 xNames(7),xNames(8),xNames(9));
00078 DEBUG_LOG(s);
00079 #endif
00080 }
00081
00082 static void print_vector2(const ColumnVector &xNames) {
00083 #ifdef DEBUG_VC
00084 int count = xNames.Storage();
00085 char t[30];
00086
00087 String s = "-> ";
00088 for (int i=1; i<=count; i++ ) {
00089 sprintf(t, "%.3f, ", xNames(i));
00090 s+= t;
00091 }
00092 DEBUG_LOG(s);
00093 #endif
00094 }
00095
00096
00097
00098
00099 void FinancePolicy::bound_correction() {
00100 err_when(lower_limit > upper_limit);
00101
00102 if (lower_bound > upper_bound)
00103 lower_bound = upper_bound;
00104
00105 lower_bound = min(upper_limit, max(lower_bound, lower_limit));
00106 upper_bound = max(lower_limit, min(upper_bound, upper_limit));
00107
00108 target_value = min(upper_bound, max(lower_bound, target_value));
00109 result_value = min(upper_bound, max(lower_bound, result_value));
00110 }
00111
00112
00113
00114
00118
00119 if( saveLast ) {
00120 last_target_value = target_value;
00121 last_upper_bound = upper_bound;
00122 last_lower_bound = lower_bound;
00123 }
00124
00125 lower_bound = min(upper_limit,max(lower_limit, target_value - OPT_MINIMUM_RANGE ));
00126 upper_bound = max(lower_limit, min(upper_limit, target_value + OPT_MINIMUM_RANGE ));
00127
00128 target_value = min( max(target_value , lower_bound), upper_bound);
00129 bound_correction();
00130 }
00131
00132 void FinancePolicy::reset_constraint_policy() {
00133 target_value = last_target_value;
00134 upper_bound = last_upper_bound;
00135 lower_bound = last_lower_bound;
00136
00137 target_value = min( max(target_value , lower_bound), upper_bound);
00138 bound_correction();
00139 }
00140
00141
00142
00143
00145
00146
00147
00148 if ( applied_flag > P_NONE ) {
00149 target_value = last_target_value ;
00150 upper_bound = last_upper_bound;
00151 lower_bound = last_lower_bound;
00152 import_weight = last_import_weight;
00153 required_flag = last_required_flag;
00154 }
00155
00156 applied_flag = P_NONE;
00157
00158
00159
00160 if ( resetAll ) {
00161 penalty_multiplier1 = 1;
00162 penalty_multiplier2 = 1;
00163 }
00164 }
00165
00166
00167
00168
00170
00171 FinancePolicy& policyP = isRevenue ? revenue_policy_array[index] : expense_policy_array[index];
00172
00173 double targetArr[REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT] = {
00174 1.5, 1.5, 0, ( policyP.upper_bound + policyP.lower_bound ) / 2,
00175 1.0, 1.0, 0, 0, 0,
00176 };
00177
00178 policyP.target_value = targetArr[isRevenue?index:index+REVENUE_POLICY_COUNT];
00179 }
00180
00181
00182
00183 #if(GAME_VERSION>=200)
00184
00186 struct Revenue_and_Expense {
00187 double Surplus_Deficit;
00188 double Tuition_Rate;
00189 double Revenue_Array[REVENUE_ITEM_COUNT][4];
00190 double Expense_Array[EXPENSE_ITEM_COUNT][4];
00191
00192 double calc_Surplus_Deficit() {
00193 int i;
00194 Revenue_Array[AC_NET_TUITION_INCOME][3] = 0.0f;
00195 for( i = 0; i < AC_NET_TUITION_INCOME; ++i )
00196 Revenue_Array[AC_NET_TUITION_INCOME][3] += Revenue_Array[i][3];
00197 Surplus_Deficit = 0.0f;
00198 for( i = AC_NET_TUITION_INCOME; i < REVENUE_ITEM_COUNT; ++i )
00199 Surplus_Deficit += Revenue_Array[i][3];
00200 for( i = 0; i < EXPENSE_ITEM_COUNT; ++i )
00201 Surplus_Deficit -= Expense_Array[i][3];
00202 return Surplus_Deficit;
00203 }
00204 };
00205
00206 static void Optimize_policy_ver2(
00207
00208 Revenue_and_Expense &Trial_Budget,
00209 Revenue_and_Expense &Final_Budget,
00210
00211 float Result_Vector_S1[REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT],
00212 float Result_Vector_S2[COST_RISE_POLICY_COUNT],
00213
00214 int endStage,
00215 const Revenue_and_Expense &Base_Budget,
00216 const Revenue_and_Expense &Base_Actual,
00217
00218 const float PL_Policy_Array_S1[REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT][4],
00219
00220 const float PL_Policy_Array_S2[COST_RISE_POLICY_COUNT][4],
00221
00222 double inflation, double Base_tuition_rate, double Base_enrollment, double Target_enrollment,
00223 double Actual_enrollment, double Base_endowmentMV, double Base_OpResBalance, float ST_int_rate_01Aug,
00224 float ST_int_rate_31Aug, double New_Debt_service );
00225
00226 static void Calc_Budget( Revenue_and_Expense &Budget_Obj, float *Policy_Vector_S1, float *Policy_Vector_S2,
00227 const Revenue_and_Expense &Base_Budget,
00228 double New_State_approp, double inflation, double Base_tuition_rate, double Target_enrollment,
00229 double Base_endowmentMV, double Base_OpResBalance, double ST_int_rate_01Aug, double New_Debt_service );
00230 static void Write_Budget( Revenue_and_Expense &, int, int );
00231 static void Calc_Matrices_S1( double trial_Surplus_Deficit, ColumnVector &c, DiagonalMatrix &Q, Matrix &A, ColumnVector &b,
00232 const float PL_Policy_Array_S1[REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT][4],
00233 const Revenue_and_Expense &Base_Budget, double Base_tuition_rate, double Target_enrollment,
00234 double Base_endowmentMV, double inflation );
00235 static void quadratic_prog( ColumnVector &c, DiagonalMatrix &Q, Matrix &A, ColumnVector &b, ColumnVector &xNames, int );
00236 static void Calc_Matrices_S2( double dollar_Constraint, ColumnVector &c, DiagonalMatrix &Q, Matrix &A, ColumnVector &b,
00237 const Revenue_and_Expense &Base_Budget,
00238 const float PL_Policy_Array_S2[COST_RISE_POLICY_COUNT][4] );
00239 static void Calc_Actual( Revenue_and_Expense &Actual_Obj, const Revenue_and_Expense &Budget_Obj,
00240 const Revenue_and_Expense &Base_Actual, double Actual_fac_salaries_31Aug, double ST_int_rate_31Aug, double Actual_enrollment,
00241 double Base_OpResBalance );
00242
00243 static void Optimize_policy_ver2(
00244
00245 Revenue_and_Expense &Trial_Budget,
00246 Revenue_and_Expense &Final_Budget,
00247
00248 float Result_Vector_S1[REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT],
00249 float Result_Vector_S2[COST_RISE_POLICY_COUNT],
00250
00251
00252 int endStage,
00253
00254 const Revenue_and_Expense &Base_Budget,
00255 const Revenue_and_Expense &Base_Actual,
00256
00257 const float PL_Policy_Array_S1[REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT][4],
00258
00259 const float PL_Policy_Array_S2[COST_RISE_POLICY_COUNT][4],
00260
00261 double inflation,
00262 double Base_tuition_rate,
00263 double Base_enrollment,
00264 double Target_enrollment,
00265 double Actual_enrollment,
00266 double Base_endowmentMV,
00267 double Base_OpResBalance,
00268 float ST_int_rate_01Aug,
00269 float ST_int_rate_31Aug,
00270 double New_Debt_service
00271 ) {
00272 int i;
00273 Revenue_and_Expense S1_Output_Budget, New_Actual;
00274
00275 double Real_Budget_Growth_Dollars;
00276
00277 double New_State_approp = Base_Budget.Revenue_Array[AC_STATE_APPROPRIATION][3];
00278 double Actual_fac_salaries_31Aug = 0.0f;
00279
00280
00281
00282
00283 for( i = 0; i < EXPENSE_ITEM_COUNT; ++i )
00284 Actual_fac_salaries_31Aug += Base_Budget.Expense_Array[i][0];
00285 Actual_fac_salaries_31Aug *= (1.0 + PL_Policy_Array_S1[REVENUE_POLICY_COUNT+PL_FACULTY_SALARY_INCREASES][0]
00286 + PL_Policy_Array_S2[PL_FACULTY_FTE][0] + 0.01 );
00287
00288
00289 for( i = 0; i < REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT; ++i )
00290
00291 Result_Vector_S1[i] = PL_Policy_Array_S1[i][0];
00292
00293
00294 for( i = 0; i < COST_RISE_POLICY_COUNT; ++i )
00295
00296 Result_Vector_S2[i] = PL_Policy_Array_S1[REVENUE_POLICY_COUNT+PL_BUDGET_ADJUSTMENT][0];
00297
00298
00299
00300 Calc_Budget( Trial_Budget, Result_Vector_S1, Result_Vector_S2,
00301 Base_Budget, New_State_approp, inflation, Base_tuition_rate, Target_enrollment,
00302 Base_endowmentMV, Base_OpResBalance, ST_int_rate_01Aug, New_Debt_service );
00303
00304
00305 Write_Budget( Trial_Budget, 76, 3 ); {
00306
00307 ColumnVector c(REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT);
00308 DiagonalMatrix Q(REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT);
00309 Matrix A((REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT)*2+2,REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT);
00310 ColumnVector b((REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT)*2+2);
00311
00312
00313
00314 ColumnVector xNames(REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT);
00315
00316
00317 Calc_Matrices_S1( Trial_Budget.Surplus_Deficit, c, Q, A, b,
00318 PL_Policy_Array_S1, Base_Budget,
00319 Base_tuition_rate, Target_enrollment, Base_endowmentMV, inflation );
00320
00321 quadratic_prog( c, Q, A, b, xNames, 100);
00322
00323
00324 for( i = 0; i < REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT; ++i ) {
00325 Result_Vector_S1[i] = (float)xNames(i+1);
00326 }
00327
00328
00329 float cSum = 0.0f;
00330 for( i = 1; i <= REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT; ++i ) {
00331 cSum += xNames(i) * A((REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT)*2+1, i );
00332 }
00333
00334
00335
00336 float wSum = 0.0f;
00337 for( i = 1; i <= REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT; ++i ) {
00338 wSum += (Q(i) * xNames(i) + c(i)) * xNames(i);
00339 }
00340
00341
00342
00343 double Alt_Result_Vector_S1[REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT];
00344 double lowLimit[REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT];
00345 double highLimit[REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT];
00346 double tolLimit[REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT];
00347 double limitCoeff[REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT];
00348 double limitSum;
00349 double cost1[REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT];
00350 double cost2[REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT];
00351 for( i = 0; i < REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT; ++i ) {
00352 lowLimit[i] = PL_Policy_Array_S1[i][1];
00353 highLimit[i] = PL_Policy_Array_S1[i][2];
00354 tolLimit[i] = 0.0005;
00355 limitCoeff[i] = A((REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT)*2+1, i+1 );
00356 cost1[i] = c(i+1);
00357 cost2[i] = Q(i+1);
00358 }
00359 limitSum = b((REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT)*2+1);
00360 tolLimit[PL_ENDOWMENT_SPENDING_RATE] = 0.001;
00361 tolLimit[PL_INDIRECT_COST_RATE] = 0.005;
00362
00363 tolLimit[REVENUE_POLICY_COUNT+PL_SURPLUS_DEFICIT] = 0.001;
00364
00365 QuadProgramming quadProg;
00366
00367 if( quadProg.sp_quadratic_programming( REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT,
00368 Alt_Result_Vector_S1,
00369 lowLimit, highLimit, tolLimit, limitCoeff, limitSum, cost1, cost2 ) ) {
00370
00371
00372 double cSum2 = 0.0;
00373 for( i = 0; i < REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT; ++i )
00374 cSum2 += limitCoeff[i] * Alt_Result_Vector_S1[i];
00375
00376
00377 double wSum2 = 0.0f;
00378 for( i = 0; i < REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT; ++i ) {
00379 wSum2 += (cost2[i] * Alt_Result_Vector_S1[i] + cost1[i]) * Alt_Result_Vector_S1[i];
00380 }
00381
00382
00383 if( wSum2 < wSum ) {
00384
00385
00386 for( i = 0; i < REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT; ++i ) {
00387 Result_Vector_S1[i] = Alt_Result_Vector_S1[i];
00388 }
00389 }
00390 }
00391 }
00392
00393
00394 for( i = 0; i < COST_RISE_POLICY_COUNT; ++i ) {
00395 Result_Vector_S2[i] = Result_Vector_S1[REVENUE_POLICY_COUNT+PL_BUDGET_ADJUSTMENT];
00396 }
00397
00398
00399 Calc_Budget( S1_Output_Budget, Result_Vector_S1, Result_Vector_S2,
00400 Base_Budget, New_State_approp, inflation, Base_tuition_rate, Target_enrollment,
00401 Base_endowmentMV, Base_OpResBalance, ST_int_rate_01Aug, New_Debt_service );
00402 Write_Budget( S1_Output_Budget, 76, 8 );
00403
00404
00405 double Base_Budget_OperatingCost = 0.0f;
00406 for( i = 0; i < OPERATING_EXPENSE_ITEM_COUNT; ++i )
00407 Base_Budget_OperatingCost += Base_Budget.Expense_Array[i][3];
00408
00409
00410
00411 if( endStage <= 1 )
00412 return;
00413
00414
00415 Real_Budget_Growth_Dollars = Result_Vector_S1[REVENUE_POLICY_COUNT+PL_BUDGET_ADJUSTMENT]
00416 * (Base_Budget_OperatingCost - Base_Budget.Expense_Array[AC_SPONSORED_RESEARCH_EXPENSE][3]); {
00417
00418 ColumnVector c(COST_RISE_POLICY_COUNT);
00419 DiagonalMatrix Q(COST_RISE_POLICY_COUNT);
00420 Matrix A(COST_RISE_POLICY_COUNT*2+2,COST_RISE_POLICY_COUNT);
00421 ColumnVector b(COST_RISE_POLICY_COUNT*2+2);
00422
00423 ColumnVector xNames(COST_RISE_POLICY_COUNT);
00424
00425
00426 Calc_Matrices_S2( Real_Budget_Growth_Dollars, c, Q, A, b,
00427 Base_Budget, PL_Policy_Array_S2 );
00428
00429 quadratic_prog( c, Q, A, b, xNames, 100 );
00430
00431 for( i = 0; i < COST_RISE_POLICY_COUNT; ++i )
00432 Result_Vector_S2[i] = (float)xNames(i+1);
00433
00434
00435 float cSum = 0.0f;
00436 for( i = 1; i <= COST_RISE_POLICY_COUNT; ++i ) {
00437 cSum += xNames(i) * A(COST_RISE_POLICY_COUNT*2+1, i );
00438 }
00439
00440
00441
00442 float wSum = 0.0f;
00443 for( i = 1; i <= COST_RISE_POLICY_COUNT; ++i ) {
00444 wSum += (Q(i) * xNames(i) + c(i)) * xNames(i);
00445 }
00446
00447
00448
00449 double Alt_Result_Vector_S2[COST_RISE_POLICY_COUNT];
00450 double lowLimit[COST_RISE_POLICY_COUNT];
00451 double highLimit[COST_RISE_POLICY_COUNT];
00452 double tolLimit[COST_RISE_POLICY_COUNT];
00453 double limitCoeff[COST_RISE_POLICY_COUNT];
00454 double limitSum;
00455 double cost1[COST_RISE_POLICY_COUNT];
00456 double cost2[COST_RISE_POLICY_COUNT];
00457 for( i = 0; i < COST_RISE_POLICY_COUNT; ++i ) {
00458 lowLimit[i] = PL_Policy_Array_S2[i][1];
00459 highLimit[i] = PL_Policy_Array_S2[i][2];
00460 tolLimit[i] = 0.0005;
00461 limitCoeff[i] = A(COST_RISE_POLICY_COUNT*2+1, i+1 );
00462 cost1[i] = c(i+1);
00463 cost2[i] = Q(i+1);
00464 }
00465 limitSum = b(COST_RISE_POLICY_COUNT*2+1);
00466
00467 QuadProgramming quadProg;
00468
00469 if( quadProg.sp_quadratic_programming( COST_RISE_POLICY_COUNT,
00470 Alt_Result_Vector_S2,
00471 lowLimit, highLimit, tolLimit, limitCoeff, limitSum, cost1, cost2 ) ) {
00472
00473
00474 double cSum2 = 0.0;
00475 for( i = 0; i < COST_RISE_POLICY_COUNT; ++i )
00476 cSum2 += limitCoeff[i] * Alt_Result_Vector_S2[i];
00477
00478
00479 double wSum2 = 0.0f;
00480 for( i = 0; i < COST_RISE_POLICY_COUNT; ++i ) {
00481 wSum2 += (cost2[i] * Alt_Result_Vector_S2[i] + cost1[i]) * Alt_Result_Vector_S2[i];
00482 }
00483
00484
00485 if( fabs(cSum2 - limitSum) < fabs(cSum - limitSum) ) {
00486
00487
00488 for( i = 0; i < COST_RISE_POLICY_COUNT; ++i ) {
00489 Result_Vector_S2[i] = Alt_Result_Vector_S2[i];
00490 }
00491 }
00492 }
00493
00494 }
00495
00496
00497 Calc_Budget( Final_Budget, Result_Vector_S1, Result_Vector_S2,
00498 Base_Budget, New_State_approp, inflation, Base_tuition_rate, Target_enrollment,
00499 Base_endowmentMV, Base_OpResBalance, ST_int_rate_01Aug, New_Debt_service );
00500
00501
00502 Write_Budget( Final_Budget, 107, 3 );
00503
00504
00505
00506 Calc_Actual( New_Actual, Final_Budget,
00507 Base_Actual, Actual_fac_salaries_31Aug, ST_int_rate_31Aug,
00508 Actual_enrollment, Base_OpResBalance );
00509
00510
00511 Write_Budget( New_Actual, 107, 8 );
00512 }
00513
00514 static void Calc_Actual( Revenue_and_Expense &Actual_Obj, const Revenue_and_Expense &Budget_Obj,
00515 const Revenue_and_Expense &Base_Actual,
00516 double Actual_fac_salaries_31Aug,
00517 double ST_int_rate_31Aug,
00518 double Actual_enrollment,
00519 double Base_OpResBalance ) {
00520 int i, j;
00521
00522
00523
00524 Actual_Obj.Revenue_Array[AC_GROSS_TUITION_INCOME][3] = Budget_Obj.Tuition_Rate * Actual_enrollment / 1000.0;
00525
00526 Actual_Obj.Revenue_Array[AC_FINANCIAL_AID][3] = Budget_Obj.Revenue_Array[AC_FINANCIAL_AID][3];
00527 Actual_Obj.Revenue_Array[AC_NET_TUITION_INCOME][3] = 0.0f;
00528 for( i = AC_GROSS_TUITION_INCOME; i < AC_NET_TUITION_INCOME; ++i )
00529 Actual_Obj.Revenue_Array[AC_NET_TUITION_INCOME][3] += Actual_Obj.Revenue_Array[i][3];
00530
00531
00532 Actual_Obj.Revenue_Array[AC_SPONSORED_RESEARCH_REVENUE][1] = Base_Actual.Revenue_Array[AC_SPONSORED_RESEARCH_REVENUE][1];
00533 Actual_Obj.Revenue_Array[AC_SPONSORED_RESEARCH_REVENUE][2] = Base_Actual.Revenue_Array[AC_SPONSORED_RESEARCH_REVENUE][1]
00534
00535 * math.safe_divide(Budget_Obj.Revenue_Array[AC_SPONSORED_RESEARCH_REVENUE][2],Budget_Obj.Revenue_Array[AC_SPONSORED_RESEARCH_REVENUE][1]);
00536 Actual_Obj.Revenue_Array[AC_SPONSORED_RESEARCH_REVENUE][3] = Actual_Obj.Revenue_Array[AC_SPONSORED_RESEARCH_REVENUE][1]
00537 + Actual_Obj.Revenue_Array[AC_SPONSORED_RESEARCH_REVENUE][2];
00538
00539
00540 Actual_Obj.Revenue_Array[AC_GIFTS][3] = Base_Actual.Revenue_Array[AC_GIFTS][3];
00541
00542 Actual_Obj.Revenue_Array[AC_ENDOWMENT_SPENDING][3] = Budget_Obj.Revenue_Array[AC_ENDOWMENT_SPENDING][3];
00543
00544 Actual_Obj.Revenue_Array[AC_INTERCOLLEGIATE_ATHLETICS][3] = Base_Actual.Revenue_Array[AC_INTERCOLLEGIATE_ATHLETICS][3];
00545
00546 Actual_Obj.Revenue_Array[AC_OTHER_OPERATING_INCOME][3] = Base_Actual.Revenue_Array[AC_OTHER_OPERATING_INCOME][3];
00547
00548 Actual_Obj.Revenue_Array[AC_INTEREST_EARNED_OR_PAID][3] = ST_int_rate_31Aug * (Base_OpResBalance + Base_Actual.Surplus_Deficit);
00549
00550 Actual_Obj.Revenue_Array[AC_STATE_APPROPRIATION][3] = Budget_Obj.Revenue_Array[AC_STATE_APPROPRIATION][3];
00551
00552
00553 for( i = 0; i < OPERATING_EXPENSE_ITEM_COUNT; ++i ) {
00554 for( j = 0; j <= 2; ++j ) {
00555 Actual_Obj.Expense_Array[i][j] = Budget_Obj.Expense_Array[i][j];
00556 }
00557 }
00558
00559
00560
00561 Actual_Obj.Expense_Array[AC_ACADEMIC_DEPARTMENTS][0] = Actual_fac_salaries_31Aug;
00562 for( j = 0; j <= 2; ++j )
00563
00564 Actual_Obj.Expense_Array[AC_SPONSORED_RESEARCH_EXPENSE][j] = Base_Actual.Expense_Array[AC_SPONSORED_RESEARCH_EXPENSE][j];
00565
00566
00567
00568 for( j = 0; j <= 2; ++j )
00569
00570 Actual_Obj.Expense_Array[AC_SERVICE_ON_GENERAL_PLANT_DEBT][j] = Budget_Obj.Expense_Array[AC_SERVICE_ON_GENERAL_PLANT_DEBT][j];
00571 for( j = 0; j <= 2; ++j )
00572
00573 Actual_Obj.Expense_Array[AC_TRANSFER_TO_CAPITAL_RESERVE][j] = Budget_Obj.Expense_Array[AC_TRANSFER_TO_CAPITAL_RESERVE][j];
00574
00575
00576 for( i = 0; i < EXPENSE_ITEM_COUNT; ++i ) {
00577 double expenseItemTotal = 0.0f;
00578 for( j = 0; j <= 2; ++j ) {
00579 expenseItemTotal += Actual_Obj.Expense_Array[i][j];
00580 }
00581 Actual_Obj.Expense_Array[i][3] = expenseItemTotal;
00582 }
00583 Actual_Obj.calc_Surplus_Deficit();
00584 }
00585
00586 static void Calc_Budget( Revenue_and_Expense &Budget_Obj, float *Policy_Vector_S1, float *Policy_Vector_S2,
00587 const Revenue_and_Expense &Base_Budget,
00588 double New_State_approp, double inflation, double Base_tuition_rate, double Target_enrollment,
00589 double Base_endowmentMV, double Base_OpResBalance, double ST_int_rate_01Aug, double New_Debt_service ) {
00590 int i;
00591
00592
00593
00594
00595 Budget_Obj.Tuition_Rate = (1.0 + inflation + Policy_Vector_S1[PL_TUITION_RATE_GROWTH]) * Base_tuition_rate;
00596 Budget_Obj.Revenue_Array[AC_GROSS_TUITION_INCOME][3] = (Budget_Obj.Tuition_Rate / 1000.0) * Target_enrollment;
00597
00598
00599 Budget_Obj.Revenue_Array[AC_FINANCIAL_AID][3] = (1.0 + inflation + Policy_Vector_S1[PL_FINANCIAL_AID]) * Base_Budget.Revenue_Array[AC_FINANCIAL_AID][3];
00600
00601
00602 Budget_Obj.Revenue_Array[AC_NET_TUITION_INCOME][3] = 0.0f;
00603 for( i = AC_GROSS_TUITION_INCOME; i < AC_NET_TUITION_INCOME; ++i ) {
00604 Budget_Obj.Revenue_Array[AC_NET_TUITION_INCOME][3] += Budget_Obj.Revenue_Array[i][3];
00605 }
00606
00607
00608
00609
00610 Budget_Obj.Revenue_Array[AC_GIFTS][3] = (1.0 + inflation) * Base_Budget.Revenue_Array[AC_GIFTS][3];
00611
00612
00613 Budget_Obj.Revenue_Array[AC_ENDOWMENT_SPENDING][3] = Policy_Vector_S1[PL_ENDOWMENT_SPENDING_RATE] * Base_endowmentMV;
00614
00615
00616 Budget_Obj.Revenue_Array[AC_INTERCOLLEGIATE_ATHLETICS][3] = (1.0 + inflation) * Base_Budget.Revenue_Array[AC_INTERCOLLEGIATE_ATHLETICS][3];
00617
00618
00619 Budget_Obj.Revenue_Array[AC_OTHER_OPERATING_INCOME][3] = (1.0 + inflation) * Base_Budget.Revenue_Array[AC_OTHER_OPERATING_INCOME][3];
00620
00621
00622 Budget_Obj.Revenue_Array[AC_INTEREST_EARNED_OR_PAID][3] = (Base_OpResBalance + Base_Budget.Surplus_Deficit) * ST_int_rate_01Aug;
00623
00624
00625 Budget_Obj.Revenue_Array[AC_STATE_APPROPRIATION][3] = New_State_approp;
00626
00627
00628
00629
00630 Budget_Obj.Expense_Array[AC_ACADEMIC_DEPARTMENTS][0] = Base_Budget.Expense_Array[AC_ACADEMIC_DEPARTMENTS][0]
00631 * (1.0 + Policy_Vector_S2[PL_FACULTY_FTE] + inflation
00632
00633 + Policy_Vector_S1[REVENUE_POLICY_COUNT+PL_FACULTY_SALARY_INCREASES] );
00634 Budget_Obj.Expense_Array[AC_ACADEMIC_DEPARTMENTS][1] = Base_Budget.Expense_Array[AC_ACADEMIC_DEPARTMENTS][1]
00635 * (1.0 + Policy_Vector_S2[PL_NON_FACULTY_DEPARTMENTAL_EXPENSE] + inflation
00636
00637 + Policy_Vector_S1[REVENUE_POLICY_COUNT+PL_STAFF_SALARY_INCREASES]);
00638 Budget_Obj.Expense_Array[AC_ACADEMIC_DEPARTMENTS][2] = Base_Budget.Expense_Array[AC_ACADEMIC_DEPARTMENTS][2]
00639
00640 * (1.0 + Policy_Vector_S2[PL_NON_FACULTY_DEPARTMENTAL_EXPENSE] + inflation);
00641 Budget_Obj.Expense_Array[AC_ACADEMIC_DEPARTMENTS][3] = Budget_Obj.Expense_Array[AC_ACADEMIC_DEPARTMENTS][0]
00642 + Budget_Obj.Expense_Array[AC_ACADEMIC_DEPARTMENTS][1]
00643 + Budget_Obj.Expense_Array[AC_ACADEMIC_DEPARTMENTS][2];
00644
00645
00646 Budget_Obj.Expense_Array[AC_SPONSORED_RESEARCH_EXPENSE][0] = Base_Budget.Expense_Array[AC_SPONSORED_RESEARCH_EXPENSE][0]
00647
00648 * (1.0 + inflation + Policy_Vector_S1[REVENUE_POLICY_COUNT+PL_FACULTY_SALARY_INCREASES]);
00649 Budget_Obj.Expense_Array[AC_SPONSORED_RESEARCH_EXPENSE][1] = Base_Budget.Expense_Array[AC_SPONSORED_RESEARCH_EXPENSE][1]
00650
00651 * (1.0 + inflation + Policy_Vector_S1[REVENUE_POLICY_COUNT+PL_STAFF_SALARY_INCREASES]);
00652 Budget_Obj.Expense_Array[AC_SPONSORED_RESEARCH_EXPENSE][2] = Base_Budget.Expense_Array[AC_SPONSORED_RESEARCH_EXPENSE][2]
00653 * (1.0 + inflation);
00654 Budget_Obj.Expense_Array[AC_SPONSORED_RESEARCH_EXPENSE][3] = Budget_Obj.Expense_Array[AC_SPONSORED_RESEARCH_EXPENSE][0]
00655 + Budget_Obj.Expense_Array[AC_SPONSORED_RESEARCH_EXPENSE][1]
00656 + Budget_Obj.Expense_Array[AC_SPONSORED_RESEARCH_EXPENSE][2];
00657
00658
00659 for( i = 1+AC_SPONSORED_RESEARCH_EXPENSE; i < OPERATING_EXPENSE_ITEM_COUNT; ++i ) {
00660 Budget_Obj.Expense_Array[i][0] = Base_Budget.Expense_Array[i][0]
00661 * (1.0 + Policy_Vector_S2[i] + inflation
00662
00663 + Policy_Vector_S1[REVENUE_POLICY_COUNT+PL_FACULTY_SALARY_INCREASES] );
00664 Budget_Obj.Expense_Array[i][1] = Base_Budget.Expense_Array[i][1]
00665 * (1.0 + Policy_Vector_S2[i] + inflation
00666
00667 + Policy_Vector_S1[REVENUE_POLICY_COUNT+PL_STAFF_SALARY_INCREASES]);
00668 Budget_Obj.Expense_Array[i][2] = Base_Budget.Expense_Array[i][2]
00669 * (1.0 + Policy_Vector_S2[i] + inflation);
00670 Budget_Obj.Expense_Array[i][3] = Budget_Obj.Expense_Array[i][0]
00671 + Budget_Obj.Expense_Array[i][1] + Budget_Obj.Expense_Array[i][2];
00672 }
00673
00674
00675
00676 Budget_Obj.Expense_Array[AC_SERVICE_ON_GENERAL_PLANT_DEBT][0] = 0.0f;
00677 Budget_Obj.Expense_Array[AC_SERVICE_ON_GENERAL_PLANT_DEBT][1] = 0.0f;
00678 Budget_Obj.Expense_Array[AC_SERVICE_ON_GENERAL_PLANT_DEBT][2] = New_Debt_service;
00679 Budget_Obj.Expense_Array[AC_SERVICE_ON_GENERAL_PLANT_DEBT][3] = Budget_Obj.Expense_Array[AC_SERVICE_ON_GENERAL_PLANT_DEBT][2];
00680
00681 Budget_Obj.Expense_Array[AC_TRANSFER_TO_CAPITAL_RESERVE][0] = 0.0f;
00682 Budget_Obj.Expense_Array[AC_TRANSFER_TO_CAPITAL_RESERVE][1] = 0.0f;
00683 Budget_Obj.Expense_Array[AC_TRANSFER_TO_CAPITAL_RESERVE][2] = Base_Budget.Expense_Array[AC_TRANSFER_TO_CAPITAL_RESERVE][2]
00684
00685 * (1.0 + inflation + Policy_Vector_S1[REVENUE_POLICY_COUNT+PL_REAL_TRANSFER_TO_PLANT_GROWTH]);
00686 Budget_Obj.Expense_Array[AC_TRANSFER_TO_CAPITAL_RESERVE][3] = Budget_Obj.Expense_Array[AC_TRANSFER_TO_CAPITAL_RESERVE][2];
00687
00688
00689
00690
00691 Budget_Obj.Revenue_Array[AC_SPONSORED_RESEARCH_REVENUE][1] = Budget_Obj.Expense_Array[AC_SPONSORED_RESEARCH_EXPENSE][3];
00692 Budget_Obj.Revenue_Array[AC_SPONSORED_RESEARCH_REVENUE][2] = Base_Budget.Revenue_Array[AC_SPONSORED_RESEARCH_REVENUE][2]
00693 + 0.5 * (Budget_Obj.Expense_Array[AC_SPONSORED_RESEARCH_EXPENSE][3]
00694 * Policy_Vector_S1[PL_INDIRECT_COST_RATE] - Base_Budget.Revenue_Array[AC_SPONSORED_RESEARCH_REVENUE][2]);
00695 Budget_Obj.Revenue_Array[AC_SPONSORED_RESEARCH_REVENUE][3] = Budget_Obj.Revenue_Array[AC_SPONSORED_RESEARCH_REVENUE][1]
00696 + Budget_Obj.Revenue_Array[AC_SPONSORED_RESEARCH_REVENUE][2];
00697
00698
00699
00700 Budget_Obj.calc_Surplus_Deficit();
00701 }
00702
00703
00704 static void Write_Budget( Revenue_and_Expense &Trial_Budget, int, int ) {
00705 #ifdef DEBUG
00706 DEBUG_LOG("Revenue :");
00707
00708 String s;
00709 for( int i = 0; i < REVENUE_ITEM_COUNT; ++i ) {
00710 s = Trial_Budget.Revenue_Array[i][3];
00711 if( i == AC_SPONSORED_RESEARCH_REVENUE ) {
00712 s += " {";
00713 s += Trial_Budget.Revenue_Array[i][1];
00714 s += " + ";
00715 s += Trial_Budget.Revenue_Array[i][2];
00716 s += "}";
00717 }
00718 DEBUG_LOG( (char *)s );
00719 }
00720
00721 DEBUG_LOG("Expense :");
00722 for( i = 0; i < EXPENSE_ITEM_COUNT; ++i ) {
00723 s = Trial_Budget.Expense_Array[i][3];
00724 s += " {";
00725 s += Trial_Budget.Expense_Array[i][0];
00726 s += " + ";
00727 s += Trial_Budget.Expense_Array[i][1];
00728 s += " + ";
00729 s += Trial_Budget.Expense_Array[i][2];
00730 s += "}";
00731 DEBUG_LOG( (char *)s );
00732 }
00733
00734 s = "Surplus = ";
00735 s += Trial_Budget.Surplus_Deficit;
00736 DEBUG_LOG( (char *)s );
00737 #endif
00738 }
00739
00740
00741
00742
00743
00744
00745 static void Calc_Matrices_S1( double trial_Surplus_Deficit, ColumnVector &c, DiagonalMatrix &Q, Matrix &A, ColumnVector &b,
00746 const float PL_Policy_Array_S1[REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT][4],
00747 const Revenue_and_Expense &Base_Budget,
00748 double Base_tuition_rate,
00749 double Target_enrollment,
00750 double Base_endowmentMV,
00751 double inflation
00752 ) {
00753
00754
00755
00756 double remainder, coefficients[REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT];
00757 double Base_Budget_OperatingCost[4];
00758 double Base_Budget_TotalUseOfFund[4];
00759
00760 int i,j;
00761 for( j = 0; j < 4; ++j ) {
00762 Base_Budget_OperatingCost[j] = 0.0f;
00763 for(i=0; i < OPERATING_EXPENSE_ITEM_COUNT; ++i )
00764 Base_Budget_OperatingCost[j] += Base_Budget.Expense_Array[i][j];
00765 }
00766 for( j = 0; j < 4; ++j ) {
00767 Base_Budget_TotalUseOfFund[j] = 0.0f;
00768 for(i=0; i < EXPENSE_ITEM_COUNT; ++i )
00769 Base_Budget_TotalUseOfFund[j] += Base_Budget.Expense_Array[i][j];
00770 }
00771
00772
00773 A = 0.0;
00774
00775
00776
00777 coefficients[PL_TUITION_RATE_GROWTH] = Base_tuition_rate * Target_enrollment / 1000.0;
00778
00779 coefficients[PL_FINANCIAL_AID] = Base_Budget.Revenue_Array[AC_FINANCIAL_AID][3];
00780
00781 coefficients[PL_ENDOWMENT_SPENDING_RATE] = Base_endowmentMV;
00782
00783 coefficients[PL_INDIRECT_COST_RATE] = Base_Budget.Expense_Array[AC_SPONSORED_RESEARCH_EXPENSE][3] * (1.015 + inflation) / 2.0f;
00784
00785
00786
00787 coefficients[REVENUE_POLICY_COUNT+PL_FACULTY_SALARY_INCREASES] = -Base_Budget_OperatingCost[0];
00788
00789 coefficients[REVENUE_POLICY_COUNT+PL_STAFF_SALARY_INCREASES] = -Base_Budget_OperatingCost[1];
00790
00791 coefficients[REVENUE_POLICY_COUNT+PL_BUDGET_ADJUSTMENT] = -Base_Budget_OperatingCost[3];
00792
00793 coefficients[REVENUE_POLICY_COUNT+PL_REAL_TRANSFER_TO_PLANT_GROWTH] = -Base_Budget.Expense_Array[AC_TRANSFER_TO_CAPITAL_RESERVE][3];
00794
00795 coefficients[REVENUE_POLICY_COUNT+PL_SURPLUS_DEFICIT] = -Base_Budget_TotalUseOfFund[3] * (1.0 + inflation);
00796
00797
00798 static double weightScale = 100000.0;
00799 for(i = 0; i < REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT; ++i ) {
00800
00801
00802
00803
00804
00805 double adjWeight = 1.0;
00806 if( coefficients[i] != 0.0 ) {
00807
00808 adjWeight = PL_Policy_Array_S1[i][3] * fabs(coefficients[i])/weightScale;
00809
00810
00811
00812
00813
00814
00815
00816 }
00817
00818
00819 c(i+1) = -PL_Policy_Array_S1[i][0] * adjWeight;
00820 Q(i+1) = adjWeight / 2.0;
00821 }
00822
00823 remainder = trial_Surplus_Deficit;
00824
00825 for( i = 0; i < REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT; ++i ) {
00826 if( i != REVENUE_POLICY_COUNT+PL_SURPLUS_DEFICIT )
00827 remainder -= coefficients[i] * PL_Policy_Array_S1[i][0];
00828 }
00829
00830 for( i = 0; i < REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT; ++i ) {
00831 A(i+1,i+1) = 1.0;
00832 b(i+1) = PL_Policy_Array_S1[i][1];
00833 A(REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT+i+1, i+1) = -1.0f;
00834
00835 b(REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT+i+1) = -PL_Policy_Array_S1[i][2];
00836
00837 A((REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT)*2+1, i+1) = -coefficients[i];
00838
00839 b((REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT)*2+1) = remainder;
00840 A((REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT)*2+2, i+1) = coefficients[i];
00841
00842 b((REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT)*2+2) = -remainder;
00843 }
00844
00845
00846
00847
00848
00849
00850 }
00851
00852
00853
00854
00855
00856
00857 static void Calc_Matrices_S2( double dollar_Constraint, ColumnVector &c, DiagonalMatrix &Q, Matrix &A, ColumnVector &b,
00858 const Revenue_and_Expense &Base_Budget,
00859 const float PL_Policy_Array_S2[COST_RISE_POLICY_COUNT][4]
00860 ) {
00861
00862
00863
00864
00865
00866 double coefficients[COST_RISE_POLICY_COUNT];
00867
00868 int i;
00869
00870
00871 A = 0.0;
00872
00873
00874
00875 for( i = 0; i < COST_RISE_POLICY_COUNT; ++i ) {
00876 if( i == PL_FACULTY_FTE ) {
00877
00878 coefficients[i] = Base_Budget.Expense_Array[AC_ACADEMIC_DEPARTMENTS][0];
00879 }
00880 else if( i == PL_NON_FACULTY_DEPARTMENTAL_EXPENSE ) {
00881 coefficients[i] = Base_Budget.Expense_Array[AC_ACADEMIC_DEPARTMENTS][1]
00882
00883 + Base_Budget.Expense_Array[AC_ACADEMIC_DEPARTMENTS][2];
00884 }
00885 else {
00886 err_when( i >= OPERATING_EXPENSE_ITEM_COUNT );
00887
00888 coefficients[i] = Base_Budget.Expense_Array[i][3];
00889 }
00890 }
00891
00892
00893 for( i = 0; i < COST_RISE_POLICY_COUNT; ++i ) {
00894
00895
00896
00897
00898
00899 double adjWeight = PL_Policy_Array_S2[i][3] * fabs(coefficients[i])/100000.0;
00900
00901 c(i+1) = -PL_Policy_Array_S2[i][0] * adjWeight;
00902 Q(i+1) = adjWeight / 2.0;
00903 }
00904
00905 for( i = 0; i < COST_RISE_POLICY_COUNT; ++i ) {
00906 A(i+1,i+1) = 1.0;
00907 b(i+1) = PL_Policy_Array_S2[i][1];
00908 A(COST_RISE_POLICY_COUNT+i+1,i+1) = -1.0f;
00909
00910 b(COST_RISE_POLICY_COUNT+i+1) = -PL_Policy_Array_S2[i][2];
00911
00912 A(COST_RISE_POLICY_COUNT*2+1,i+1) = coefficients[i];
00913
00914 b(COST_RISE_POLICY_COUNT*2+1) = dollar_Constraint;
00915 A(COST_RISE_POLICY_COUNT*2+2,i+1) = -coefficients[i];
00916
00917 b(COST_RISE_POLICY_COUNT*2+2) = -dollar_Constraint;
00918 }
00919 }
00920
00921 static void quadratic_prog( ColumnVector &c, DiagonalMatrix &Q, Matrix &A, ColumnVector &b, ColumnVector &xNames, int loopCountMultiplier ) {
00922
00923 LinearAlgebra::quadratic_prog(c,Q,A,b,xNames, loopCountMultiplier);
00924
00925 }
00926
00927
00928 static void input_Optimize_policy_ver2(
00929 Revenue_and_Expense& Base_Budget,
00930 Revenue_and_Expense& Base_Actual,
00931
00932 float PL_Policy_Array_S1[REVENUE_POLICY_COUNT+EXPENSE_POLICY_COUNT][4],
00933
00934 float PL_Policy_Array_S2[COST_RISE_POLICY_COUNT][4],
00935 double& inflation, double& Base_tuition_rate,
00936 double& Base_enrollment, double& Target_enrollment, double& Actual_enrollment,
00937 double& Base_endowmentMV,double& Base_OpResBalance,
00938 float& ST_int_rate_01Aug, float& ST_int_rate_31Aug,
00939 double& New_Debt_service ) {
00940
00941
00942
00943 int i;
00944
00945 if( info.prerun_year && info.game_year == 1 ) {
00946 for( i = 0; i < REVENUE_ITEM_COUNT; ++i ) {
00947 Base_Budget.Revenue_Array[i][0] = 0.0;
00948 Base_Budget.Revenue_Array[i][1] = finance.revenue_array[i].direct;
00949 Base_Budget.Revenue_Array[i][2] = finance.revenue_array[i].indirect;
00950 Base_Budget.Revenue_Array[i][3] = finance.revenue_array[i].total;
00951 }
00952 for( i = 0; i < EXPENSE_ITEM_COUNT; ++i ) {
00953 Base_Budget.Expense_Array[i][0] = finance.expense_array[i].faculty;
00954 Base_Budget.Expense_Array[i][1] = finance.expense_array[i].staff;
00955 Base_Budget.Expense_Array[i][2] = finance.expense_array[i].other;
00956 Base_Budget.Expense_Array[i][3] = finance.expense_array[i].total;
00957 }
00958 }
00959 else {
00960 for( i = 0; i < REVENUE_ITEM_COUNT; ++i ) {
00961 Base_Budget.Revenue_Array[i][0] = 0.0;
00962 Base_Budget.Revenue_Array[i][1] = finance.projected_revenue_array[i].month_start.direct;
00963 Base_Budget.Revenue_Array[i][2] = finance.projected_revenue_array[i].month_start.indirect;
00964 Base_Budget.Revenue_Array[i][3] = finance.projected_revenue_array[i].month_start.total;
00965 }
00966 for( i = 0; i < EXPENSE_ITEM_COUNT; ++i ) {
00967 Base_Budget.Expense_Array[i][0] = finance.projected_expense_array[i].month_start.faculty;
00968 Base_Budget.Expense_Array[i][1] = finance.projected_expense_array[i].month_start.staff;
00969 Base_Budget.Expense_Array[i][2] = finance.projected_expense_array[i].month_start.other;
00970 Base_Budget.Expense_Array[i][3] = finance.projected_expense_array[i].month_start.total;
00971 }
00972 }
00973
00974 if( info.prerun_year && info.game_year == 1 ) {
00975 for( i = 0; i < REVENUE_ITEM_COUNT; ++i ) {
00976 Base_Actual.Revenue_Array[i][0] = 0.0;
00977 Base_Actual.Revenue_Array[i][1] = finance.revenue_array[i].direct;
00978 Base_Actual.Revenue_Array[i][2] = finance.revenue_array[i].indirect;
00979 Base_Actual.Revenue_Array[i][3] = finance.revenue_array[i].total;
00980 }
00981 for( i = 0; i < EXPENSE_ITEM_COUNT; ++i ) {
00982 Base_Actual.Expense_Array[i][0] = finance.expense_array[i].faculty;
00983 Base_Actual.Expense_Array[i][1] = finance.expense_array[i].staff;
00984 Base_Actual.Expense_Array[i][2] = finance.expense_array[i].other;
00985 Base_Actual.Expense_Array[i][3] = finance.expense_array[i].total;
00986 }
00987 }
00988 else {
00989 for( i = 0; i < REVENUE_ITEM_COUNT; ++i ) {
00990 Base_Actual.Revenue_Array[i][0] = 0.0;
00991 Base_Actual.Revenue_Array[i][1] = finance.projected_revenue_array[i].this_year.direct;
00992 Base_Actual.Revenue_Array[i][2] = finance.projected_revenue_array[i].this_year.indirect;
00993 Base_Actual.Revenue_Array[i][3] = finance.projected_revenue_array[i].this_year.total;
00994 }
00995 for( i = 0; i < EXPENSE_ITEM_COUNT; ++i ) {
00996 Base_Actual.Expense_Array[i][0] = finance.projected_expense_array[i].this_year.faculty;
00997 Base_Actual.Expense_Array[i][1] = finance.projected_expense_array[i].this_year.staff;
00998 Base_Actual.Expense_Array[i][2] = finance.projected_expense_array[i].this_year.other;
00999 Base_Actual.Expense_Array[i][3] = finance.projected_expense_array[i].this_year.total;
01000 }
01001 }
01002
01003 for( i = 0; i < REVENUE_POLICY_COUNT; ++i ) {
01004
01005 PL_Policy_Array_S1[i][0] = (float)finance.revenue_policy_array[i].target_value / 100.0f;
01006
01007 PL_Policy_Array_S1[i][1] = (float)finance.revenue_policy_array[i].lower_bound / 100.0f;
01008
01009 PL_Policy_Array_S1[i][2] = (float)finance.revenue_policy_array[i].upper_bound / 100.0f;
01010
01011 PL_Policy_Array_S1[i][3] = (float)finance.revenue_policy_array[i].import_weight;
01012 if( finance.revenue_policy_array[i].required_flag ) {
01013
01014 PL_Policy_Array_S1[i][1] = PL_Policy_Array_S1[i][2] = (float)finance.revenue_policy_array[i].target_value / 100.0f;
01015 PL_Policy_Array_S1[i][3] = OPT_HIGH_WEIGHT * 10;
01016 }
01017 }
01018 for( i = 0; i < EXPENSE_POLICY_COUNT; ++i ) {
01019
01020 PL_Policy_Array_S1[REVENUE_POLICY_COUNT+i][0] = (float)finance.expense_policy_array[i].target_value / 100.0f;
01021
01022 PL_Policy_Array_S1[REVENUE_POLICY_COUNT+i][1] = (float)finance.expense_policy_array[i].lower_bound / 100.0f;
01023
01024 PL_Policy_Array_S1[REVENUE_POLICY_COUNT+i][2] = (float)finance.expense_policy_array[i].upper_bound / 100.0f;
01025
01026 PL_Policy_Array_S1[REVENUE_POLICY_COUNT+i][3] = (float)finance.expense_policy_array[i].import_weight;
01027 if( finance.expense_policy_array[i].required_flag ) {
01028
01029 PL_Policy_Array_S1[REVENUE_POLICY_COUNT+i][1] = PL_Policy_Array_S1[REVENUE_POLICY_COUNT+i][2] = (float)finance.expense_policy_array[i].target_value / 100.0f;
01030 PL_Policy_Array_S1[REVENUE_POLICY_COUNT+i][3] = OPT_HIGH_WEIGHT * 10;
01031 }
01032 }
01033
01034 for( i = 0; i < COST_RISE_POLICY_COUNT; ++i ) {
01035 PL_Policy_Array_S2[i][0] = (float)finance.cost_rise_policy_array[i].target_value / 100.0f;
01036 PL_Policy_Array_S2[i][1] = (float)finance.cost_rise_policy_array[i].lower_bound / 100.0f;
01037 PL_Policy_Array_S2[i][2] = (float)finance.cost_rise_policy_array[i].upper_bound / 100.0f;
01038 PL_Policy_Array_S2[i][3] = (float)finance.cost_rise_policy_array[i].import_weight;
01039 if( finance.cost_rise_policy_array[i].required_flag ) {
01040 PL_Policy_Array_S2[i][1] = PL_Policy_Array_S2[i][2] = (float)finance.cost_rise_policy_array[i].target_value / 100.0f;
01041 PL_Policy_Array_S2[i][3] = OPT_HIGH_WEIGHT * 10;
01042 }
01043 }
01044
01045 inflation = finance.inflation_rate/100.0;
01046 Base_tuition_rate = finance.tuition_rate;
01047
01048 Base_enrollment = (info.prerun_year && info.game_year == 1)
01049 ? enroll_res.total_student_count
01050 : department_array.student_level_history[MAX_STUDENT_LEVEL_TOTAL][HISTORY_YEAR_COUNT-1];
01051 Target_enrollment = enroll_res.target_enrollment[UG_TRADITION] + enroll_res.target_enrollment[UG_NONTRADITION]
01052 + enroll_res.target_enrollment[MASTER] + department_array.student_level_history[DOCTOR][HISTORY_YEAR_COUNT-1];
01053 Actual_enrollment = Target_enrollment;
01054
01055
01056
01057 Base_endowmentMV = investment_office.smoothed_endowment_value + investment_office.smoothed_quasi_endowment_value;
01058
01059 Base_OpResBalance = finance.this_year.asset_array[AC_OPERATING_RESERVE];
01060 ST_int_rate_01Aug = (float)finance.short_term_debt_interest_history[THIS_MONTH-1] / 100.0f;
01061 ST_int_rate_31Aug = (float)finance.short_term_debt_interest_history[THIS_MONTH] / 100.0f;
01062
01063 New_Debt_service = (info.prerun_year && info.game_year == 1)
01064 ? finance.expense_array[AC_SERVICE_ON_GENERAL_PLANT_DEBT].total
01065 : finance.projected_expense_array[AC_SERVICE_ON_GENERAL_PLANT_DEBT].next_year.total;
01066 }
01067 #endif
01068
01069
01071
01072 memset( this, 0, sizeof(Finance) );
01073
01074 fiscal_year_start_month = 9;
01075 fiscal_year_end_month = 8;
01076
01077
01078
01079 inflation_rate = 0.0;
01080 short_term_debt_interest = 3.0;
01081 long_term_debt_interest = 6.0;
01082 debt_fraction_repaid_annually = 4.0;
01083 family_income_growth = 0.0;
01084 construction_cost_growth = 3.0;
01085
01086 building_life_for_calc_depreciation = 50;
01087
01088
01089
01090 investment_office.expected_real_annual_return_rate = 7.0f; endowment_return = 7.0;
01091 sponsored_research_growth = 0.0;
01092 gifts_growth = 0.0;
01093 athletics_revenue_growth = 0.0;
01094 bank_debt_interest = 5.0;
01095 other_expense_growth = 0.5;
01096 other_income_growth = 0.0;
01097
01098
01099
01100
01101 float rate = m.fmax(.01f, math.get_random_snd(.04f, PSCH_SD(.01f))) / 12;
01102
01103
01104 inflation_rate_hist.init(FA_HISTORY_YEAR, 0);
01105 inflation_rate = inflation_rate_hist.get_sum();
01106
01107 err_when(inflation_rate != 0);
01108
01109
01110
01111
01112
01113 int i;
01114
01115
01116 revenue_policy_array[PL_TUITION_RATE_GROWTH].lower_limit = -5;
01117 revenue_policy_array[PL_FINANCIAL_AID].lower_limit = -5;
01118 revenue_policy_array[PL_ENDOWMENT_SPENDING_RATE].lower_limit = 4;
01119 revenue_policy_array[PL_INDIRECT_COST_RATE].lower_limit = 20;
01120
01121 expense_policy_array[0].lower_limit = 0.0;
01122 expense_policy_array[1].lower_limit = 0.0;
01123 expense_policy_array[2].lower_limit = -5;
01124 expense_policy_array[3].lower_limit = -5;
01125 expense_policy_array[4].lower_limit = -3;
01126
01127
01128 revenue_policy_array[PL_TUITION_RATE_GROWTH].upper_limit = 5;
01129 revenue_policy_array[PL_FINANCIAL_AID].upper_limit = 5;
01130 revenue_policy_array[PL_ENDOWMENT_SPENDING_RATE].upper_limit = 10;
01131 revenue_policy_array[PL_INDIRECT_COST_RATE].upper_limit = 70;
01132
01133 expense_policy_array[0].upper_limit = 5.0;
01134 expense_policy_array[1].upper_limit = 5.0;
01135 expense_policy_array[2].upper_limit = 5.0;
01136 expense_policy_array[3].upper_limit = 5.0;
01137 expense_policy_array[4].upper_limit = 3;
01138
01139 revenue_policy_array[0].max_penalty1 = 10;
01140 revenue_policy_array[1].max_penalty1 = 10;
01141 revenue_policy_array[2].max_penalty1 = 5;
01142 revenue_policy_array[3].max_penalty1 = 20;
01143
01144 expense_policy_array[0].max_penalty1 = 20;
01145 expense_policy_array[1].max_penalty1 = 20;
01146 expense_policy_array[2].max_penalty1 = 5;
01147 expense_policy_array[3].max_penalty1 = 10;
01148 expense_policy_array[4].max_penalty1 = 20;
01149
01150 expense_policy_array[0].max_penalty2 = 20;
01151 expense_policy_array[1].max_penalty2 = 20;
01152 expense_policy_array[2].max_penalty2 = 5;
01153 expense_policy_array[3].max_penalty2 = 10;
01154 expense_policy_array[4].max_penalty2 = 20;
01155
01156
01157
01158 for ( i=0; i<REVENUE_POLICY_COUNT; i++) {
01159
01160
01161 revenue_policy_array[i].lower_bound = revenue_policy_array[i].lower_limit;
01162 revenue_policy_array[i].upper_bound = revenue_policy_array[i].upper_limit;
01163 revenue_policy_array[i].import_weight = OPT_MID_WEIGHT;
01164 revenue_policy_array[i].penalty_multiplier1 = 1;
01165 revenue_policy_array[i].penalty_multiplier2 = 1;
01166
01167 set_policy_target(true, i);
01168 }
01169
01170 for ( i=0; i<EXPENSE_POLICY_COUNT; i++) {
01171
01172
01173 expense_policy_array[i].lower_bound = expense_policy_array[i].lower_limit;
01174 expense_policy_array[i].upper_bound = expense_policy_array[i].upper_limit;
01175 expense_policy_array[i].import_weight = OPT_MID_WEIGHT;
01176 expense_policy_array[i].penalty_multiplier1 = 1;
01177 expense_policy_array[i].penalty_multiplier2 = 1;
01178
01179 set_policy_target(false, i);
01180 }
01181
01182
01183
01184 revenue_policy_array[0].lower_bound = 0;
01185
01186
01187 for (i=0; i<REVENUE_POLICY_COUNT; i++) {
01188 revenue_policy_array[i].reset_change(true);
01189 revenue_policy_array[i].bound_correction();
01190 revenue_policy_array[i].penalty_direction = NEGATIVE;
01191 }
01192
01193 for (i=0; i<EXPENSE_POLICY_COUNT; i++) {
01194 expense_policy_array[i].reset_change(true);
01195 expense_policy_array[i].bound_correction();
01196 expense_policy_array[i].penalty_direction = NEGATIVE;
01197 }
01198
01199 revenue_policy_array[PL_TUITION_RATE_GROWTH].penalty_direction = POSITIVE;
01200 revenue_policy_array[PL_INDIRECT_COST_RATE].penalty_direction = POSITIVE;
01201
01202
01203
01204
01205
01206 cost_rise_policy_array[0].target_value = 0.0;
01207 cost_rise_policy_array[1].target_value = 0.0;
01208 cost_rise_policy_array[2].target_value = 0.0;
01209 cost_rise_policy_array[3].target_value = 0.0;
01210 cost_rise_policy_array[4].target_value = 0.0;
01211
01212 cost_rise_policy_array[5].target_value = 0.0;
01213 cost_rise_policy_array[6].target_value = 0.0;
01214 cost_rise_policy_array[7].target_value = 0.0;
01215 cost_rise_policy_array[8].target_value = 0.0;
01216 cost_rise_policy_array[9].target_value = 0.0;
01217
01218 cost_rise_policy_array[0].lower_bound = -5;
01219 cost_rise_policy_array[1].lower_bound = -5;
01220 cost_rise_policy_array[2].lower_bound = -5;
01221 cost_rise_policy_array[3].lower_bound = -5;
01222 cost_rise_policy_array[4].lower_bound = -5;
01223
01224 cost_rise_policy_array[5].lower_bound = -5;
01225 cost_rise_policy_array[6].lower_bound = -5;
01226 cost_rise_policy_array[7].lower_bound = -5;
01227 cost_rise_policy_array[8].lower_bound = -5;
01228 cost_rise_policy_array[9].lower_bound = -5;
01229
01230 cost_rise_policy_array[0].upper_bound = 5;
01231 cost_rise_policy_array[1].upper_bound = 5;
01232 cost_rise_policy_array[2].upper_bound = 5;
01233 cost_rise_policy_array[3].upper_bound = 5;
01234 cost_rise_policy_array[4].upper_bound = 5;
01235
01236 cost_rise_policy_array[5].upper_bound = 5;
01237 cost_rise_policy_array[6].upper_bound = 5;
01238 cost_rise_policy_array[7].upper_bound = 5;
01239 cost_rise_policy_array[8].upper_bound = 5;
01240 cost_rise_policy_array[9].upper_bound = 5;
01241
01242 cost_rise_policy_array[0].max_penalty1 = 5;
01243 cost_rise_policy_array[1].max_penalty1 = 10;
01244 cost_rise_policy_array[2].max_penalty1 = 5;
01245 cost_rise_policy_array[3].max_penalty1 = 50;
01246 cost_rise_policy_array[4].max_penalty1 = 5;
01247
01248 cost_rise_policy_array[5].max_penalty1 = 5;
01249 cost_rise_policy_array[6].max_penalty1 = 50;
01250 cost_rise_policy_array[7].max_penalty1 = 10;
01251 cost_rise_policy_array[8].max_penalty1 = 10;
01252 cost_rise_policy_array[9].max_penalty1 = 50;
01253
01254 cost_rise_policy_array[0].max_penalty2 = 0;
01255 cost_rise_policy_array[1].max_penalty2 = 0;
01256 cost_rise_policy_array[2].max_penalty2 = 5;
01257 cost_rise_policy_array[3].max_penalty2 = 10;
01258 cost_rise_policy_array[4].max_penalty2 = 0;
01259
01260 cost_rise_policy_array[5].max_penalty2 = 50;
01261 cost_rise_policy_array[6].max_penalty2 = 0;
01262 cost_rise_policy_array[7].max_penalty2 = 0;
01263 cost_rise_policy_array[8].max_penalty2 = 0;
01264 cost_rise_policy_array[9].max_penalty2 = 0;
01265
01266 for ( i=0; i<COST_RISE_POLICY_COUNT; i++) {
01267 cost_rise_policy_array[i].lower_limit = -5.0;
01268 cost_rise_policy_array[i].upper_limit = 5.0;
01269 cost_rise_policy_array[i].import_weight = OPT_MID_WEIGHT;
01270 cost_rise_policy_array[i].penalty_multiplier1 = 1;
01271 cost_rise_policy_array[i].penalty_multiplier2 = 1;
01272 }
01273
01274
01275 for ( i=0; i<COST_RISE_POLICY_COUNT; i++) {
01276 cost_rise_policy_array[i].bound_correction();
01277 cost_rise_policy_array[i].reset_change(true);
01278 cost_rise_policy_array[i].penalty_direction = NEGATIVE;
01279 }
01280 }
01281
01282
01283
01284
01286
01287
01288 }
01289
01290
01291
01292
01300
01301 PeerSchool *playerSchoolEx = school_res.player_peer_school;
01302
01303
01304
01305 tuition_rate = playerSchoolEx->tuition_rate;
01306 }
01307
01308 void Finance::init_data() {
01309 int i;
01310 PeerSchool *playerSchoolEx = school_res.player_peer_school;
01311
01312
01313
01314 int totalFacResearchExpense = 0;
01315 int d;
01316
01317 Department *dept;
01318
01319 for ( d=department_array.size(); d>0; d-- ) {
01320 if ( department_array.is_deleted(d) )
01321 continue;
01322
01323 dept = department_array[d];
01324
01325 dept->calc_research_dollar();
01326
01327
01328
01329 totalFacResearchExpense += dept->total_research_dollar /1000;
01330 }
01331
01332 int totalResearchExpense = 0;
01333
01334
01335 totalResearchExpense = int( 12 * totalFacResearchExpense );
01336
01337
01338
01339 memset( last_year.asset_array, 0, sizeof(last_year.asset_array) );
01340 memset( last_year.liability_array, 0, sizeof(last_year.liability_array) );
01341
01342
01343 last_year.asset_array[AC_OPERATING_RESERVE] = playerSchoolEx->operating_reserve * 1.3;
01344 #if(GAME_VERSION>=200)
01345 this_year.asset_array[AC_OPERATING_RESERVE] = last_year.asset_array[AC_OPERATING_RESERVE];
01346 #endif
01347 last_year.asset_array[AC_ENDOWMENT] = playerSchoolEx->endowment_market;
01348