Esempio n. 1
0
static void print_vector(c_vector * p)
{
    c_iterator first, last;
    first = c_vector_begin(p);
    last = c_vector_end(p);
    print_vector2(first, last);
}
Esempio n. 2
0
//---------- Begin of function Finance::optimize_policy_3 -----------//
//!
bool Finance::optimize_policy_3() {
    Department *deptPtr;
    int i;
    int deptCount = department_array.department_count;

#ifdef TEST_MATHCA
    deptCount = 10;
#endif

    const double weight_intrinsic = 0.45f;          // c148 Weight on intrinsic value (v. TL)
    //const double weight_response = 0.7f;	// c149 Weight on responsiveness (v. stability)

    err_when(deptCount<=0);

    //----------------------------//

    //ColumnVector avgSalary(deptCount);		// column E 153:162		// $000
    //ColumnVector facCount(deptCount);		// column I 153:162

    //----------------------------// check player input

    //## chea check the total_hires & totaltarget
    int totalupper = 0;
    for (int r=0; r<department_array.department_count; r++ ) {
	HiringPolicy* finPr2 = &(finance.hiring_policy_array[r]);
	totalupper += finPr2 -> upper_bound;
    }

    if (totalupper < total_hires) {
	box.msg("The total of your upper bound values is less than the total faculty you wanted to be hired. ");
	return false;
    }
    //## chea check the total_hires & totaltarget

    ColumnVector targetHire(deptCount), weightsIV3(deptCount), upperBound(deptCount);

    for (i=deptCount; i>0; i--) {
	err_if ( department_array.is_deleted(i) )
	    err_here();

	deptPtr = department_array[i];

	DepartmentInfo* deptInfo = department_res[deptPtr->department_id];

	weightsIV3(i) = (double)1/(double)max( 1,deptPtr->faculty_array.size() );

	//## chea try to avoid the bug below
	if (finance.hiring_policy_array[i-1].upper_bound< finance.hiring_policy_array[i-1].target_value) {
	    finance.hiring_policy_array[i-1].upper_bound = finance.hiring_policy_array[i-1].target_value;
	}

	upperBound(i) = finance.hiring_policy_array[i-1].upper_bound;

	targetHire(i) = finance.hiring_policy_array[i-1].target_value;

	err_when(upperBound(i) < targetHire(i));
    }

#ifdef TEST_MATHCA
    double dummyArr[] = {3,7,13,2,2, 1,5,0,1,4};
    double dummyW[] = {1.000,1.135,1.450,1.000,0.955,1.000,1.000,0.775,1.000,1.000};

    targetHire << dummyArr;
    upperBound << dummyArr;
    weightsIV3 << dummyW;
#endif

    //----------------------------// construct quad_program input matrices PART A

    ColumnVector c(deptCount);
    DiagonalMatrix Q(deptCount);

    c = -SP(targetHire, weightsIV3);
    Q.set_diagonal(weightsIV3);

    //----------------------------//	PART B

    //	for (i=1; i <=deptCount; i++)
    //	{
    //		surplusRHS(1) += avgSalary(i) * facCount(i)  * (1+growthRate);
    //		surplusCoefs3(i) = avgSalary(i) * (1+growthRate);
    //	}

    //	{
    //		double maxSavingAtNewSalary = 0;		// J177

    //		for (i=1; i <=deptCount; i++)
    //		{
    //			maxSavingAtNewSalary += (lowerBound3(i) - facCount(i)) * avgSalary(i) * (1+growthRate);
    //		}

    //		double C136 = finance.cost_rise_policy_array[PL_FACULTY_FTE].result_value / 100;
    //		double C203 = finance.stage1_expense[S1_FACULTY_SALARY_INCREASES].base_value;
    //
    //		#ifdef TEST_MATHCA
    //		surplusRHS(1) += -520.327f;
    //		#else
    //		surplusRHS(1) += max(C136*C203,maxSavingAtNewSalary);	// += i178 where i178=MAX(C136*C203,J177)
    //		#endif
    //	}

    DiagonalMatrix I(deptCount);  I = 1;
    Matrix A = -I;
    ColumnVector b = -upperBound;

    err_when(total_hires<0);                        // check player input

    RowVector tmpList(deptCount); tmpList = 1;
    ColumnVector totalHires(1); totalHires(1) = total_hires;

#ifdef TEST_MATHCA
    err_here();
    totalHires(1) = -10;
    for (i=1;i<=deptCount;i++)
	totalHires(1) += targetHire(i);
#endif

    A = A & -tmpList;
    b = b & -totalHires;

    //----------------------------//	Go run it!

    ColumnVector xNames(deptCount);
    if (!LinearAlgebra::quadratic_prog(c,Q,A,b,xNames))
	return false;

    print_vector2(xNames);

    //----------------------------//

    //int deptCount = department_array.size();
    int resultTotal = 0;                            // 990423
    //int resultArr[MAX_DEPARTMENT];

    // use following procedures :
    // i) find the largest (remaining) value in xNames and round it to the nearest integer.
    //    For ties, just use the department that comes up first in the search
    // ii) if that integer >= 1 put it into the Results vector ELSE put 1 in the result vector
    // iii) repeat from (i) until sum of results equals maxHires. If the value in the (ii)
    // is greate than the remaining hires, use the remaining hires instead of (ii)

    int deptRank;
    double lastXNames;
    int lastDept=0;

    for(deptRank=0; deptRank<deptCount; ++deptRank) {
	int curDept=0;
	double curXNames;
	for( i=1; i<=deptCount; ++i ) {
	    double xNamesValue = xNames(i);

	    // this department has been searched
	    if( lastDept != 0
		&& (xNamesValue > lastXNames || xNamesValue == lastXNames && i <= lastDept) )
		continue;

	    // find the department with maximum xNames
	    if( curDept != 0 && xNamesValue <= curXNames )
		continue;

	    curDept = i;
	    curXNames = xNamesValue;
	}

	// find a department, mark it so next for(deptRank) won't scan it again
	i = lastDept = curDept;
	lastXNames = curXNames;

	int xNamesInt = int( curXNames + 0.5 );       //round to integer

	// at least get 1 place
	// or use ceil((total_hires-resultTotal)/(deptCount-deptRank)), if 1 can't fill up all the vacancies
	xNamesInt = max( xNamesInt, 1 );

	// check remaining
	err_when( resultTotal > total_hires );
	if( xNamesInt > total_hires - resultTotal )
	    xNamesInt = total_hires - resultTotal;

	// place the result and add the total

	finance.hiring_policy_array[curDept-1].result_value = xNamesInt;
	resultTotal += xNamesInt;
    }


    //## chea fix the rounding error

    int counter =0;

    if (resultTotal > total_hires) {
	counter = resultTotal - total_hires;

	//## chea set upper bound to target
	for (int q=0; q<department_array.department_count; q++ ) {
	    HiringPolicy* finPr5 = &(finance.hiring_policy_array[q]);

	    if (finPr5 -> result_value >=1) {
		finPr5 -> result_value --;
		counter--;
	    }

	    if (counter == 0) break;

	}

	resultTotal = total_hires;
    }

    // readjust result_value may cause bug

    int diff = total_hires - resultTotal;
    int deptRecno = 0;

    for (i=0; i<diff; i++) {

	finance.hiring_policy_array[deptRecno].result_value ++;

	if(finance.hiring_policy_array[deptRecno].result_value > 10) {
	    finance.hiring_policy_array[deptRecno].result_value --;
	    diff++;
	}

	if ( ++deptRecno == deptCount )
	    deptRecno = 0;
    }

    //## chea set upper bound to target
    for (int cq=0; cq<department_array.department_count; cq++ ) {
	HiringPolicy* finPr3 = &(finance.hiring_policy_array[cq]);
	//		finPr3 -> target_value = finPr3 -> result_value;				//BUGHERE
	if (finPr3 -> upper_bound < finPr3 -> result_value)
	    finPr3 -> upper_bound = finPr3 -> result_value;
    }

    return true;
}