Changes for checkstyle 8.32
[policy/apex-pdp.git] / examples / examples-adaptive / src / main / java / org / onap / policy / apex / examples / adaptive / model / java / AutoLearnPolicyDecideTaskSelectionLogic.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.apex.examples.adaptive.model.java;
22
23 import java.util.Arrays;
24 import java.util.List;
25 import java.util.Random;
26 import org.onap.policy.apex.context.ContextException;
27 import org.onap.policy.apex.core.engine.executor.context.TaskSelectionExecutionContext;
28 import org.onap.policy.apex.examples.adaptive.concepts.AutoLearn;
29
30 /**
31  * The Class AutoLearnPolicyDecideTaskSelectionLogic.
32  */
33 public class AutoLearnPolicyDecideTaskSelectionLogic {
34     // Recurring string constants
35     private static final String AUTO_LEARN_ALBUM = "AutoLearnAlbum";
36     private static final String AUTO_LEARN = "AutoLearn";
37
38     private static final Random RAND = new Random(System.currentTimeMillis());
39     private static final double WANT = 50.0;
40     private int size;
41
42     /**
43      * Gets the task.
44      *
45      * @param executor the executor
46      * @return the task
47      */
48     public boolean getTask(final TaskSelectionExecutionContext executor) {
49         String idString = executor.subject.getId();
50         executor.logger.debug(idString);
51
52         String inFieldsString = executor.inFields.toString();
53         executor.logger.debug(inFieldsString);
54
55         final List<String> tasks = executor.subject.getTaskNames();
56         size = tasks.size();
57
58         try {
59             executor.getContextAlbum(AUTO_LEARN_ALBUM).lockForWriting(AUTO_LEARN);
60         } catch (final ContextException e) {
61             executor.logger.error("Failed to acquire write lock on \"autoLearn\" context", e);
62             return false;
63         }
64
65         // Get the context object
66         AutoLearn autoLearn = (AutoLearn) executor.getContextAlbum(AUTO_LEARN_ALBUM).get(AUTO_LEARN);
67         if (autoLearn == null) {
68             autoLearn = new AutoLearn();
69         }
70
71         // Check the lists are initialized
72         if (!autoLearn.isInitialized()) {
73             autoLearn.init(size);
74         }
75
76         final double now = (Double) (executor.inFields.get("MonitoredValue"));
77         final double diff = now - WANT;
78         final int option = getOption(diff, autoLearn);
79         learn(option, diff, autoLearn);
80
81         executor.getContextAlbum(AUTO_LEARN_ALBUM).put(AUTO_LEARN_ALBUM, autoLearn);
82
83         try {
84             executor.getContextAlbum(AUTO_LEARN_ALBUM).unlockForWriting(AUTO_LEARN);
85         } catch (final ContextException e) {
86             executor.logger.error("Failed to acquire write lock on \"autoLearn\" context", e);
87             return false;
88         }
89
90         executor.subject.getTaskKey(tasks.get(option)).copyTo(executor.selectedTask);
91         return true;
92     }
93
94     /**
95      * Gets the option.
96      *
97      * @param diff the diff
98      * @param autoLearn the auto learn
99      * @return the option
100      */
101     private int getOption(final double diff, final AutoLearn autoLearn) {
102         final Double[] avdiffs = autoLearn.getAvDiffs().toArray(new Double[autoLearn.getAvDiffs().size()]);
103         final int r = RAND.nextInt(size);
104         int closestupi = -1;
105         int closestdowni = -1;
106         double closestup = Double.MAX_VALUE;
107         double closestdown = Double.MIN_VALUE;
108         for (int i = 0; i < size; i++) {
109             if (Double.isNaN(avdiffs[i])) {
110                 return r;
111             }
112             if (avdiffs[i] >= diff && avdiffs[i] <= closestup) {
113                 closestup = avdiffs[i];
114                 closestupi = i;
115             }
116             if (avdiffs[i] <= diff && avdiffs[i] >= closestdown) {
117                 closestdown = avdiffs[i];
118                 closestdowni = i;
119             }
120         }
121         return calculateReturnValue(diff, r, closestupi, closestdowni, closestup, closestdown);
122     }
123
124     /**
125      * Learn.
126      *
127      * @param option the option
128      * @param diff the diff
129      * @param autoLearn the auto learn
130      */
131     private void learn(final int option, final double diff, final AutoLearn autoLearn) {
132         final Double[] avdiffs = autoLearn.getAvDiffs().toArray(new Double[autoLearn.getAvDiffs().size()]);
133         final Long[] counts = autoLearn.getCounts().toArray(new Long[autoLearn.getCounts().size()]);
134         if (option < 0 || option >= avdiffs.length) {
135             throw new IllegalArgumentException("Error: option" + option);
136         }
137         counts[option]++;
138         if (Double.isNaN(avdiffs[option])) {
139             avdiffs[option] = diff;
140         } else {
141             avdiffs[option] = (avdiffs[option] * (counts[option] - 1) + diff) / counts[option];
142         }
143         autoLearn.setAvDiffs(Arrays.asList(avdiffs));
144         autoLearn.setCounts(Arrays.asList(counts));
145     }
146
147     /**
148      * Calculate the return value of the learning.
149      * 
150      * @param diff the difference
151      * @param random the random value
152      * @param closestupi closest to i upwards
153      * @param closestdowni closest to i downwards
154      * @param closestup closest up value
155      * @param closestdown closest down value
156      * @return the return value
157      */
158     private int calculateReturnValue(final double diff, final int random, int closestupi, int closestdowni,
159         double closestup, double closestdown) {
160         if (closestupi == -1 || closestdowni == -1) {
161             return random;
162         }
163         if (closestupi == closestdowni) {
164             return closestupi;
165         }
166         if (Math.abs(closestdown - diff) > Math.abs(closestup - diff)) {
167             return closestupi;
168         } else {
169             return closestdowni;
170         }
171     }
172 }