Channels ▼
RSS

Parallel

Autonomic Delivery of Expertise via Web Services

Source Code Accompanies This Article. Download It Now.


October, 2004: Autonomic Delivery of Expertise via Web Services

Are you getting the job done?

Mike is an IBM certified senior project manager and can be contacted at fichtelmus.ibm.com.


One of the best indicators of project trouble is a quantifiable measure known as "earned value analysis." If practiced diligently and appropriately, earned value analysis lets you know about a wall before you hit it. For a number of reasons, this has obvious advantages. First, from the perspective of managing a portfolio of projects, projects at risk can be assessed and killed before spiraling into a nosedive. Second, at the individual project level, an earned value analysis that flags trouble ahead can provide the leverage needed for replanning, additional resources, and other forms of mitigation. It's certainly not the only measure of project success or failure and it doesn't address projects as investments the way Net Present Value or Internal Rate of Return do, but earned value can help you decide whether you're throwing good money after bad.

The purpose of earned value analysis is to answer one simple question: Are you getting the job done? In broad terms, it lets you assess how well or how poorly you're doing. Earned value analysis explores the relationships between three values expressed in dollars:

  • The first value is the Budgeted Cost for Work Scheduled (BCWS), which expresses how much work is planned to be done.
  • The second value is the Actual Cost of Work Performed (ACWP), which expresses the actual cost of the work that's already been done on the project (or task).
  • The final value is the Budgeted Cost for Work Performed (BCWP), also known as "earned value" (EV), which expresses how much work has actually been done on the project.

The relationships between BCWS, ACWP, and BCWP are expressed as four other values:

  • The Cost Variance (CV) equals BCWP minus ACWP and expresses the relationship between the amount of work that actually has been done and what it actually cost to do it. Under ideal circumstances, the CV should be equal to zero.
  • The second value is Schedule Variance (SV) and is equal to BCWP minus BCWS. SV expresses the relationship between the amount of work that's actually been done and the amount of work that you planned to do. Again, under ideal circumstances, the SV should equal zero.
  • The third value is the Cost Performance Index (CPI), which is equal to BCWP divided by ACWP.
  • The fourth value is the Schedule Performance Index (SPI) and is equal to BCWP divided by BCWS. Both are measures of efficiency.

This is all fairly straightforward, but examples clarify further. Assume that a project has a Budgeted Cost of Work Scheduled of $800,000, an Actual Cost of Work Performed of $800,000, and a Budgeted Cost of Work Performed of $800,000. In this case, you would generate a Cost Variance of 0, a Schedule Variance of 0, a Cost Performance Index of 1 (100 percent), and a Schedule Performance Index of 1 (100 percent). This is the ideal situation because we are operating at 100-percent efficiency and our estimates correspond exactly with our actual performance. Further assume that another project has a Budgeted Cost of Work Scheduled of $800,000, but an Actual Cost of Work Performed of $600,000, and a Budgeted Cost of Work Performed of $400,000. In this case, you would generate a negative Cost Variance of $200,000, a negative Schedule Variance of $400,000, a Cost Performance Index of 0.66 (66 percent), and a Schedule Performance Index of 0.5 (50 percent). This is a bad situation because you are operating at only 66 percent efficiency, we are well behind schedule, and we are burning money. If this information was available early on, it might be possible either to fix matters or cancel the project to avoid a costly failure. Now assume that a final example project has a Budgeted Cost of Work Scheduled of $800,000, an Actual Cost of Work Performed of $600,000, and a Budgeted Cost of Work Performed of $1,000,000. In this case, we would generate a positive Cost Variance of $400,000, a positive Schedule Variance of $200,000, a Cost Performance Index of 1.6 (160 percent), and a Schedule Performance Index of 1.25 (125 percent). This is that rare and glorious situation in which the project team is given a vacation in Hawaii. The only downside here is that estimates may be called into question because resources may have been allocated to this project that could have been better applied elsewhere.

This is certainly not rocket science and the value of the information provided is fairly obvious. What may not be obvious, and what might qualify as rocket science, is the application of an expert system utilizing fuzzy reasoning to provide consistent determination on what constitutes a good, bad, or adequate project. Capturing human judgment, then delivering and applying it uniformly and consistently throughout an organization is one of the chief values of expert system technology.

The Earned Value Application

The earned value application I present here is a Service-Oriented Architecture (SOA) application designed to deliver projections on the risk associated with a project. This risk assessment is derived from a rule-based expert system that employs fuzzy logic to reason and make conclusions from the information provided. The rule-based expert system is invoked from a JavaBean that, in turn, can be accessed and invoked over an SOA using web-services technology. It is not essential that a GUI is used to access the web service, but I've provided one for demonstration purposes. An alternative would be to access the web service from another project-management application using SOAP and XML.

