CertainTrust.java 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  1. /**
  2. * CertainTrust SDK
  3. *
  4. * Implements the computational trust model "CertainTrust"
  5. * in Java.
  6. * See <http://www.tk.informatik.tu-darmstadt.de/de/research/smart-security-and-trust/> for further details.
  7. *
  8. *
  9. * Telecooperation Department, Technische Universit�t Darmstadt
  10. * <http://www.tk.informatik.tu-darmstadt.de/>
  11. *
  12. * Prof. Dr. Max Mühlhäuser <max@informatik.tu-darmstadt.de>
  13. * Florian Volk <florian.volk@cased.de>
  14. *
  15. *
  16. * @author Maria Pelevina
  17. * @author David Kalnischkies
  18. * @version 1.1
  19. */
  20. /* This Source Code Form is subject to the terms of the Mozilla Public
  21. * License, v. 2.0. If a copy of the MPL was not distributed with this
  22. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  23. package CertainTrust;
  24. import java.util.Observable;
  25. /**
  26. *
  27. * t - average rating value, [0; 1], from very negative to very positive
  28. * c - certainty value, [0; 1] from low certainty (no evidence) to the maximal maximal certainty.
  29. * f - initial trust value
  30. * w - weight
  31. * r - number of positive evidence
  32. * s - number of negative evidence
  33. * n - maximal number of expected evidence
  34. * doc - degree of conflict
  35. *
  36. */
  37. public class CertainTrust extends Observable {
  38. private double c, t, f, r, s, doc;
  39. private int n, weight = 2;
  40. //=========== Constructors =================
  41. /**
  42. * Constructs a CertainTrust object with predefined n value.
  43. * @param n - maximal number of expected evidence
  44. */
  45. public CertainTrust(int n) {
  46. if (n > 0) {
  47. this.n = n;
  48. c = 0;
  49. t = 0.5;
  50. f = 0.5;
  51. r = 0;
  52. s = 0;
  53. }
  54. else throw new IllegalArgumentException("N should be greater than 0. Entered n = " + n + "\n");
  55. }
  56. /**
  57. * Constructs a CertainTrust object with predefined r, s, n values.
  58. * @param r - number of positive evidence
  59. * @param s - number of negative evidence
  60. * @param n - maximal number of expected evidence
  61. */
  62. public CertainTrust(double r, double s, int n) {
  63. if (n > 0) {
  64. this.n = n;
  65. this.c = 0;
  66. this.t = 0.5;
  67. this.f = 0.5;
  68. this.doc = 0;
  69. setRS(r, s);
  70. }
  71. else throw new IllegalArgumentException("N should be greater than 0. Entered n = " + n + "\n");
  72. }
  73. /**
  74. * Constructs a CertainTrust object with predefined c, t, f, n values.
  75. * @param c - certainty
  76. * @param t - average rating
  77. * @param f - initial trust value
  78. * @param n - maximal number of expected evidence
  79. */
  80. public CertainTrust(double t, double c, double f, int n) {
  81. this(t,c,f,n,0);
  82. }
  83. /**
  84. * Constructs a CertainTrust object with predefined c, t, f, n values.
  85. * @param c - certainty
  86. * @param t - average rating
  87. * @param f - initial trust value
  88. * @param n - maximal number of expected evidence
  89. * @param doc - initial degree of conflict
  90. */
  91. private CertainTrust(double t, double c, double f, int n, double doc) {
  92. if (n > 0) {
  93. if (f <= 1 && f >= 0) {
  94. this.n = n;
  95. this.f = f;
  96. this.r = 0;
  97. this.s = 0;
  98. this.doc = doc;
  99. setTC(t, c);
  100. }
  101. else throw new IllegalArgumentException("f should lie within [0;1]. Entered f = " + f + "\n");
  102. }
  103. else throw new IllegalArgumentException("N should be greater than 0. Entered n = " + n + "\n");
  104. }
  105. //=========== Setters =================
  106. /**
  107. * Resets N value. Renormalises r and s values, recalculates c and t accordingly.
  108. * @param n - new maximal number of expected evidence
  109. */
  110. public void setN(int n) {
  111. if (n > 0) {
  112. this.n = n;
  113. normaliseRS();
  114. calculateRStoTC();
  115. setChanged();
  116. notifyObservers();
  117. }
  118. else throw new IllegalArgumentException("N should be greater than 0. Entered n = " + n + "\n");
  119. }
  120. /**
  121. * Sets f value.
  122. * @param f - initial trust value.
  123. */
  124. public void setF(double f) {
  125. if (f >= 0 && f <= 1) {
  126. this.f = f;
  127. setChanged();
  128. notifyObservers();
  129. }
  130. else throw new IllegalArgumentException("f should lie within [0;1]. Entered f = " + f + "\n");
  131. }
  132. /**
  133. * Sets Distance of Conflict value.
  134. * @param doc is the new value for DoC
  135. */
  136. public void setDoC(double doc) {
  137. if (doc > 0) {
  138. this.doc = doc;
  139. }
  140. else throw new IllegalArgumentException("DoC should be greater than 0. Entered DoC = " + doc + "\n");
  141. }
  142. /**
  143. * Sets c and t values. Recalculates r and s values accordingly.
  144. * @param t - new average trust value
  145. * @param c - new certainty value
  146. */
  147. public void setTC(double t, double c) {
  148. if (c >= 0 && c <= 1) {
  149. if (t >= 0 && t <= 1) {
  150. this.c = c;
  151. this.t = t;
  152. calculateTCtoRS();
  153. setChanged();
  154. notifyObservers();
  155. }
  156. else throw new IllegalArgumentException("t should be greater than 0. Entered t = " + t + "\n");
  157. }
  158. else throw new IllegalArgumentException("c should lie within [0;1]. Entered c = " + c + "\n");
  159. }
  160. /**
  161. * Sets r and s values. Recalculates c and t values accordingly.
  162. * @param r - new number of positive evidence
  163. * @param s - new number of negative evidence
  164. */
  165. public void setRS(double r, double s) {
  166. if (r >= 0) {
  167. if (s >= 0) {
  168. this.r = r;
  169. this.s = s;
  170. normaliseRS();
  171. calculateRStoTC();
  172. setChanged();
  173. notifyObservers();
  174. }
  175. else throw new IllegalArgumentException("s should be positive. Entered s = " + s + "\n");
  176. }
  177. else throw new IllegalArgumentException("r should be positive. Entered r = " + r + "\n");
  178. }
  179. /**
  180. * Add some positive evidence to r.
  181. * @param posEvidence - number of new positive evidences
  182. */
  183. public void addR(int posEvidence) {
  184. if (posEvidence >= 0) {
  185. r += posEvidence;
  186. normaliseRS();
  187. calculateRStoTC();
  188. setChanged();
  189. notifyObservers();
  190. }
  191. else throw new IllegalArgumentException("Number of positive evidences should be positive. Entered " + posEvidence + "\n");
  192. }
  193. /**
  194. * Add some negative evidence to s.
  195. * @param negEvidence - number of new negative evidences
  196. */
  197. public void addS(int negEvidence) {
  198. if (negEvidence >= 0) {
  199. s += negEvidence;
  200. normaliseRS();
  201. calculateRStoTC();
  202. setChanged();
  203. notifyObservers();
  204. }
  205. else throw new IllegalArgumentException("Number of negative evidences should be positive. Entered " + negEvidence + "\n");
  206. }
  207. //=========== Internal Calculations ==========
  208. /**
  209. * Normalises r and s values according to n - maximal number of expected evidence
  210. * Important! Doesn't notify observers.
  211. */
  212. private void normaliseRS() {
  213. if (r + s > n){
  214. double initR = r;
  215. r = r*n / (initR + s);
  216. s = s*n / (initR + s);
  217. }
  218. }
  219. /**
  220. * Calculates c and t values based on existing r and s values
  221. * Important! Doesn't notify observers.
  222. */
  223. private void calculateRStoTC() {
  224. c = n * (r + s) / ( weight*(n-r-s) + n*(r+s));
  225. if (c == 0)
  226. t = 0.5;
  227. else t = r / (r + s);
  228. }
  229. /**
  230. * Calculates r and s values based on existing c and t values
  231. * Important! Doesn't notify observers.
  232. */
  233. private void calculateTCtoRS() {
  234. if (c == 0) {
  235. r = 0;
  236. s = 0;
  237. t = 0.5;
  238. }
  239. else {
  240. r = (2*c*weight*n*t) / (2*c*weight + n - c*n);
  241. s = (2*c*weight*n - 2*c*weight*n*t) / (2*c*weight + n - c*n);
  242. }
  243. }
  244. //=========== Getters =================
  245. public double getC() {
  246. return c;
  247. }
  248. public double getT() {
  249. return t;
  250. }
  251. public double getF() {
  252. return f;
  253. }
  254. public double getR() {
  255. return r;
  256. }
  257. public double getS() {
  258. return s;
  259. }
  260. public int getN() {
  261. return n;
  262. }
  263. public double getDoC() {
  264. return doc;
  265. }
  266. public double getExpectation() {
  267. return t*c + (1-c)*f;
  268. }
  269. //=========== Logic =================
  270. /**
  271. * Computes OR function for this CertainTrust object and the specified argument. Result is returned as a new object,
  272. * argument and this CertainTrust object remain unchanged.
  273. * N values of both objects should be equal.
  274. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  275. * @param arg - CertainTrust object
  276. * @return - result of OR computation for this object and an argument.
  277. */
  278. private CertainTrust OR(CertainTrust arg){
  279. double c1 = getC();
  280. double t1 = getT();
  281. double f1 = getF();
  282. double c2 = arg.getC();
  283. double t2 = arg.getT();
  284. double f2 = arg.getF();
  285. double resT = 0.5, resF = 0.5, resC = 0;
  286. if (this.getN() != arg.getN())
  287. throw new IllegalStateException("Different N values. Operation not allowed. \n");
  288. resF = f1 + f2 - f1*f2;
  289. if (almostEqual(resF, 0))
  290. resC = c1 + c2 - c1*c2;
  291. else
  292. resC = c1 + c2 - c1*c2 - (c1*f2*(1-c2)*(1-t1)+c2*f1*(1-c1)*(1-t2)) / resF;
  293. if (almostEqual(resC, 0))
  294. resT = 0.5;
  295. else resT = (1/resC) * (c1*t1 + c2*t2 - c1*c2*t1*t2);
  296. resT = adjustValue(resT);
  297. resC = adjustValue(resC);
  298. resF = adjustValue(resF);
  299. CertainTrust result = new CertainTrust(resT, resC, resF, n, 0);
  300. return result;
  301. }
  302. /**
  303. * Computes OR function for this CertainTrust object and the specified arguments.
  304. * Result is returned as a new object, arguments and this CertainTrust object remain unchanged.
  305. * Example: a.OR(b, c, d) returns new CertainTrust object that equals a OR b OR c OR d.
  306. * Multiple arguments allowed, but not less than one.
  307. * N values of all objects should be equal.
  308. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  309. * @param args - arguments
  310. * @return - result of OR computation for this object and all arguments.
  311. */
  312. public CertainTrust OR(CertainTrust ...args) {
  313. CertainTrust result = clone();
  314. for (CertainTrust m: args) {
  315. if (n != m.getN())
  316. throw new IllegalStateException("Different N values. Operation not allowed. \n");
  317. result = result.OR(m);
  318. }
  319. return result;
  320. }
  321. /**
  322. * Computes AND function for this CertainTrust object and the specified argument. Result is returned as a new object,
  323. * argument and this CertainTrust object remain unchanged.
  324. * N values of both objects should be equal.
  325. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  326. * @param arg - CertainTrust object
  327. * @return - result of AND computation for this object and an argument.
  328. */
  329. private CertainTrust AND(CertainTrust arg){
  330. double c1 = getC();
  331. double f1 = getF();
  332. double t1 = getT();
  333. double c2 = arg.getC();
  334. double f2 = arg.getF();
  335. double t2 = arg.getT();
  336. double resC = 0, resT = 0.5, resF = 0.5;
  337. if (n != arg.getN())
  338. throw new IllegalStateException("Different N values. Operation not allowed. \n");
  339. resF = f1*f2;
  340. if (almostEqual(resF, 1)) //avoid division by 0
  341. resC = c1 + c2 - c1*c2;
  342. else
  343. resC = c1 + c2 - c1*c2 - (c2*t2*(1-c1)*(1-f1)+c1*t1*(1-c2)*(1-f2)) / (1 - resF);
  344. if (almostEqual(resC, 0))
  345. resT = 0.5;
  346. else if (almostEqual(resF, 1)) //avoid division by 0
  347. resT = (1/resC) * (c1*t1*c2*t2);
  348. else resT = (1/resC) * ((c1*t1*c2*t2) + (c1*f2*t1*(1-c2)*(1-f1)+c2*f1*t2*(1-c1)*(1-f2)) / (1 - resF));
  349. resT = adjustValue(resT);
  350. resC = adjustValue(resC);
  351. resF = adjustValue(resF);
  352. CertainTrust result = new CertainTrust(resT, resC, resF, n, 0);
  353. return result;
  354. }
  355. /**
  356. * Computes AND function for this CertainTrust object and the specified arguments.
  357. * Result is returned as a new object, arguments and this CertainTrust object remain unchanged.
  358. * Example: a.AND(b, c, d) returns new CertainTrust object that equals a AND b AND c AND d.
  359. * Multiple arguments allowed, but not less than one.
  360. * N values of all objects should be equal.
  361. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  362. * @param args - arguments
  363. * @return - result of AND computation for this object and all arguments.
  364. */
  365. public CertainTrust AND(CertainTrust ...args) {
  366. CertainTrust result = clone();
  367. for (CertainTrust m: args) {
  368. if (n != m.getN())
  369. throw new IllegalStateException("Different N values. Operation not allowed. \n");
  370. result = result.AND(m);
  371. }
  372. return result;
  373. }
  374. /**
  375. * Returns NOT of this CertainTrust object.
  376. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  377. * @return - NOT of this CertainTrust object.
  378. */
  379. public CertainTrust NOT(){
  380. return new CertainTrust(getC(), adjustValue(1 - getT()), adjustValue(1 - getF()), n, 0);
  381. }
  382. /**
  383. * an internal implementation of fusion function.
  384. * Is called by wFusion and cFusion
  385. * @param args - an array of CertainTrust objects
  386. * @param weights - an integer array of corresponding weights
  387. * @param doc - a degree of conflict (always 0 for wFusion)
  388. * @return - new CertainTrust object
  389. */
  390. private static CertainTrust internalFusion(CertainTrust[] args, int[] weights, double doc) {
  391. double resC, resT, resF;
  392. boolean allOne = true;
  393. boolean allZero = true;
  394. boolean allWeightsZero = true;
  395. boolean atLeastOne1 = false;
  396. int arrLength = args.length;
  397. // set the flags about C and Weight values
  398. for (int i = 0; i < arrLength; i++)
  399. if (args[i].getC() != 1) {
  400. allOne = false;
  401. i = arrLength;
  402. }
  403. for (int i = 0; i < arrLength; i++)
  404. if (args[i].getC() != 0) {
  405. allZero = false;
  406. i = arrLength;
  407. }
  408. for (int i = 0; i < arrLength; i++)
  409. if (weights[i] != 0) {
  410. allWeightsZero = false;
  411. i = arrLength;
  412. }
  413. for (int i = 0; i < arrLength; i++)
  414. if (args[i].getC() == 1) {
  415. atLeastOne1 = true;
  416. i = arrLength;
  417. }
  418. //Calculate T and C
  419. // 1. all C's = 1
  420. if (allOne) {
  421. // set C
  422. resC = 1 * (1 - doc);
  423. // set T
  424. if (allWeightsZero) {// save some calculation time
  425. resT = 0;
  426. }
  427. else { // or use the function
  428. double numeratorT = 0, denominatorT = 0;
  429. for (int i = 0; i < arrLength; i++) {
  430. numeratorT += weights[i] * args[i].getT();
  431. denominatorT += weights[i];
  432. }
  433. resT = numeratorT/denominatorT;
  434. }
  435. }
  436. else {
  437. if (atLeastOne1)
  438. throw new IllegalStateException("Illeagal arguments. Either all C values must equal 1 or none of them. Operation not allowed \n");
  439. // 2. Any other combination
  440. if (allWeightsZero) { // save some calculation time
  441. resT = 0;
  442. resC = 0;
  443. }
  444. else { // or use the function
  445. double numeratorT = 0, denominatorT = 0, numeratorC = 0, denominatorC = 0, mult;
  446. for (int i = 0; i < arrLength; i++) {
  447. mult = 1;
  448. for (int j = 0; j < arrLength; j++) // Count the product for each sum element
  449. if (j != i)
  450. mult *= 1 - args[j].getC();
  451. numeratorT += weights[i] * args[i].getT() * args[i].getC() * mult;
  452. denominatorT += weights[i] * args[i].getC() * mult;
  453. denominatorC += weights[i] * mult;
  454. }
  455. numeratorC = denominatorT;
  456. resC = (numeratorC/denominatorC) * (1 - doc);
  457. if (allZero)
  458. resT = 0.5;
  459. else
  460. resT = numeratorT/denominatorT;
  461. }
  462. // Special case for T
  463. if (allZero)
  464. resT = 0.5;
  465. }
  466. // Calculate F
  467. if (allWeightsZero)
  468. resF = 0;
  469. else {
  470. double numerator = 0, denominator = 0;
  471. for (int i = 0; i < arrLength; i ++) {
  472. numerator += weights[i] * args[i].getF();
  473. denominator += weights[i];
  474. }
  475. resF = numerator/denominator;
  476. }
  477. return new CertainTrust(resT, resC, resF, args[0].getN(), doc);
  478. }
  479. /**
  480. * Performs weighted fusion for an array of CertainTrust objects in correspondence with
  481. * an array of weights. Returns new CertainTrust object.
  482. * Requirements: N values of CertainTrust objects must be equal.
  483. * Number of weights should equal the number of CertainTrust objects.
  484. * Arrays must be non-empty
  485. * Either all of CertainTrust must be of certainty 1 or none of them.
  486. * @param args - an array of CertainTrust objects
  487. * @param weights - an integer array of corresponding weights
  488. * @return - new CertainTrust object
  489. */
  490. public static CertainTrust wFusion(CertainTrust[] args, int[] weights) {
  491. //arrays should be equal
  492. if (args.length == weights.length) {
  493. //and not empty
  494. if (args.length != 0) {
  495. boolean equalNs = true;
  496. int N = args[0].getN();
  497. for (int i = 1; i < args.length; i++)
  498. if (N != args[i].getN()) {
  499. equalNs = false;
  500. i = args.length;
  501. }
  502. //and all N's of TC's must be equal
  503. if (equalNs) {
  504. return internalFusion(args, weights, 0);
  505. }
  506. throw new IllegalStateException("Different N values. Operation not allowed. \n");
  507. }
  508. throw new IllegalStateException("Arrays are empty. Operation not allowed. \n");
  509. }
  510. throw new IllegalStateException("Different lengths of arrays. Operation not allowed. \n");
  511. }
  512. /**
  513. * Conflicted Fusion is a variation of weighted fusion, which additionally computes the degree of conflict
  514. * between given opinions (CertainTrust objects) and takes it into consideration while performing fusion.
  515. * The degree of conflict is then saved in the resulting CertainTrust object and may be checked with getDoC() function.
  516. * @param args - an array of CertainTrust objects
  517. * @param weights - an integer array of corresponding weights
  518. * @return - new CertainTrust object
  519. */
  520. public static CertainTrust cFusion(CertainTrust[] args, int[] weights) {
  521. //arrays should be equal
  522. if (args.length == weights.length) {
  523. //and not empty
  524. if (args.length != 0) {
  525. boolean equalNs = true;
  526. int N = args[0].getN();
  527. for (int i = 1; i < args.length; i++)
  528. if (N != args[i].getN()) {
  529. equalNs = false;
  530. i = args.length;
  531. }
  532. //and all N's of TC's must be equal
  533. if (equalNs) {
  534. double denominator = args.length*(args.length - 1) / 2;
  535. double numerator = 0;
  536. for (int i = 0; i < args.length; i++)
  537. for (int j = i; j < args.length; j++)
  538. numerator += Math.abs(args[i].getT() - args[j].getT()) * args[i].getC() * args[j].getC()*(1 - Math.abs((double)(weights[i] - weights[j])/(weights[i] + weights[j])));
  539. double doc = numerator/denominator;
  540. return internalFusion(args, weights, doc);
  541. }
  542. throw new IllegalStateException("Different N values. Operation not allowed. \n");
  543. }
  544. throw new IllegalStateException("Arrays are empty. Operation not allowed. \n");
  545. }
  546. throw new IllegalStateException("Different lengths of arrays. Operation not allowed. \n");
  547. }
  548. /**
  549. * Computes CONSENSUS function for this CertainTrust object and the specified argument. Result is returned as a new object,
  550. * argument and this CertainTrust object remain unchanged.
  551. * N values of both objects should be equal.
  552. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  553. * @param arg - CertainTrust object
  554. * @return - result of CONSENSUS computation for this object and an argument.
  555. */
  556. private CertainTrust CONSENSUS(CertainTrust arg){
  557. double c1 = getC();
  558. double f1 = getF();
  559. double t1 = getT();
  560. double c2 = arg.getC();
  561. double f2 = arg.getF();
  562. double t2 = arg.getT();
  563. double resC = 0, resT = 0.5, resF = 0.5;
  564. if (n != arg.getN())
  565. throw new IllegalStateException("Different N values. Operation not allowed. \n");
  566. //resF = f1*f2;
  567. if (almostEqual(resF, 1)) //avoid division by 0
  568. resC = (c1+c2-2*c1*c2)/(1-c1*c2);
  569. else
  570. resC = (c1+c2-2*c1*c2)/(1-c1*c2);
  571. if (almostEqual(resC, 0))
  572. resT = 0.5;
  573. else if (almostEqual(resF, 1)) //avoid division by 0
  574. resT = (c1*t1*(1-c2)+c2*t2*(1-c1))/(c1*(1-c2)+c2*(1-c1));
  575. else resT = (c1*t1*(1-c2)+c2*t2*(1-c1))/(c1*(1-c2)+c2*(1-c1));
  576. resT = adjustValue(resT);
  577. resC = adjustValue(resC);
  578. resF = adjustValue(resF);
  579. CertainTrust result = new CertainTrust(resT, resC, resF, n, 0);
  580. return result;
  581. }
  582. /**
  583. * Computes CONSENSUS function for this CertainTrust object and the specified arguments.
  584. * Result is returned as a new object, arguments and this CertainTrust object remain unchanged.
  585. * Example: a.CONSENSUS(b, c, d) returns new CertainTrust object that equals a CONSENSUS b CONSENSUS c CONSENSUS d.
  586. * Multiple arguments allowed, but not less than one.
  587. * N values of all objects should be equal.
  588. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  589. * @param args - arguments
  590. * @return - result of CONSENSUS computation for this object and all arguments.
  591. */
  592. public CertainTrust CONSENSUS(CertainTrust ...args) {
  593. CertainTrust result = clone();
  594. for (CertainTrust m: args) {
  595. if (n != m.getN())
  596. throw new IllegalStateException("Different N values. Operation not allowed. \n");
  597. result = result.CONSENSUS(m);
  598. }
  599. return result;
  600. }
  601. /**
  602. * Computes DISCOUNTING function for this CertainTrust object and the specified argument. Result is returned as a new object,
  603. * argument and this CertainTrust object remain unchanged.
  604. * N values of both objects should be equal.
  605. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  606. * @param arg - CertainTrust object
  607. * @return - result of DISCOUNTING computation for this object and an argument.
  608. */
  609. private CertainTrust DISCOUNTING(CertainTrust arg){
  610. double c1 = getC();
  611. double f1 = getF();
  612. double t1 = getT();
  613. double c2 = arg.getC();
  614. double f2 = arg.getF();
  615. double t2 = arg.getT();
  616. double resC = 0, resT = 0.5, resF = 0.5;
  617. if (n != arg.getN())
  618. throw new IllegalStateException("Different N values. Operation not allowed. \n");
  619. //resF = f1*f2;
  620. if (almostEqual(resF, 1))
  621. resC = t1*c1*c2;
  622. else
  623. resC = t1*c1*c2;
  624. if (almostEqual(resC, 0))
  625. resT = 0.5;
  626. else if (almostEqual(resF, 1))
  627. resT = t2;
  628. else resT = t2;
  629. resT = adjustValue(resT);
  630. resC = adjustValue(resC);
  631. resF = adjustValue(resF);
  632. CertainTrust result = new CertainTrust(resT, resC, resF, n, 0);
  633. return result;
  634. }
  635. /**
  636. * Computes DISCOUNTING function for this CertainTrust object and the specified arguments.
  637. * Result is returned as a new object, arguments and this CertainTrust object remain unchanged.
  638. * Example: a.DISCOUNTING(b, c, d) returns new CertainTrust object that equals a DISCOUNTING b DISCOUNTING c DISCOUNTING d.
  639. * Multiple arguments allowed, but not less than one.
  640. * N values of all objects should be equal.
  641. * For detailed information see CertainLogic: A Logic for Modeling Trust and Uncertainty
  642. * @param args - arguments
  643. * @return - result of DISCOUNTING computation for this object and all arguments.
  644. */
  645. public CertainTrust DISCOUNTING(CertainTrust ...args) {
  646. CertainTrust result = clone();
  647. for (CertainTrust m: args) {
  648. if (n != m.getN())
  649. throw new IllegalStateException("Different N values. Operation not allowed. \n");
  650. result = result.DISCOUNTING(m);
  651. }
  652. return result;
  653. }
  654. //=========== Additional Functions =================
  655. @Override
  656. public CertainTrust clone() {
  657. CertainTrust copy = new CertainTrust(n);
  658. copy.c = this.c;
  659. copy.t = this.t;
  660. copy.f = this.f;
  661. copy.r = this.r;
  662. copy.s = this.s;
  663. copy.doc = this.doc;
  664. return copy;
  665. }
  666. /**
  667. * Adjusts the value of a into the allowed range [0,1].
  668. * @param a - value to be adjusted
  669. */
  670. private double adjustValue(double a) {
  671. return Math.max(Math.min(a, 1), 0);
  672. }
  673. /**
  674. * compares two double values using an epsilon
  675. * @param value - given value
  676. * @param target - expected value
  677. * @return
  678. */
  679. private boolean almostEqual(double value, double target) {
  680. return Math.abs(value - target) < 1E-10;
  681. }
  682. }