00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00040 #include <plugins/prediction/PluginPrediction.h>
00041
00042
00043 namespace beliefstate {
00044 namespace plugins {
00045 PLUGIN_CLASS::PLUGIN_CLASS() {
00046 m_jsnModel = NULL;
00047 m_dtDecisionTree = NULL;
00048 m_expOwl = NULL;
00049 m_bInsidePredictionModel = false;
00050 m_ndActive = NULL;
00051 m_bModelLoaded = false;
00052 m_nClassFlexibility = 6;
00053
00054 this->setPluginVersion("0.1");
00055 }
00056
00057 PLUGIN_CLASS::~PLUGIN_CLASS() {
00058 if(m_jsnModel) {
00059 delete m_jsnModel;
00060 }
00061
00062 if(m_dtDecisionTree) {
00063 delete m_dtDecisionTree;
00064 }
00065
00066 if(m_expOwl) {
00067 delete m_expOwl;
00068 }
00069
00070 m_lstPredictionStack.clear();
00071 }
00072
00073 Result PLUGIN_CLASS::init(int argc, char** argv) {
00074 Result resInit = defaultResult();
00075
00076
00077 this->setSubscribedToEvent("symbolic-begin-context", true);
00078 this->setSubscribedToEvent("symbolic-end-context", true);
00079 this->setSubscribedToEvent("symbolic-node-active", true);
00080
00081 this->setOffersService("predict", true);
00082 this->setOffersService("load-model", true);
00083 this->setOffersService("invert-decision-tree", true);
00084
00085
00086 m_jsnModel = new JSON();
00087 m_dtDecisionTree = new DecisionTree();
00088
00089
00090 m_expOwl = new CExporterOwl();
00091
00092 return resInit;
00093 }
00094
00095 Result PLUGIN_CLASS::deinit() {
00096 return defaultResult();
00097 }
00098
00099 Result PLUGIN_CLASS::cycle() {
00100 Result resCycle = defaultResult();
00101 this->deployCycleData(resCycle);
00102
00103 return resCycle;
00104 }
00105
00106 Event PLUGIN_CLASS::consumeServiceEvent(ServiceEvent seEvent) {
00107 Event evReturn = this->Plugin::consumeServiceEvent(seEvent);
00108
00109 if(seEvent.siServiceIdentifier == SI_REQUEST) {
00110 if(seEvent.strServiceName == "predict") {
00111 ServiceEvent seResponse = eventInResponseTo(seEvent);
00112 CDesignator* cdRequest = seEvent.cdDesignator;
00113
00114 seResponse.bPreserve = true;
00115 CDesignator* cdResponse = new CDesignator();
00116 cdResponse->setType(ACTION);
00117
00118 bool bSuccess = false;
00119 if(m_bModelLoaded) {
00120 this->info("Received Prediction Request.");
00121
00122 if(!this->predict(cdRequest, cdResponse)) {
00123 this->fail("Failed to predict!");
00124
00125 cdResponse->setValue("success", false);
00126 cdResponse->setValue("message", "Failed to predict.");
00127 } else {
00128 cdResponse->setValue("success", true);
00129 }
00130 } else {
00131 this->warn("Received Prediction Request without loaded prediction model. Ignoring.");
00132
00133 cdResponse->setValue("success", false);
00134 cdResponse->setValue("message", "No model loaded.");
00135 }
00136
00137 seResponse.cdDesignator = cdResponse;
00138 this->deployServiceEvent(seResponse);
00139 } else if(seEvent.strServiceName == "load-model") {
00140 CDesignator* cdRequest = seEvent.cdDesignator;
00141
00142 if(cdRequest) {
00143 if(cdRequest->stringValue("type") == "task-tree") {
00144 std::string strPath = cdRequest->stringValue("file");
00145
00146 if(strPath != "") {
00147 this->info("Load task tree model: '" + strPath + "'");
00148
00149 if(this->load(strPath)) {
00150 this->info("Finished loading task tree model.");
00151 m_bModelLoaded = true;
00152 } else {
00153 this->fail("Failed to load task tree model.");
00154 }
00155 } else {
00156 this->fail("No file specified for loading task tree model.");
00157 }
00158 } else if(cdRequest->stringValue("type") == "decision-tree") {
00159 std::string strPath = cdRequest->stringValue("file");
00160 this->info("Load decision tree model: '" + strPath + "'");
00161
00162 if(strPath != "") {
00163 if(this->loadDecisionTree(strPath)) {
00164 this->info("Finished loading decision tree model.");
00165 } else {
00166 this->fail("Failed to load decision tree model.");
00167 }
00168 } else {
00169 this->fail("No file specified for loading decision tree model.");
00170 }
00171 }
00172 }
00173
00174 ServiceEvent seResponse = eventInResponseTo(seEvent);
00175 this->deployServiceEvent(seResponse);
00176 } else if(seEvent.strServiceName == "invert-decision-tree") {
00177 if(seEvent.cdDesignator) {
00178 std::string strTargetResult = seEvent.cdDesignator->stringValue("target-result");
00179
00180 if(strTargetResult != "") {
00181 CKeyValuePair* ckvpFeatures = seEvent.cdDesignator->childForKey("features");
00182
00183 Property* prTargetResult = new Property();
00184 prTargetResult->set(strTargetResult);
00185
00186 vector<CKeyValuePair*> vecSolutions = m_dtDecisionTree->invert(prTargetResult, ckvpFeatures);
00187 delete prTargetResult;
00188
00189 ServiceEvent seResponse = eventInResponseTo(seEvent);
00190 seResponse.bPreserve = true;
00191 seResponse.cdDesignator = new CDesignator();
00192 seResponse.cdDesignator->setType(ACTION);
00193
00194 CKeyValuePair* ckvpSolutions = seResponse.cdDesignator->addChild("solutions");
00195
00196 for(int nI = 0; nI < vecSolutions.size(); nI++) {
00197 CKeyValuePair* ckvpSolution = vecSolutions.at(nI);
00198
00199 ckvpSolution->setKey("solution_" + this->str(nI));
00200 ckvpSolutions->addChild(ckvpSolution);
00201 }
00202
00203 this->deployServiceEvent(seResponse);
00204 } else {
00205 this->warn("Cannot invert decision tree model without target result.");
00206 }
00207 }
00208 }
00209 }
00210
00211 return evReturn;
00212 }
00213
00214 void PLUGIN_CLASS::consumeEvent(Event evEvent) {
00215 if(evEvent.strEventName == "symbolic-begin-context") {
00216 if(m_bInsidePredictionModel) {
00217 if(evEvent.lstNodes.size() > 0) {
00218 this->descend(evEvent.lstNodes.front());
00219 issueGlobalToken("symbolic-context-began");
00220 } else {
00221 this->warn("Consuming 'symbolic-begin-context' event without nodes!");
00222 }
00223 } else {
00224 this->fail("No prediction model loaded, won't descend.");
00225 }
00226 } else if(evEvent.strEventName == "symbolic-end-context") {
00227 if(evEvent.lstNodes.size() > 0) {
00228 this->ascend(evEvent.lstNodes.front());
00229 } else {
00230 this->warn("Consuming 'symbolic-end-context' event without nodes!");
00231 }
00232 } else if(evEvent.strEventName == "symbolic-node-active") {
00233 if(evEvent.lstNodes.size() > 0) {
00234 Node* ndNode = evEvent.lstNodes.front();
00235
00236 this->info("Prediction context is now node '" + ndNode->title() + "'.");
00237 m_ndActive = ndNode;
00238 } else {
00239 this->info("Prediction context is now top-level (so not predicting).");
00240 m_ndActive = NULL;
00241 }
00242 }
00243 }
00244
00245 bool PLUGIN_CLASS::serviceCallbackLoad(designator_integration_msgs::DesignatorCommunication::Request &req, designator_integration_msgs::DesignatorCommunication::Response &res) {
00246 bool bSuccess = false;
00247
00248 CDesignator* desigRequest = new CDesignator(req.request.designator);
00249 CDesignator* desigResponse = new CDesignator();
00250 desigResponse->setType(ACTION);
00251
00252 if(desigRequest->stringValue("load") == "model") {
00253 this->info("Received Model Load Request.");
00254
00255 std::string strFile = desigRequest->stringValue("file");
00256 if(strFile != "") {
00257 this->info(" - Load model: '" + strFile + "'");
00258
00259 bSuccess = this->load(strFile);
00260
00261 if(bSuccess) {
00262 m_bModelLoaded = true;
00263 }
00264 } else {
00265 this->fail(" - No model file specified!");
00266 }
00267 }
00268
00269 res.response.designators.push_back(desigResponse->serializeToMessage());
00270
00271 delete desigRequest;
00272 delete desigResponse;
00273
00274 return bSuccess;
00275 }
00276
00277 bool PLUGIN_CLASS::load(string strFile) {
00278 bool bReturn = false;
00279
00280 std::ifstream ifFile(strFile.c_str());
00281 if(ifFile.good()) {
00282 std::string strJSON((istreambuf_iterator<char>(ifFile)), (istreambuf_iterator<char>()));
00283
00284 m_jsnModel->parse(strJSON);
00285
00286 if(m_jsnModel->rootProperty()) {
00287 this->info("Successfully loaded and parsed model '" + strFile + "'.");
00288 bReturn = true;
00289 m_bInsidePredictionModel = true;
00290
00291 this->info("Okay, descending to 'Toplevel'.");
00292 this->descend("Toplevel");
00293
00294 bReturn = true;
00295 } else {
00296 this->fail("Failed to load model '" + strFile + "', unable to parse.");
00297 }
00298 } else {
00299 this->fail("Failed to load model '" + strFile + "', file does not exist.");
00300 bReturn = false;
00301 }
00302
00303 ifFile.close();
00304
00305 return bReturn;
00306 }
00307
00308 bool PLUGIN_CLASS::descend(Node* ndDescend) {
00309 return this->descend(ndDescend->title());
00310
00311 }
00312
00313 bool PLUGIN_CLASS::descend(std::string strClass, bool bForceClass) {
00314 bool bResult = false;
00315 bool bFlexible = false;
00316
00317 m_mtxStackProtect.lock();
00318 Property* prDescendTo = NULL;
00319
00320 if(m_lstPredictionStack.size() == 0) {
00321
00322
00323 prDescendTo = m_jsnModel->rootProperty()->namedSubProperty(strClass);
00324 } else {
00325
00326
00327 if(m_bInsidePredictionModel) {
00328 Property* prActive = m_lstPredictionStack.back().prLevel;
00329
00330 if(prActive->namedSubProperty("subTypes")) {
00331 prDescendTo = prActive->namedSubProperty("subTypes")->namedSubProperty(strClass);
00332 }
00333
00334 if(!prDescendTo) {
00335
00336
00337
00338 std::string strClasses = "";
00339 for(Property* prType : prActive->namedSubProperty("subTypes")->subProperties()) {
00340 if(strClasses != "") {
00341 strClasses += " ";
00342 }
00343
00344 strClasses += prType->key();
00345 }
00346
00347 this->warn("No match for descend. Available classes: " + strClasses);
00348
00349 if(m_nClassFlexibility > 0) {
00350
00351 if(prActive->namedSubProperty("subTypes")->subProperties().size() > 0) {
00352
00353 this->warn("Being flexible: Accept '" + prActive->namedSubProperty("subTypes")->subProperties().front()->key() + "' for '" + strClass + "'");
00354 prDescendTo = prActive->namedSubProperty("subTypes")->subProperties().front();
00355 bFlexible = true;
00356 m_nClassFlexibility--;
00357 }
00358 }
00359 }
00360 }
00361 }
00362
00363 if(prDescendTo) {
00364 m_bInsidePredictionModel = true;
00365
00366 this->info("Descending by class: '" + strClass + "'");
00367
00368 PredictionTrack ptTrack;
00369 ptTrack.prLevel = prDescendTo;
00370 ptTrack.strClass = (bFlexible ? "*" : strClass);
00371 m_lstPredictionStack.push_back(ptTrack);
00372
00373 bResult = true;
00374 } else {
00375 this->warn("Couldn't descend by class: '" + strClass + "'");
00376
00377 if(m_bInsidePredictionModel) {
00378 this->warn("Leaving prediction model, entering unknown sub-tree.");
00379 m_bInsidePredictionModel = false;
00380 } else {
00381 this->info("Continuing descent into unknown sub-tree.");
00382 }
00383
00384 PredictionTrack ptTrack;
00385 ptTrack.prLevel = NULL;
00386 ptTrack.strClass = strClass;
00387 m_lstPredictionStack.push_back(ptTrack);
00388 }
00389
00390 m_mtxStackProtect.unlock();
00391
00392 return bResult;
00393 }
00394
00395 bool PLUGIN_CLASS::ascend(Node* ndAscend) {
00396 bool bResult = false;
00397
00398 std::string strClass = ndAscend->title();
00399
00400 m_mtxStackProtect.lock();
00401 if(m_lstPredictionStack.size() > 0) {
00402 bool bGoon = true;
00403
00404 while(bGoon) {
00405 PredictionTrack ptTrack = m_lstPredictionStack.back();
00406 m_lstPredictionStack.pop_back();
00407
00408 if(strClass == ptTrack.strClass || ptTrack.strClass == "*") {
00409 if(ptTrack.strClass == "*") {
00410 m_nClassFlexibility++;
00411 }
00412
00413 if(m_lstPredictionStack.size() > 0) {
00414 PredictionTrack ptTrackNew = m_lstPredictionStack.back();
00415
00416 if(m_bInsidePredictionModel) {
00417 this->info("Ascending by class: '" + strClass + "'");
00418 } else {
00419 if(ptTrackNew.prLevel) {
00420 this->info("Ascending back into prediction model. Predictions possible again.");
00421 m_bInsidePredictionModel = true;
00422 } else {
00423 this->info("Ascending out of part of the unknown sub-tree.");
00424 }
00425 }
00426 } else {
00427 this->fail("Careful: Ascending into empty prediction stack. This shouldn't happen, as at least a 'Toplevel' stack entry is expected.");
00428 }
00429
00430 bResult = true;
00431 } else {
00432 this->fail("Tried to ascend from '" + strClass + "', but we're in '" + ptTrack.strClass + "'. Moving up the chain.");
00433 bResult = true;
00434 }
00435
00436 if(m_lstPredictionStack.size() == 0 || bResult) {
00437 bGoon = false;
00438 }
00439 }
00440 } else {
00441 this->warn("Ascending although we have no prediction tree loaded. Did you load a model? (Hint: The answer is 'No'.)");
00442 }
00443
00444 m_mtxStackProtect.unlock();
00445
00446 return bResult;
00447 }
00448
00449 PLUGIN_CLASS::PredictionResult PLUGIN_CLASS::evaluatePredictionRequest(Property* prActive, CKeyValuePair* ckvpFeatures, CKeyValuePair* ckvpRequested) {
00450 PredictionResult presResult;
00451
00452
00453 std::map<std::string, double> mapEffectiveFailureRates;
00454
00455
00456 std::list< pair<Property*, int> > lstLinearTree = this->linearizeTree(prActive, m_lstPredictionStack.size());
00457 std::list< pair<Property*, int> > lstRunTree;
00458 double dLeftOverSuccess = 1.0f;
00459
00460 for(pair<Property*, int> prCurrent : lstLinearTree) {
00461 lstRunTree.push_back(prCurrent);
00462
00463 presResult = this->probability(lstRunTree, ckvpFeatures, ckvpRequested);
00464
00465 for(pair<std::string, double> prFailure : presResult.mapFailureProbabilities) {
00466 if(mapEffectiveFailureRates.find(prFailure.first) == mapEffectiveFailureRates.end()) {
00467 mapEffectiveFailureRates[prFailure.first] = 0.0f;
00468 }
00469
00470 mapEffectiveFailureRates[prFailure.first] += (prFailure.second * dLeftOverSuccess);
00471 dLeftOverSuccess -= (prFailure.second * dLeftOverSuccess);
00472 }
00473 }
00474
00475 presResult.dSuccessRate = 1.0f;
00476
00477 for(std::pair<std::string, double> prFailure : mapEffectiveFailureRates) {
00478 presResult.mapFailureProbabilities[prFailure.first] = prFailure.second;
00479 presResult.dSuccessRate -= prFailure.second;
00480 }
00481
00482 return presResult;
00483 }
00484
00485 bool PLUGIN_CLASS::predict(CDesignator* cdRequest, CDesignator* cdResponse) {
00486 bool bResult = false;
00487
00488 m_mtxStackProtect.lock();
00489
00490 if(m_bInsidePredictionModel) {
00491
00492
00493 if(m_jsnModel->rootProperty()) {
00494
00495 if(m_lstPredictionStack.size() > 0) {
00496 PredictionTrack ptCurrent = m_lstPredictionStack.back();
00497 this->info("Predicting for class: '" + ptCurrent.strClass + "' at level " + this->str((int)m_lstPredictionStack.size()));
00498
00499 CKeyValuePair* ckvpActiveFeatures = cdRequest->childForKey("active-features");
00500 CKeyValuePair* ckvpRequestedFeatures = cdRequest->childForKey("requested-features");
00501
00502 if(ckvpActiveFeatures) {
00503 std::string strActiveFeatures = "";
00504
00505 for(std::string strKey : ckvpActiveFeatures->keys()) {
00506 if(strActiveFeatures != "") {
00507 strActiveFeatures += ", ";
00508 }
00509
00510 strActiveFeatures += strKey;
00511 }
00512
00513 this->info("Active features: " + strActiveFeatures);
00514 }
00515
00516 if(ckvpRequestedFeatures) {
00517 std::string strRequestedFeatures = "";
00518
00519 for(std::string strKey : ckvpRequestedFeatures->keys()) {
00520 if(strRequestedFeatures != "") {
00521 strRequestedFeatures += ", ";
00522 }
00523
00524 strRequestedFeatures += strKey;
00525 }
00526
00527 this->info("Requested features: " + strRequestedFeatures);
00528 }
00529
00530
00531 Property* prActive = m_lstPredictionStack.back().prLevel;
00532 PredictionResult presResult = this->evaluatePredictionRequest(prActive, ckvpActiveFeatures, ckvpRequestedFeatures);
00533
00534
00535
00536 CKeyValuePair* ckvpFailureProbabilities = cdResponse->addChild("failures");
00537 for(pair<std::string, double> prFailure : presResult.mapFailureProbabilities) {
00538 ckvpFailureProbabilities->setValue(prFailure.first, prFailure.second);
00539 }
00540
00541
00542 CKeyValuePair* ckvpRequestedFeatureValues = cdResponse->addChild("requested");
00543 for(pair<std::string, Property*> prReq : presResult.mapRequestedFeatureValues) {
00544 ckvpRequestedFeatureValues->addChild(prReq.first, prReq.second);
00545 }
00546
00547
00548 cdResponse->setValue("success", presResult.dSuccessRate);
00549
00550 bResult = true;
00551 } else {
00552 this->fail("Nothing on the prediction stack. Toplevel not loaded. This is bad.");
00553 }
00554 } else {
00555 this->fail("No root element loaded. Did you load a prediction model?");
00556 }
00557 } else {
00558 this->fail("Outside of prediction model, no predictions possible.");
00559 }
00560
00561 m_mtxStackProtect.unlock();
00562
00563 return bResult;
00564 }
00565
00566 std::list< pair<Property*, int> > PLUGIN_CLASS::linearizeTree(Property* prTop, int nLevel) {
00567 std::list< pair<Property*, int> > lstProps;
00568 lstProps.push_back(make_pair(prTop, nLevel));
00569
00570 Property* prSubs = prTop->namedSubProperty("subTypes");
00571
00572 if(prSubs) {
00573 for(Property* prSub : prSubs->subProperties()) {
00574 std::list< pair<Property*, int> > lstSubProps = this->linearizeTree(prSub, nLevel + 1);
00575
00576 for(pair<Property*, int> prSubSub : lstSubProps) {
00577 lstProps.push_back(make_pair(prSubSub.first, prSubSub.second));
00578 }
00579 }
00580 }
00581
00582 return lstProps;
00583 }
00584
00585 std::map<std::string, double> PLUGIN_CLASS::relativeFailureOccurrences(std::list<Property*> lstFailures, int nTracks) {
00586 std::map<std::string, int> mapFailureOcc;
00587
00588 for(Property* prFailure : lstFailures) {
00589 std::string strType = prFailure->namedSubProperty("type")->getString();
00590
00591 if(mapFailureOcc[strType] == 0) {
00592 mapFailureOcc[strType] = 1;
00593 } else {
00594 mapFailureOcc[strType]++;
00595 }
00596 }
00597
00598 std::map<std::string, double> mapFailureRelOcc;
00599 for(std::pair<std::string, int> prFailOcc : mapFailureOcc) {
00600 mapFailureRelOcc[prFailOcc.first] = (double)prFailOcc.second / (double)nTracks;
00601 }
00602
00603 return mapFailureRelOcc;
00604 }
00605
00606 std::list<Property*> PLUGIN_CLASS::failuresForTreeNode(Property* prNode) {
00607 if(m_mapNodeFailures.find(prNode) != m_mapNodeFailures.end()) {
00608 return m_mapNodeFailures[prNode];
00609 }
00610
00611 std::list<Property*> lstEmpty;
00612 return lstEmpty;
00613 }
00614
00615 std::list<Property*> PLUGIN_CLASS::parametersForTreeNode(Property* prNode) {
00616 if(m_mapNodeParameters.find(prNode) != m_mapNodeParameters.end()) {
00617 return m_mapNodeParameters[prNode];
00618 }
00619
00620 std::list<Property*> lstEmpty;
00621 return lstEmpty;
00622 }
00623
00624 std::map<std::string, double> PLUGIN_CLASS::relativeFailuresForNode(Property* prNode, int nLevel, CKeyValuePair* ckvpFeatures) {
00625 std::map<std::string, double> mapRelFail;
00626
00627 if(prNode) {
00628 ckvpFeatures->setValue("Level", nLevel);
00629 ckvpFeatures->setValue("Task", prNode->key());
00630
00631
00632 std::string strTagName = "";
00633
00634 CKeyValuePair* ckvpDesignators = m_ndActive->metaInformation()->childForKey("designators");
00635 if(ckvpDesignators) {
00636 for(CKeyValuePair* ckvpDesignator : ckvpDesignators->children()) {
00637 CKeyValuePair* ckvpDescription = ckvpDesignator->childForKey("description");
00638
00639 if(ckvpDescription) {
00640 strTagName = ckvpDescription->stringValue("tagname");
00641
00642 if(strTagName != "") {
00643 break;
00644 }
00645 }
00646 }
00647 }
00648
00649 if(strTagName != "") {
00650 ckvpFeatures->setValue("TAGNAME", strTagName);
00651 }
00652
00653 Property* prResult = this->evaluateDecisionTree(ckvpFeatures);
00654
00655 if(prResult) {
00656
00657
00658
00659
00660 mapRelFail[prResult->getString()] = 1.0f;
00661 }
00662 }
00663
00664 return mapRelFail;
00665 }
00666
00667 PLUGIN_CLASS::PredictionResult PLUGIN_CLASS::probability(std::list< pair<Property*, int> > lstSequence, CKeyValuePair* ckvpFeatures, CKeyValuePair* ckvpRequested) {
00668 PredictionResult presResult;
00669
00670
00671
00672
00673 if(lstSequence.size() > 0) {
00674 Property* prCurrentNode = lstSequence.back().first;
00675
00676
00677 std::map<std::string, double> mapFailureRelOcc = this->relativeFailuresForNode(prCurrentNode, lstSequence.back().second, ckvpFeatures);
00678
00679 double dLocalSuccess = 1.0f;
00680 for(std::pair<std::string, double> prPair : mapFailureRelOcc) {
00681 dLocalSuccess -= prPair.second;
00682 }
00683
00684 std::map<std::string, double> mapSubFailures;
00685 if(dLocalSuccess > 0.0f) {
00686
00687 std::list< pair<Property*, int> > lstAllButLast = lstSequence;
00688 lstAllButLast.pop_back();
00689
00690
00691 PredictionResult presSub = this->probability(lstAllButLast, ckvpFeatures, ckvpRequested);
00692 mapSubFailures = presSub.mapFailureProbabilities;
00693 } else {
00694 lstSequence.clear();
00695 }
00696
00697
00698 for(std::pair<std::string, double> prMap : mapFailureRelOcc) {
00699 presResult.mapFailureProbabilities[prMap.first] = prMap.second;
00700 }
00701
00702 double dLocalSuccessDelta = 0.0f;
00703
00704
00705 for(pair<std::string, double> prFailure : mapSubFailures) {
00706 presResult.mapFailureProbabilities[prFailure.first] = prFailure.second * dLocalSuccess;
00707 dLocalSuccessDelta += presResult.mapFailureProbabilities[prFailure.first];
00708 }
00709
00710 presResult.dSuccessRate = dLocalSuccess - dLocalSuccessDelta;
00711 } else {
00712
00713
00714 presResult.dSuccessRate = 1.0f;
00715 }
00716
00717 return presResult;
00718 }
00719
00720 bool PLUGIN_CLASS::loadDecisionTree(std::string strPath) {
00721 return m_dtDecisionTree->load(strPath);
00722 }
00723
00724 Property* PLUGIN_CLASS::evaluateDecisionTree(CKeyValuePair* ckvpFeatures) {
00725 return m_dtDecisionTree->evaluate(ckvpFeatures);
00726 }
00727 }
00728
00729 extern "C" plugins::PLUGIN_CLASS* createInstance() {
00730 return new plugins::PLUGIN_CLASS();
00731 }
00732
00733 extern "C" void destroyInstance(plugins::PLUGIN_CLASS* icDestroy) {
00734 delete icDestroy;
00735 }
00736 }