Developed at IBM's T.J. Watson Research Center, the Agent Building and Learning Environment (ABLE) is a complete environment for designing, testing, and implementing Java-based artificial intelligence agents (http://www.alphaworks.ibm.com/tech/able/). In terms of artificial intelligence features supported, ABLE is comprehensive and one would be hard pressed to think of an artificial intelligence paradigm that it does not employ.

Each paradigm is implemented as a JavaBean, and the collected beans are called "AbleBeans." While in this article I focus only on a single paradigm—that of rule-based fuzzy-logic expert systems—there are many others, including:

  • Temporal Difference Learning.
  • Naïve Bayes.
  • Radial Basis Function.
  • Decision Tree.
  • K Nearest Neighbor.
  • Neural Network Prediction.
  • Kohonen Self Organizing Map Neural Network.
  • Clustering Neural Network.
  • Genetic Search.

In addition to these AI paradigms, ABLE provides agent beans for buyer/seller conversation logic and for developing agents to automatically tune (autotune) computer systems and networks.

There is also a complete ABLE Ruleset Language (ARL) for incorporating expert system paradigms into an application. Rulesets are developed by using the ruleset editor supplied with ABLE. Simply execute the RunRsEditor command (located in the able/bin directory) as appropriate for the operating system. The ruleset editor provides a GUI, similar to a wordprocessor but with the specific purpose of developing and testing rulesets using the ABLE Ruleset Language (ARL). ARL is extremely comprehensive and its similarity to Java makes it relatively easy for Java programmers to learn and use. ARL provides numerous inference engines including forward and backward chaining, predicate calculus, Rete algorithm, and fuzzy logic. I'll be discussing only the fuzzy logic inference engine, so please consult the ABLE documentation for information on the others.

After the ruleset editor is invoked, open the file riskEV.arl; see Figure 1 and Listing One. This particular ruleset has a number of sections. First, there is the ruleset name. Then, there is a set of variable declarations. All the variables declared are Fuzzy variables, with one exception. The fuzzy variables declared are for Budgeted Cost of Work Scheduled, Actual Cost of Work Performed, Budgeted Cost of Work Performed, Cost Variance, Schedule Variance, Schedule Performance Index, and Cost Performance Index. To illustrate, I use the Schedule Performance Index as an example:

Fuzzy SPI = new Fuzzy(0.0, 2.0) {
Linear VeryGood = new Linear (1.5, 2.0, ARL.Up);
Linear Good = new Linear (1.00, 1.5, ARL.Up);
Linear Bad = new Linear ( 0.5, 0.9, ARL.Down);
Linear VeryBad = new Linear ( 0.0, 0.5, ARL.Down);
Triangle Adequate = new Triangle(0.95, 1.0, 1.05);
};

This statement declares a new Fuzzy variable, SPI, which can range in value from 0.0 to 2.0. The SPI variable has a number of Linear properties, which can range in one direction or the other, and a single Triangle property. Note that this is a cardinal value of fuzzy reasoning. Fuzzy logic provides for reasoning with imprecision. Very often, you must reason and make decisions with incomplete information and fuzzy logic lets you codify this capability. For example, I've made the somewhat arbitrary designation that a VeryGood SPI is somewhere in the range of 1.5 to 2.0. Someone else may have said that it should be in the range of 1.7 to 2.0, or perhaps some other value depending on their subjective criteria. While VeryGood can mean a range of values, it cannot mean anything at all. The fuzzy reasoning inference engine lets you codify clearly what might otherwise be a rather vague term. The single variable that is not declared as Fuzzy but as Continuous is SymRating, which is simply the symbolic (A for low risk, B for acceptable risk, or C for high risk). While letter grades have a universal meaning from our shared experience at school, this variable could also have been defined with other values.

Two statements declaring values that the ruleset expects as inputs and the values it delivers as outputs come next. The ruleset can be run from within the ruleset editor for testing. In this case, this can be arranged simply by switching the comment designator ("//") from the blank inputs() statement to the inputs {BCWS,ACWP,BCWP}; statement and removing the comments from one set of the assertion statements.

There is an init() ruleblock to perform one-time initialization of control parameters. These control parameters specify the inferencing methods that the fuzzy inferencing engine uses. The first of these, CorrelationMethod, will use the Minimum method. The second, AlphaCut, is used to specify the "truth" threshold.

