#include "tool.h" using namespace std; float Distance[RunTotal+1]; float mArray[TotalMitigations+1]; float Data[RunTotal+1][TotalMitigations+2]; int mCounter,era,run,TotalInstances,instanceCounter; float MinCost,MaxCost,MinAtt,MaxAtt; float infinity,small; int singletonFlag; int main(int argc, char *argv) { srand((unsigned int)time(NULL)); WhichStack *stack = new WhichStack( TotalMitigations ); //Each entry in stack is a singleton at first. //Each time a singletong is created, all other symbols are assigned to be 0 and the score is returned. singletonFlag = 1; for ( int att = 1; att <= 99; att++ ) { for ( int val = 0; val < 2; val++ ) { int attVal[2] = { att, val }; stack->push( attVal, tool ); } } singletonFlag = 0; //from now on, each time an entry is created, a certain number of times 0 or 1 is randomly assigned to d=-1 (don't care) symbols and median score is returned. stack->select( 2000, 200, 0.2 ); Rule *r = stack->getBest(); float m[TotalMitigations+1]; ruleToModel( r, m ); Components *bestCom = (Components*)(r->getComponent()); for ( int i = 1; i < TotalMitigations+1; i++ ) if ( m[i] == -1 ) cout << 'd'; else cout << m[i]; cout << endl; if ( bestCom != NULL ) cout << "Cost: " << bestCom->mCost << ", " << "Attainment: " << bestCom->mAtt << endl; else cout << r->getRuleSet()->size() << endl; return 0; } void ruleToModel( Rule *rule, float m[] ) { //this function is needed since a rule must be converted into an array of mitigations with values set to 0 or 1. vector< DisjunctionSet * > *attVals = rule->getRuleSet(); for ( int i = 1; i <= TotalMitigations; i++ ) m[i] = -1; for ( unsigned int att = 0; att < attVals->size(); att++ ) { cout << attVals->at( att )->mAttribute << endl; m[ attVals->at( att )->mAttribute ] = attVals->at( att )->mValues[0]; } } float tool(Rule *rule) { float FixedMitigations[TotalMitigations+1]; ruleToModel( rule, FixedMitigations ); infinity = pow((float)10,(float)20); small = pow((float)10,(float)-20); float att, cost, median, medianCost, medianAtt; TotalInstances = 0; MinCost = infinity; MaxCost = -infinity; MinAtt = infinity; MaxAtt = -infinity; if (singletonFlag == 0) { for (run = 1; run <= RunTotal; run++) { for (mCounter = 1; mCounter <= TotalMitigations; mCounter++) { //if in the previous runs the mitigation is fixed to a certain value (0 or 1) then use that value. otherwise, select it at random if (FixedMitigations[mCounter] == -1) mArray[mCounter] = selectValue(0,1); else mArray[mCounter] = FixedMitigations[mCounter]; } //find the cost and att using these mitigations model(&cost,&att,mArray); //store the current instance addInstance(cost,att); } //find the distances from sweet spot for each instance findDistanceSweetSpot(); median = medianScore(&medianCost, &medianAtt); Components *com = new Components(); com->mCost = medianCost; com->mAtt = medianAtt; rule->setComponent( (void *)com ); cout << "The score is: " << median << endl; } else { Components *com = new Components(); com->mCost = 0; com->mAtt = 0; rule->setComponent( (void *)com ); median = (float)(rand()/((double)(RAND_MAX)+(double)(1)) * 0.0001); } return -median; } float medianScore(float *medianCost, float* medianAtt) { float returnValue; float tempValue; int i,j,firstIndex,secondIndex; float tempArray[TotalInstances]; for (i = 1; i <= TotalInstances; i++) tempArray[i] = Distance[i]; for (i = 1; i <= TotalInstances; i++) { tempValue = tempArray[i]; j = i; while ((j > 1) && (tempArray[j-1] > tempValue)) { tempArray[j] = tempArray[j-1]; j = j - 1; } tempArray[j] = tempValue; } ///find the median score according to the number of elements in the array //also, find the cost and attainment for that score in the same fashion if (TotalInstances % 2 == 0) { returnValue = (tempArray[TotalInstances/2] + tempArray[TotalInstances/2 + 1])/2; for (i = 1; i <= TotalInstances; i++) { if (Distance[i] == tempArray[TotalInstances/2]) firstIndex = i; if (Distance[i] == tempArray[TotalInstances/2 + 1]) secondIndex = i; } *medianCost = (Data[firstIndex][1] + Data[secondIndex][1])/2; *medianAtt = (Data[firstIndex][2] + Data[secondIndex][2])/2; } else { returnValue = tempArray[(TotalInstances+1)/2]; for (i = 1; i <= TotalInstances; i++) { if (Distance[i] == tempArray[(TotalInstances+1)/2]) firstIndex = i; } *medianCost = Data[firstIndex][1]; *medianAtt = Data[firstIndex][2]; } /* returnValue = tempArray[TotalMitigations]; for (i = 1; i <= TotalInstances; i++) { if (Distance[i] == returnValue) firstIndex = i; } *medianCost = Data[firstIndex][1]; *medianAtt = Data[firstIndex][2]; */ return returnValue; } void findDistanceSweetSpot() { float normalizedCost,normalizedAtt; //normalize the att and cost using their for (instanceCounter = 1; instanceCounter <= TotalInstances; instanceCounter++) { //calculate the normalized cost and att (if max and min are the same, the small numbers added allow the distance to be correct) normalizedCost = (Data[instanceCounter][1] - MinCost)/(MaxCost - MinCost + small); normalizedAtt = (Data[instanceCounter][2] - MinAtt)/(MaxAtt - MinAtt + small); //distance of each instance is measured from normalized (cost=0,att=1) which is the sweet spot //It is returned as -1 * distance since it is going to be used as a score and the higher the score (the lower the distance) the better it is Distance[instanceCounter] = (-1) * pow( pow((float)(normalizedCost - 0),(float)2) + pow((float)(normalizedAtt - 1), (float)2),(float)0.5); } } int selectValue(int val1, int val2) { double randomValue = (double)rand()/((double)(RAND_MAX)+(double)(1)); int returnValue; if (randomValue < 0.5) returnValue = val1; else returnValue = val2; return returnValue; } void addInstance(float costVar, float attVar) { TotalInstances++; Data[TotalInstances][1] = costVar; Data[TotalInstances][2] = attVar; for (mCounter = 1; mCounter <= TotalMitigations; mCounter++) Data[TotalInstances][mCounter+2] = mArray[mCounter]; if (MinCost > Data[TotalInstances][1]) MinCost = Data[TotalInstances][1]; if (MaxCost < Data[TotalInstances][1]) MaxCost = Data[TotalInstances][1]; if (MinAtt > Data[TotalInstances][2]) MinAtt = Data[TotalInstances][2]; if (MaxAtt < Data[TotalInstances][2]) MaxAtt = Data[TotalInstances][2]; MinAtt = 0; MinCost = 0; MaxAtt = 265; MaxCost = 1450245; } float minValue(float val1, float val2) { if (val1 < val2) return val1; else return val2; }