• No results found

This code is also available on https://gist.github.com/c8e3699a46c629b5cbdb

package SA;

/** current output SA: Starting Application === Binary options (0, 1) Total amount of criteria: 16

Total amount of combinations: 65536 Favor Native: 38360

Favor Hybrid: 6960 Favor Web: 11396 No Favor: 8820

Now with minimum of 5 criteria (total of: 16)

Total amount of combinations: 63019 (total of: 65536) Favor Native: 37150 (total of: 38360)

Favor Hybrid: 6731 (total of: 6960) Favor Web: 10729 (total of: 11396) No Favor: 8409 (total of: 8820)

=== Ternary option (-1, 0, 1) Total amount of criteria: 16

Total amount of combinations: 43046721 Favor Native: 16635006

Favor Hybrid: 4361872 Favor Web: 18145746 No Favor: 3904097

Now with minimum of 5 criteria (total of: 16)

Total amount of combinations: 43012608 (total of: 43046721) Favor Native: 16622515 (total of: 16635006)

Favor Hybrid: 4358913 (total of: 4361872) Favor Web: 18131918 (total of: 18145746) No Favor: 3899262 (total of: 3904097) SA: Ending Application

*/

/**

* class SA :: Sensitivity Analysis

* This class takes a weighted decision matrix, and calculates all possible scenarios; by enabling or disabling criteria

* The summary shows which platform is favored, based on the weights of the criteria

* @Author: Ernst Fluttert * @Date: 29 august 2012 */

public class SA {

// outcome variables private int outcomeWeb; private int outcomeWebMC; private int outcomeNative; private int outcomeNativeMC; private int outcomeHybrid; private int outcomeHybridMC;

private int outcomeUndecided; private int outcomeUndecidedMC; private int outcomeTotal; private int outcomeTotalMC;

private int minimumCriteria = 5; // only count with minimum amount of

involved criteria

// list of criteria, each with 4 weights (impact, native, hybrid, web)

private int[][] criteria; // the list of criteria

private String[] criteriaNames; // name of the criteria

// constructor, initializes the numbers and criteria public SA(){

// put counters on 0 resetCounter();

criteria = new int[16][4];

// === criteria (weight, native, hybrid, web) // C1 connectivity (offline access?)

criteria[0] = new int[]{2, 2, 1, -1}; // C2 Device Sensor usage

criteria[1] = new int[]{2, 2, 1, -1}; // C3 Market (app must be in market) criteria[2] = new int[]{2, 2, 2, 0}; // C4 Amount of platforms (more than 1?) criteria[3] = new int[]{3, 0, 1, 2};

// C5 Mechanisms (do you need native functions) criteria[4] = new int[]{2, 2, 1, -1};

// C6 Content (text and image only?) criteria[5] = new int[]{2, 0, 1, 2};

// C7 Updatability (multiple versions planned?) criteria[6] = new int[]{1, 0, 1, 2};

// C8 personalisation (personalized content) criteria[7] = new int[]{1, 2, 1, 0};

// C9 responsiveness (immediate vs delayed) criteria[8] = new int[]{1, 2, 1, 0};

// C10 native ui elements like hardware buttons and look and feel criteria[9] = new int[]{1, 2, 0, 0};

// C11 Screensize, also support pads? criteria[10] = new int[]{1, 0, 1, 2};

// C12 heterogeneity device number of hardware devices criteria[11] = new int[]{1, 0, 2, 2};

// C13 user expectation, high expectation? criteria[12] = new int[]{1, 2, 1, 0};

// C14 Encrypted data?

criteria[13] = new int[]{1, 2, 1, 2}; // C15 Market fee: use transactions? criteria[14] = new int[]{1, 0, 0, 2}; // C16 market regulations

criteria[15] = new int[]{1, 0, 0, 2}; }

// reset the counters to zero public void resetCounter(){

outcomeWeb = 0; outcomeWebMC = 0; outcomeNative = 0; outcomeNativeMC = 0; outcomeHybrid = 0; outcomeHybridMC = 0; outcomeUndecided = 0; outcomeUndecidedMC = 0; outcomeTotal = 0; outcomeTotalMC = 0; }

// function run: starts the test. Calculates all possible mutations, and passes this off for analysis

public void run(){

// determine number of criteria

int numberOfCriteria = criteria.length; // First Run: binary choices ( 0 , 1) binaryChoice(numberOfCriteria);

System.out.println("=== Binary options (0, 1) "); stats();

// reset stats before second run resetCounter();

// Second Run: Ternary choice ( -1 , 0, and 1) ternaryChoice(0, numberOfCriteria, "");

System.out.println(" ");

System.out.println("=== Ternary option (-1 , 0, 1) "); stats();

}

// all possibilities for a binary option (yes or no) public void binaryChoice(int numberOfCriteria){

// to calculate every combination of criteria (either on or off)

// This is done by taking taking 2 to the power of number of criteria ( 3 criteria would yield 8 possibilities, 5 criteria would yield 32 etc)