Next, the process() ruleblock is defined. In this case, it is the only process() ruleblock of the ruleset. It designates use of the fuzzy inferencing engine. Within this ruleblock, you'll notice a number of assertion statements (which are commented out) along with a number of rules. As previously mentioned, this ruleset can be invoked in the ruleset editor simply by changing the inputs() statement and removing the comment designator from one set of assertions. Once you've made those changes (be careful not to save the changes or save to another filename), you can verify the ruleset. Ruleset verification is simple—you notice a magnifying glass button along the row of buttons at the top of the ruleset editor. If you push this button, the ruleset will be verified and any syntactical errors will surface. To test the ruleset, use the Run ruleset button, which looks like a person walking with an arrow pointing to the right. After you push this button, the output results from the inferencing performed will be displayed in a separate window. That's all there is to it. Figure 1 shows the riskEV ruleset output when run from the ruleset editor under Linux.

While the task of developing a reasoning capability for an application couldn't be much easier, I don't want to minimize the complexity that is captured in each of the ARL inference engines. The ABLE Rule Language is well documented and there is a large amount of information available elsewhere on the theory and practice upon which these inference engines have been built.

The Earned Value JavaBean

The EV JavaBean is comprised of three classes: Risk (Listing One), RiskAssessor (available electronically; see "Resource Center," page 5), and RiskForecast (also available electronically). The Risk class encapsulates the Risk object with its get/set (properties) methods. For example, again using Schedule Performance Index for illustration:

public void setSpi(String spi_parm) {
this.spi_parm = spi_parm;
}
public String getSpi() {
return spi_parm;
}

The RiskAssessor class does most of the work. The calculateRiskValue() method obtains an output string from the getRisk() method, then tokenizes the string into separate values for display purposes. The getRisk() method takes three input values, as you might imagine: BCWS, ACWP and BCWP. It sets the value of the rules string to "riskEV.arl" (the ABLE Rule Language ruleset file), instantiates an AbleRuleSet object, and parses the ARL file. The ruleset is then processed and the output result provided.

The RiskForecast class contains two methods:

  • getRiskForecast() instantiates a Risk object and invokes the calculateRiskValue() method in the RiskAssessor class.
  • main() can be used to test the EV application as a Java application. Figure 2 is an example of executing the EV application using the Eclipse IDE on Linux.

Be sure that the appropriate ABLE jar files are available when you compile the application. For example, when using Eclipse or Websphere Studio Application Developer (WSAD), add able.jar, ablerules.jar, antlr.jar, and JLog.jar to the project build path. Before generating the web service using WSAD, ensure that these jar files are also located on the WSAD test server's class path (or, for that matter, on the class path of the target deployment server). This will vary depending on your installation and operating system, so examine the server console to obtain the classpath information.

The Earned Value Web Service

Websphere Studio Application Developer makes the job of converting the Earned Value JavaBean into a web service very straightforward (see Figures 2 and 3). Obviously, it's not the only way to create a web service (you could use Eclipse or any number of other tools), but WSAD's web-service wizard makes generating a web service from a JavaBean easy.

First, highlight the project name. Next, from the dropdown menu, select File|New|Other|Web Services|Web Service. Next, choose JavaBean Web Service as the Web Services Type, then choose Test the Web Service|Generate a Proxy|Test the Generated Proxy. The Client Proxy Type should be set to Java Proxy. Next, make sure that the Service Web Project and the Client Web Project names are correct. Then, choose RiskForecast as the JavaBean. Check the getRiskForecast() method and uncheck the main() method. Select Finish to generate the web service.

A test web-service interface is generated as part of the web-service client project, which is composed of a TestClient.jsp, Input.jsp, Method.jsp, and Result.jsp. These are displayed as separate web-browser frames. To test the web service, select the getRiskForecast method from the Methods frame and the Inputs frame will display the BCWS, ACWP, and BCWP entry fields. If you enter values from the various test cases included in the code comments (or use values from a real project), and press the Invoke button, the Risk Rating is displayed in the Results frame.

Conclusion

Earned value isn't the only measure of risk and as you can see, adding other measures is very easy. For example, you might want to qualify the earned value assessment with a project size fuzzy value of Small, Medium, and Large. Projects with a BCWS over $1 million might be treated differently than those under a million. Other factors that might be used include importance of the project to the business and opportunity cost (lost value to the business) if the project is not implemented. Since the Earned Value application is comprised of web-service components it is easy to customize or expand to cover additional areas of project risk. Indeed, the application does not even have to be accessed via a browser GUI—it can be accessed from other project management tools via SOAP and an SOA architecture.

DDJ



Listing One

