23d4e24864666519e73dc128dd4d776f5ea9e1a0
[policy/apex-pdp.git] /
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
27 import org.onap.policy.apex.context.ContextException;
28 import org.onap.policy.apex.core.engine.executor.context.TaskSelectionExecutionContext;
29 import org.onap.policy.apex.examples.adaptive.concepts.AutoLearn;
30
31 /**
32  * The Class AutoLearnPolicy_Decide_TaskSelectionLogic.
33  */
34 // CHECKSTYLE:OFF: checkstyle:typeName
35 public class AutoLearnPolicy_Decide_TaskSelectionLogic {
36     // CHECKSTYLE:ON: checkstyle:typeName
37     private static final Random RAND = new Random(System.currentTimeMillis());
38     private static final double WANT = 50.0;
39     private int size;
40
41     /**
42      * Gets the task.
43      *
44      * @param executor the executor
45      * @return the task
46      */
47     public boolean getTask(final TaskSelectionExecutionContext executor) {
48         executor.logger.debug(executor.subject.getId());
49         executor.logger.debug(executor.inFields.toString());
50         final List<String> tasks = executor.subject.getTaskNames();
51         size = tasks.size();
52
53         try {
54             executor.getContextAlbum("AutoLearnAlbum").lockForWriting("AutoLearn");
55         } catch (final ContextException e) {
56             executor.logger.error("Failed to acquire write lock on \"autoLearn\" context", e);
57             return false;
58         }
59
60         // Get the context object
61         AutoLearn autoLearn = (AutoLearn) executor.getContextAlbum("AutoLearnAlbum").get("AutoLearn");
62         if (autoLearn == null) {
63             autoLearn = new AutoLearn();
64         }
65
66         // Check the lists are initialized
67         if (!autoLearn.isInitialized()) {
68             autoLearn.init(size);
69         }
70
71         final double now = (Double) (executor.inFields.get("MonitoredValue"));
72         final double diff = now - WANT;
73         final int option = getOption(diff, autoLearn);
74         learn(option, diff, autoLearn);
75
76         executor.getContextAlbum("AutoLearnAlbum").put("AutoLearnAlbum", autoLearn);
77
78         try {
79             executor.getContextAlbum("AutoLearnAlbum").unlockForWriting("AutoLearn");
80         } catch (final ContextException e) {
81             executor.logger.error("Failed to acquire write lock on \"autoLearn\" context", e);
82             return false;
83         }
84
85         executor.subject.getTaskKey(tasks.get(option)).copyTo(executor.selectedTask);
86         return true;
87     }
88
89     /**
90      * Gets the option.
91      *
92      * @param diff the diff
93      * @param autoLearn the auto learn
94      * @return the option
95      */
96     private int getOption(final double diff, final AutoLearn autoLearn) {
97         final Double[] avdiffs = autoLearn.getAvDiffs().toArray(new Double[autoLearn.getAvDiffs().size()]);
98         final int r = RAND.nextInt(size);
99         int closestupi = -1;
100         int closestdowni = -1;
101         double closestup = Double.MAX_VALUE;
102         double closestdown = Double.MIN_VALUE;
103         for (int i = 0; i < size; i++) {
104             if (Double.isNaN(avdiffs[i])) {
105                 return r;
106             }
107             if (avdiffs[i] >= diff && avdiffs[i] <= closestup) {
108                 closestup = avdiffs[i];
109                 closestupi = i;
110             }
111             if (avdiffs[i] <= diff && avdiffs[i] >= closestdown) {
112                 closestdown = avdiffs[i];
113                 closestdowni = i;
114             }
115         }
116         if (closestupi == -1 || closestdowni == -1) {
117             return r;
118         }
119         if (closestupi == closestdowni) {
120             return closestupi;
121         }
122         if (Math.abs(closestdown - diff) > Math.abs(closestup - diff)) {
123             return closestupi;
124         } else {
125             return closestdowni;
126         }
127     }
128
129     /**
130      * Learn.
131      *
132      * @param option the option
133      * @param diff the diff
134      * @param autoLearn the auto learn
135      */
136     private void learn(final int option, final double diff, final AutoLearn autoLearn) {
137         final Double[] avdiffs = autoLearn.getAvDiffs().toArray(new Double[autoLearn.getAvDiffs().size()]);
138         final Long[] counts = autoLearn.getCounts().toArray(new Long[autoLearn.getCounts().size()]);
139         if (option < 0 || option >= avdiffs.length) {
140             throw new IllegalArgumentException("Error: option" + option);
141         }
142         counts[option]++;
143         if (Double.isNaN(avdiffs[option])) {
144             avdiffs[option] = diff;
145         } else {
146             avdiffs[option] = (avdiffs[option] * (counts[option] - 1) + diff) / counts[option];
147         }
148         autoLearn.setAvDiffs(Arrays.asList(avdiffs));
149         autoLearn.setCounts(Arrays.asList(counts));
150     }
151 }