for (int i = 0; i < Math.pow(2, numberOfCriteria); i++) {

// the magic step is to create the binary representation of the number

String binaryRep = Integer.toBinaryString(i); while (binaryRep.length() < numberOfCriteria){ // is it the specified length?, output should be

binaryRep = "0" + binaryRep; // add leading zero's

}

calcRow(binaryRep, true); // process

the criteria as binary }

}

// all possibilities for a ternary option ( inverse norm - doesnt apply - norm)

public void ternaryChoice(int depth, int maxdepth, String row){ if(depth == maxdepth){

// maximum depth reached please calculate the values per platforms calcRow(row, false); // process criteria as ternary

return; // done with recursion :P

} else{

String origRow = row; for(int i = 0; i<3; i++){

//System.out.println("i="+i+" depth:"+ (depth+1) + " maxdepth:"+maxdepth);

// continue with recursion

ternaryChoice(depth+1, maxdepth, origRow+i); }

} }

// function calcRow: Takes a binary string (like "0011101010"), and calculates the weight per platform, based on the weight specified in the constructor

public void calcRow(String cr, boolean binary){ // convert the string to a character array char[] crt = cr.toCharArray();

int correction = 0;

if(!binary){correction = 1;}

// cr = current row. This is a string with 0 or 1 for each criteria // cr[0,1,0] = only the second criteria is enabled. Please calculate the result of this for each platform

int on = 0; // native platform

int oh = 0; // hybrid platform

int ow = 0; // web platform

int crl = crt.length; // length of row

int ec = 0; // number of enabled criteria

// determine if minimum amount of criteria is applied for(int z=0; z<crl; z++){

int curval = (Integer.parseInt( Character.toString(crt[z]) ) - correction);

if(curval== -1 || curval == 1 ){ec++;} }

// process the string again for values for(int z=0; z<crl; z++){

//System.out.println("crl: "+ crl +" z:" + z + " on:" + on + " crt(z):" + (crt[z]) + " (int)crt[z]: " + Integer.parseInt(

Character.toString(crt[z]) ) );

// SUM the enabled criteria * weight of criteria * impact on implementation platform

int enabled = (Integer.parseInt( Character.toString(crt[z]) ) - correction);

on += ( enabled * criteria[z][0] * criteria[z][1]); oh += ( enabled * criteria[z][0] * criteria[z][2]);

ow += ( enabled * criteria[z][0] * criteria[z][3]); }

//System.out.println(cr + " == "+ on + " " + oh + " "+ ow ); // analyse and process the score for this sequence of criteria analyseResult(on,oh,ow, ec);

}

/** function analyseResult :: compares the scores per platform and decides which has the highest score

* @param on : OutcomeNative , the score of the native platform * @param oh : OutcomeHybrid , the score of the hybrid platform * @param ow : OutComeWeb , the score of the web platform * @param ec : EnabledCriteria , the amount of enabled criteria */

public void analyseResult(int on, int oh, int ow, int ec){ // process normal results

if(on > oh && on > ow){outcomeNative++;} // native has highest

score

else {

if(oh > on && oh > ow){outcomeHybrid++;} // hybrid has highest score

else{

if(ow > on && ow > oh){outcomeWeb++;} // web has highest

score

else{

// there is no highest, so it is undecided outcomeUndecided++;

} } }

outcomeTotal++; // check if all

possibilities are checked (double check feature) // process if minimum amount is satisfied if(ec >= minimumCriteria){

if(on > oh && on > ow){outcomeNativeMC++;} // native has

highest score

else {

if(oh > on && oh > ow){outcomeHybridMC++;} // hybrid has

highest score

else{

if(ow > on && ow > oh){outcomeWebMC++;} // web has

highest score

else{

// there is no highest, so it is undecided outcomeUndecidedMC++;

} } }

outcomeTotalMC++; //

check if all possibilities are checked (double check feature) }

}

// print the stats public void stats(){

System.out.println("Total amount of criteria: " + criteria.length); System.out.println("Total amount of combinations: " + outcomeTotal);

System.out.println("Favor Native: " + outcomeNative); System.out.println("Favor Hybrid: " + outcomeHybrid); System.out.println("Favor Web: " + outcomeWeb); System.out.println("No Favor: " + outcomeUndecided); if(minimumCriteria > 0){

System.out.println("");

System.out.println("Now with minimum of " + minimumCriteria + " criteria (total of: " + criteria.length + ")");

System.out.println("Total amount of combinations: " + outcomeTotalMC + " (total of: " + outcomeTotal + ")");

System.out.println("Favor Native: " + outcomeNativeMC + " (total of: " + outcomeNative + ")");

System.out.println("Favor Hybrid: " + outcomeHybridMC + " (total of: " + outcomeHybrid + ")");

System.out.println("Favor Web: " + outcomeWebMC + " (total of: " + outcomeWeb + ")");

System.out.println("No Favor: " + outcomeUndecidedMC + " (total of: " + outcomeUndecided + ")");

} } /**

* public method main :: Starts the application * @param args

* @return void */

public static void main(String[] args){

System.out.println("SA: Starting Application"); // print to console that program starts

SA analysis = new SA(); analysis.run();

System.out.println("SA: Ending Application"); // print to console that program starts

} // end main }