/**
* This fuzzy ruleset, when given data for BCWS, ACWP and BCWP, will determine 
* a risk rating of * A (good), B (adequate), or C (poor). You may change the 
* values used in the assertion rules, re-verify and re-run the ruleset 
* to determine new risk ratings. 
*/

ruleset RiskEV {
  variables {
    Fuzzy BCWS = new Fuzzy(0, 2000)  {
      Linear    Large  = new Linear  (1000, 2000, ARL.Up);
      Linear    Small  = new Linear  ( 0,  1000, ARL.Down);
      Triangle  Medium = new Triangle( 0,  1000, 2000);
    };
     Fuzzy ACWP = new Fuzzy(0, 2000)  {
      Linear    Large  = new Linear  (1000, 2000, ARL.Up);
      Linear    Small  = new Linear  ( 0,  1000, ARL.Down);
      Triangle  Medium = new Triangle( 0,  1000, 2000);
    };
     Fuzzy BCWP = new Fuzzy(0, 2000)  {
      Linear    Large  = new Linear  (1000, 2000, ARL.Up);
      Linear    Small  = new Linear  ( 0,  1000, ARL.Down);
      Triangle  Medium = new Triangle( 0,  1000, 2000);
    };
     Fuzzy SV = new Fuzzy(-2000, 2000)  {
      Linear    VeryGood  = new Linear  (1000, 2000, ARL.Up);
      Linear    Good  = new Linear  (500, 1000, ARL.Up);
      Linear    Bad  = new Linear  ( -1000,  -500, ARL.Down);
      Linear    VeryBad  = new Linear  ( -2000,  -1000, ARL.Down);
      Triangle  Adequate = new Triangle( -500, 0, 500);
    };
     Fuzzy CV = new Fuzzy(-2000, 2000)  {
      Linear    VeryGood  = new Linear  (1000, 2000, ARL.Up);
      Linear    Good  = new Linear  (500, 1000, ARL.Up);
      Linear    Bad  = new Linear  ( -1000,  -500, ARL.Down);
      Linear    VeryBad  = new Linear  ( -2000,  -1000, ARL.Down);
      Triangle  Adequate = new Triangle( -500, 0, 500);
    };
     Fuzzy SPI = new Fuzzy(0.0, 2.0)  {
      Linear    VeryGood  = new Linear  (1.5, 2.0, ARL.Up);
      Linear    Good  = new Linear  (1.00, 1.5, ARL.Up);
      Linear    Bad  = new Linear  ( 0.5,  0.9, ARL.Down);
      Linear    VeryBad  = new Linear  ( 0.0,  0.5, ARL.Down);
      Triangle  Adequate = new Triangle(0.95, 1.0, 1.05);
    };
     Fuzzy CPI = new Fuzzy(0.0, 2.0)  {
      Linear    VeryGood  = new Linear  (1.5, 2.0, ARL.Up);
      Linear    Good  = new Linear  (1.00, 1.5, ARL.Up);
      Linear    Bad  = new Linear  ( 0.5,  0.9, ARL.Down);
      Linear    VeryBad  = new Linear  ( 0.0,  0.5, ARL.Down);
      Triangle  Adequate = new Triangle( 0.95, 1.0, 1.05);
    };
    Fuzzy RiskRating = new Fuzzy(0.0, 1.0)  {
      Triangle  Medium = new Triangle(0.3, 0.5, 0.65);
      Linear    Low   = new Linear  (0.6, 1.0, ARL.Up);
      Linear    High     = new Linear  (0.0, 0.4, ARL.Down);
    };
    Categorical SymRating = new Categorical(new String[] {"C", "B", "A"});
  }
  //inputs {};
  inputs {BCWS,ACWP,BCWP};
  outputs {BCWS, ACWP, BCWP, CV, SV, SPI, CPI, RiskRating, SymRating};
  // Running this ruleset 
  // produces the following output:
  //     Variable...<BCWS>    Value......<>
  //     Variable...<ACWP>   Value......<>
  //     Variable...<BCWP>   Value......<>
  //     Variable...<CV>  Value......<>
  //     Variable...<SV>      Value......<>
  //     Variable...<CPI>  Value......<>
  //     Variable...<SPI>      Value......<>
  //     Variable...<RiskRating>    Value......<>
  //     Variable...<SymRating> Value......<>

  void init() { 
       : setControlParameter(ARL.process, ARL.CorrelationMethod, ARL.Minimum);
       : setControlParameter(ARL.process, ARL.AlphaCut, 0.01);
  }     
  void process() using Fuzzy { 
    //case 1 Ideal planning, going according to schedule.
    // 
    //A01: BCWS   = 800;
    //A02: ACWP  =  800;
    //A03: BCWP =  800;

    //case 2 One of the worst cases, 50% behind schedule, 
    //                                 cost overrun, project underrunning.
    //A01: BCWS   = 800;
    //A02: ACWP  =  600;
    //A03: BCWP =  400;

    //case 3 Good and bad. Efficiency (CPI) exceeds 100%, but behind schedule.
    // 
    //A01: BCWS   = 800;
    //A02: ACWP  =  400;
    //A03: BCWP =  600;

    //case 4 Good and bad.  Efficiency (CPI) is on track, but 
    //                                       project behind schedule.
    //A01: BCWS   = 800;
    //A02: ACWP  =  600;
    //A03: BCWP =  600;

    //case 5 Good and bad.  Efficiency (CPI) is behind, so project 
    //                        is behind schedule, but costs are on track.
    //A01: BCWS   = 800;
    //A02: ACWP  =  800;
    //A03: BCWP =  600;

    //case 6 , Very Good, 125%  Efficiency (CPI), so project ahead 
    //                                     of schedule, and within costs.
    //A01: BCWS   = 800;
    //A02: ACWP  =  800;
    //A03: BCWP =  1000;

    //case 7 , 100%  Efficiency (CPI), and project ahead of 
    //                                      schedule, and within costs.
    //A01: BCWS   = 800;
    //A02: ACWP  =  1000;
    //A03: BCWP =  1000;

    //case 8 Very Good, 130%  Efficiency (CPI), and project on 
    //                                   schedule, and under budgeted costs
    //A01: BCWS   = 800;
    //A02: ACWP  =  600;
    //A03: BCWP =  800;

    //case 9 Good and bad, 80%  Efficiency (CPI), and project on 
    //                                 schedule, but over budgeted costs
    //A01: BCWS   = 800;
    //A02: ACWP  =  1000;
    //A03: BCWP =  800;

    //case 10 Very bad, 60%  Efficiency( CPI), and project behind 
    //                              schedule, and over budgeted costs.
    //A01: BCWS   = 800;
    //A02: ACWP  =  1000;
    //A03: BCWP =  600;

    //case 11 Very good, 160%  Efficiency (CPI), and project ahead 
    //                             schedule, and under budgeted costs.
    //A01: BCWS   = 800;
    //A02: ACWP  =  600;
    //A03: BCWP =/  1000;

    //case 12 Good and bad, 83%  Efficiency (CPI), and project ahead 
    //                               schedule, but over budgeted costs.
    //A01: BCWS   = 800;
    //A02: ACWP  =  1200;
    //A03: BCWP =  1000;

    //case 13 Good , 120%  Efficiency (CPI), and project very 
    //                       ahead schedule, but over budgeted costs.
    //A01: BCWS   = 800;
    //A02: ACWP  =  1000;
    //A03: BCWP =  1200;

    R1: CV      =  BCWP - ACWP;
    R2: SV      =  BCWP - BCWS;
    R3: CPI  = (BCWP / ACWP);
    R4: SPI = (BCWP / BCWS); 
    
    R05: if (CV is VeryGood ) then RiskRating is Low;
    R06: if (CV is Good ) then RiskRating is Low;    
    R07: if (CV is Adequate ) then RiskRating is Medium;
    R08: if (CV is Bad) then RiskRating is High;
    R09: if (CV is VeryBad ) then RiskRating is High;
    
    R10: if (SV is VeryGood ) then RiskRating is Low;
    R11: if (SV is Good ) then RiskRating is Low;    
    R12: if (SV is Adequate ) then RiskRating is Medium;
    R13: if (SV is Bad) then RiskRating is High;
    R14: if (SV is VeryBad ) then RiskRating is High;
    
    R15: if (SPI is VeryGood ) then RiskRating is Low;
    R16: if (SPI is Good ) then RiskRating is Low;    
    R17: if (SPI is Adequate ) then RiskRating is Medium;
    R18: if (SPI is Bad) then RiskRating is High;
    R19: if (SPI is VeryBad ) then RiskRating is High;
    
    R20: if (CPI is VeryGood ) then RiskRating is Low;
    R21: if (CPI is Good ) then RiskRating is Low;    
    R22: if (CPI is Adequate ) then RiskRating is Medium;
    R23: if (CPI is Bad) then RiskRating is High;
    R24: if (CPI is VeryBad ) then RiskRating is High;

    R25: if (RiskRating is High    ) then SymRating = "C";
    R26: if (RiskRating is Medium) then SymRating = "B";
    R27: if (RiskRating is Low  ) then SymRating = "A";
  }
}
Back to article


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video