diff options
author | 2020-11-03 22:52:26 -0500 | |
---|---|---|
committer | 2020-11-03 22:52:26 -0500 | |
commit | 945f487a08b643392a5d5918c631640b9a0e4605 (patch) | |
tree | b537c456e395950ce98daaabb9468c7c17d5a72b /Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app | |
parent | Fix numeric-solver-at-end (diff) | |
download | VIATRA-Generator-945f487a08b643392a5d5918c631640b9a0e4605.tar.gz VIATRA-Generator-945f487a08b643392a5d5918c631640b9a0e4605.tar.zst VIATRA-Generator-945f487a08b643392a5d5918c631640b9a0e4605.zip |
add realistic solver
Diffstat (limited to 'Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app')
4 files changed, 404 insertions, 0 deletions
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Domain.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Domain.xtend new file mode 100644 index 00000000..c8fd435b --- /dev/null +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Domain.xtend | |||
@@ -0,0 +1,7 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app | ||
2 | |||
3 | enum Domain{ | ||
4 | Yakindumm, | ||
5 | Ecore, | ||
6 | Github | ||
7 | } \ No newline at end of file | ||
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend new file mode 100644 index 00000000..dfde6593 --- /dev/null +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend | |||
@@ -0,0 +1,96 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app | ||
2 | |||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.EMFGraph | ||
4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.CsvFileWriter | ||
5 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.GraphReader | ||
6 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.validation.ViolationCheck | ||
7 | import hu.bme.mit.inf.dslreasoner.domains.yakindu.sgraph.yakindumm.impl.YakindummPackageImpl | ||
8 | import java.io.File | ||
9 | import java.util.ArrayList | ||
10 | import org.eclipse.emf.ecore.EPackage | ||
11 | import org.eclipse.emf.ecore.EcorePackage | ||
12 | import org.eclipse.viatra.query.runtime.rete.matcher.ReteEngine | ||
13 | import org.eclipse.emf.ecore.impl.EcorePackageImpl | ||
14 | import org.eclipse.emf.ecore.EReference | ||
15 | |||
16 | //import yakindumm2.impl.Yakindumm2PackageImpl | ||
17 | |||
18 | class Main { | ||
19 | var static Domain d = Domain.Yakindumm; | ||
20 | val static String suffix = '.xmi' | ||
21 | val static String OUTPUT_FOLDER = "Inputs/measurement2/yakindu/Alloy/"; | ||
22 | val static String INPUT_FOLDER = "outputs/measurement2/yakindu/Alloy/"; | ||
23 | val static int NUM_RUNS = 1; | ||
24 | |||
25 | static class RWInformation{ | ||
26 | public var String inputFolder; | ||
27 | public var String outputFolder; | ||
28 | public var int numRuns; | ||
29 | |||
30 | new(String inputFolder, String outputFolder, int numRuns){ | ||
31 | this.inputFolder = inputFolder; | ||
32 | this.outputFolder = outputFolder; | ||
33 | this.numRuns = numRuns; | ||
34 | } | ||
35 | } | ||
36 | |||
37 | def static void main(String[] args){ | ||
38 | //init model | ||
39 | var EPackage metamodel; | ||
40 | //init viatra engine for the violation checker | ||
41 | ReteEngine.getClass(); | ||
42 | |||
43 | if(d == Domain.Yakindumm){ | ||
44 | YakindummPackageImpl.eINSTANCE.eClass; | ||
45 | metamodel = YakindummPackageImpl.eINSTANCE; | ||
46 | }else if (d == Domain.Ecore){ | ||
47 | EcorePackage.eINSTANCE.eClass; | ||
48 | metamodel = EcorePackageImpl.eINSTANCE; | ||
49 | }else if (d == Domain.Github){ | ||
50 | //TODO: Initialize Github Package | ||
51 | } | ||
52 | |||
53 | |||
54 | println("Start Reading Models..."); | ||
55 | var reader = new GraphReader(metamodel, suffix); | ||
56 | |||
57 | val models = new RWInformation(OUTPUT_FOLDER, INPUT_FOLDER, NUM_RUNS); | ||
58 | calculateAllModels(models.inputFolder, models.outputFolder,models.numRuns, reader); | ||
59 | println("finished"); | ||
60 | } | ||
61 | |||
62 | static def calculateAllModels(String inputFolder, String outputFolder, int numRuns, GraphReader reader){ | ||
63 | (new File(outputFolder)).mkdir(); | ||
64 | for(var i = 1; i <= numRuns; i++){ | ||
65 | val models = new ArrayList<EMFGraph>(); | ||
66 | models.addAll(reader.readModels(inputFolder + "run" + i)); | ||
67 | for(model : models){ | ||
68 | calculateAndOutputMetrics(model, YakindummPackageImpl.eNAME, outputFolder+model.name+"_run_"+i+".csv"); | ||
69 | } | ||
70 | } | ||
71 | println("output results Ended for: " + outputFolder); | ||
72 | |||
73 | |||
74 | } | ||
75 | |||
76 | static def calculateAndOutputMetrics(EMFGraph model, String metaModel, String fileName){ | ||
77 | //println("evaluating for " + model.name); | ||
78 | model.metaModel = metaModel; | ||
79 | |||
80 | //remove eGenericType for Ecore domain | ||
81 | if(d == Domain.Ecore){ | ||
82 | var refsToRemove = EcorePackageImpl.eINSTANCE.eAllContents.filter(EReference).filter[ | ||
83 | it.name.equals('eGenericType') || it.name.equals('eGenericSuperTypes') || it.name.equals('eFactoryInstance')|| | ||
84 | it.name.equals('eGenericExceptions') || it.name.equals('references') || it.name.equals('contents'); | ||
85 | ]; | ||
86 | refsToRemove.forEach[model.removeReference(it)]; | ||
87 | } | ||
88 | |||
89 | var outputs = model.evaluateAllMetrics(); | ||
90 | var violations = ViolationCheck.calculateViolationCounts(model.root, d); | ||
91 | println(violations); | ||
92 | var violationsOutput = newArrayList('violations', violations+''); | ||
93 | outputs.add(violationsOutput); | ||
94 | CsvFileWriter.write(outputs, fileName); | ||
95 | } | ||
96 | } \ No newline at end of file | ||
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetric.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetric.xtend new file mode 100644 index 00000000..5e62b586 --- /dev/null +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetric.xtend | |||
@@ -0,0 +1,85 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app | ||
2 | |||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.JSDistance | ||
4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.KSDistance | ||
5 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.PartialInterpretationGraph | ||
6 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.CsvFileWriter | ||
7 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric | ||
8 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric | ||
9 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric | ||
10 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric | ||
11 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | ||
12 | import java.io.File | ||
13 | import java.io.FileNotFoundException | ||
14 | import java.io.PrintWriter | ||
15 | import java.util.ArrayList | ||
16 | import java.util.List | ||
17 | import org.eclipse.emf.ecore.util.EcoreUtil | ||
18 | import org.eclipse.viatra.dse.api.Solution | ||
19 | |||
20 | class PartialInterpretationMetric { | ||
21 | var static KSDistance ks; | ||
22 | var static JSDistance js; | ||
23 | |||
24 | def static void initPaths(){ | ||
25 | new File("debug/metric/").mkdir(); | ||
26 | new File("debug/metric/trajectories/").mkdir(); | ||
27 | } | ||
28 | |||
29 | // calculate the metrics for a state | ||
30 | def static void calculateMetric(PartialInterpretation partial, String path, String currentStateId, Integer counter){ | ||
31 | val metrics = new ArrayList<Metric>(); | ||
32 | metrics.add(new OutDegreeMetric()); | ||
33 | metrics.add(new NodeActivityMetric()); | ||
34 | metrics.add(new MultiplexParticipationCoefficientMetric()); | ||
35 | |||
36 | //make dir since the folder can be none existing | ||
37 | new File(path).mkdir(); | ||
38 | val filename = path + "/state_"+currentStateId+"-"+counter+".csv"; | ||
39 | val metricCalculator = new PartialInterpretationGraph(partial, metrics, currentStateId); | ||
40 | |||
41 | CsvFileWriter.write(metricCalculator.evaluateAllMetrics(), filename); | ||
42 | } | ||
43 | |||
44 | def static void outputTrajectories(PartialInterpretation empty, List<Solution> solutions){ | ||
45 | for(solution : solutions){ | ||
46 | |||
47 | //need to copy the empty solution because the transition directly worked on the graph | ||
48 | val emptySolutionCopy = EcoreUtil.copy(empty) | ||
49 | val trajectory = solution.shortestTrajectory; | ||
50 | trajectory.model = emptySolutionCopy | ||
51 | |||
52 | // state codes that will record the trajectory | ||
53 | val stateCodes = newArrayList() | ||
54 | var counter = 0 | ||
55 | |||
56 | //transform and record the state codes for each state | ||
57 | while(trajectory.doNextTransformation){ | ||
58 | //println(trajectory.stateCoder.createStateCode) | ||
59 | val stateId = trajectory.stateCoder.createStateCode.toString | ||
60 | val interpretation = trajectory.getModel(); | ||
61 | println(stateId) | ||
62 | //calculate metrics of current state | ||
63 | calculateMetric(interpretation as PartialInterpretation, "debug/metric/output", stateId, counter) | ||
64 | stateCodes.add(stateId) | ||
65 | counter++ | ||
66 | } | ||
67 | |||
68 | |||
69 | //output the trajectory | ||
70 | try{ | ||
71 | new File("debug/metric/trajectories/").mkdir(); | ||
72 | val path = "debug/metric/trajectories/trajectory"+trajectory.stateCoder.createStateCode.toString+".csv" | ||
73 | val PrintWriter writer = new PrintWriter(new File(path)) | ||
74 | val output = new StringBuilder | ||
75 | for(stateCode : stateCodes){ | ||
76 | output.append(stateCode+'\n') | ||
77 | } | ||
78 | writer.write(output.toString()) | ||
79 | writer.close() | ||
80 | }catch(FileNotFoundException e) { | ||
81 | e.printStackTrace() | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | } \ No newline at end of file | ||
diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetricDistance.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetricDistance.xtend new file mode 100644 index 00000000..697b2639 --- /dev/null +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetricDistance.xtend | |||
@@ -0,0 +1,216 @@ | |||
1 | package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app | ||
2 | |||
3 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.EuclideanDistance | ||
4 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.JSDistance | ||
5 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.KSDistance | ||
6 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.StateData | ||
7 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.PartialInterpretationGraph | ||
8 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.RepMetricsReader | ||
9 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric | ||
10 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup | ||
11 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric | ||
12 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric | ||
13 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeTypeMetric | ||
14 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric | ||
15 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.predictor.LinearModel | ||
16 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | ||
17 | import java.util.ArrayList | ||
18 | import java.util.HashMap | ||
19 | import java.util.List | ||
20 | import java.util.Map | ||
21 | import org.apache.commons.math3.stat.regression.OLSMultipleLinearRegression | ||
22 | import org.eclipse.xtend.lib.annotations.Accessors | ||
23 | import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.EdgeTypeMetric | ||
24 | |||
25 | class PartialInterpretationMetricDistance { | ||
26 | |||
27 | var KSDistance ks; | ||
28 | var JSDistance js; | ||
29 | var EuclideanDistance ed; | ||
30 | var Map<Object, StateData> stateAndHistory; | ||
31 | var OLSMultipleLinearRegression regression; | ||
32 | List<StateData> samples; | ||
33 | var MetricSampleGroup g; | ||
34 | @Accessors(PUBLIC_GETTER) | ||
35 | var LinearModel linearModel; | ||
36 | |||
37 | |||
38 | new(Domain d){ | ||
39 | var metrics = RepMetricsReader.read(d); | ||
40 | this.g = metrics; | ||
41 | ks = new KSDistance(g); | ||
42 | js = new JSDistance(g); | ||
43 | ed = new EuclideanDistance(g); | ||
44 | regression = new OLSMultipleLinearRegression(); | ||
45 | regression.noIntercept = false; | ||
46 | stateAndHistory = new HashMap<Object, StateData>(); | ||
47 | samples = new ArrayList<StateData>(); | ||
48 | linearModel = new LinearModel(0.01); | ||
49 | } | ||
50 | |||
51 | def MetricDistanceGroup calculateMetricDistanceKS(PartialInterpretation partial){ | ||
52 | val metrics = new ArrayList<Metric>(); | ||
53 | metrics.add(new OutDegreeMetric()); | ||
54 | metrics.add(new NodeActivityMetric()); | ||
55 | metrics.add(new MultiplexParticipationCoefficientMetric()); | ||
56 | metrics.add(new NodeTypeMetric()); | ||
57 | val metricCalculator = new PartialInterpretationGraph(partial, metrics, null); | ||
58 | var metricSamples = metricCalculator.evaluateAllMetricsToSamples(); | ||
59 | |||
60 | var mpc = ks.mpcDistance(metricSamples.mpcSamples); | ||
61 | var na = ks.naDistance(metricSamples.naSamples); | ||
62 | var outDegree = ks.outDegreeDistance(metricSamples.outDegreeSamples); | ||
63 | var nodeType = ks.nodeTypeDistance(metricSamples.nodeTypeSamples); | ||
64 | //var typedOutDegree = ks.typedOutDegreeDistance(metricSamples.typedOutDegreeSamples); | ||
65 | var distance = new MetricDistanceGroup(mpc, na, outDegree, nodeType); | ||
66 | distance.nodeTypeInfo = metricSamples.nodeTypeSamples; | ||
67 | return distance; | ||
68 | } | ||
69 | |||
70 | def MetricDistanceGroup calculateMetricEuclidean(PartialInterpretation partial){ | ||
71 | val metrics = new ArrayList<Metric>(); | ||
72 | metrics.add(new OutDegreeMetric()); | ||
73 | metrics.add(new NodeActivityMetric()); | ||
74 | metrics.add(new MultiplexParticipationCoefficientMetric()); | ||
75 | |||
76 | val metricCalculator = new PartialInterpretationGraph(partial, metrics, null); | ||
77 | var metricSamples = metricCalculator.evaluateAllMetricsToSamples(); | ||
78 | |||
79 | var mpc = ed.mpcDistance(metricSamples.mpcSamples); | ||
80 | var na = ed.naDistance(metricSamples.naSamples); | ||
81 | var outDegree = ed.outDegreeDistance(metricSamples.outDegreeSamples); | ||
82 | |||
83 | return new MetricDistanceGroup(mpc, na, outDegree); | ||
84 | } | ||
85 | |||
86 | def MetricDistanceGroup calculateMetricDistance(PartialInterpretation partial){ | ||
87 | val metrics = new ArrayList<Metric>(); | ||
88 | metrics.add(new OutDegreeMetric()); | ||
89 | metrics.add(new NodeActivityMetric()); | ||
90 | metrics.add(new MultiplexParticipationCoefficientMetric()); | ||
91 | |||
92 | val metricCalculator = new PartialInterpretationGraph(partial, metrics, null); | ||
93 | var metricSamples = metricCalculator.evaluateAllMetricsToSamples(); | ||
94 | |||
95 | var mpc = js.mpcDistance(metricSamples.mpcSamples); | ||
96 | var na = js.naDistance(metricSamples.naSamples); | ||
97 | var outDegree = js.outDegreeDistance(metricSamples.outDegreeSamples); | ||
98 | |||
99 | return new MetricDistanceGroup(mpc, na, outDegree); | ||
100 | } | ||
101 | |||
102 | def resetRegression(Object state){ | ||
103 | samples.clear(); | ||
104 | |||
105 | if(stateAndHistory.containsKey(state)){ | ||
106 | var data = stateAndHistory.get(state); | ||
107 | |||
108 | var curState = state; | ||
109 | |||
110 | samples.add(data); | ||
111 | |||
112 | while(stateAndHistory.containsKey(data.lastState) && data.lastState != curState){ | ||
113 | curState = data.lastState; | ||
114 | data = stateAndHistory.get(data.lastState); | ||
115 | samples.add(data); | ||
116 | } | ||
117 | |||
118 | if(samples.size == 0){ | ||
119 | println('state: ' + state); | ||
120 | println('last state: ' + data.lastState); | ||
121 | } | ||
122 | } | ||
123 | println("trajectory sample size:" + samples.size) | ||
124 | } | ||
125 | |||
126 | def feedData(Object state, double[] features, double value, Object lastState){ | ||
127 | var data = new StateData(features, value, lastState); | ||
128 | stateAndHistory.put(state, data); | ||
129 | samples.add(data); | ||
130 | } | ||
131 | |||
132 | def getPredictionForNextDataSample(double[] features, double value, double[] featuresToPredict){ | ||
133 | if(samples.size <= 4){ | ||
134 | println('OK'); | ||
135 | } | ||
136 | var data = new StateData(features, value, null); | ||
137 | samples.add(data); | ||
138 | |||
139 | // create training set from current data | ||
140 | var double[][] xSamples = samples.map[it.features]; | ||
141 | var double[] ySamples = samples.map[it.value]; | ||
142 | |||
143 | |||
144 | regression.newSampleData(ySamples, xSamples); | ||
145 | var prediction = predict(featuresToPredict); | ||
146 | |||
147 | //remove the last element just added | ||
148 | samples.remove(samples.size - 1); | ||
149 | return prediction; | ||
150 | } | ||
151 | |||
152 | def private predict(double[] featuresToPredict){ | ||
153 | var parameters = regression.estimateRegressionParameters(); | ||
154 | // the regression will add an initial column for 1's, the first parameter is constant term | ||
155 | var result = parameters.get(0); | ||
156 | for(var i = 0; i < featuresToPredict.length; i++){ | ||
157 | result += parameters.get(i+1) * featuresToPredict.get(i); | ||
158 | } | ||
159 | return result; | ||
160 | } | ||
161 | |||
162 | def double[] calculateFeature(int step, int violations){ | ||
163 | var features = newDoubleArrayOfSize(2); | ||
164 | //constant term | ||
165 | features.set(0, 1); //a | ||
166 | features.set(0, Math.sqrt(step) + 30) // b | ||
167 | features.set(1, 1.0 / (step + 30) );// c | ||
168 | |||
169 | |||
170 | // features.set(2, violations); | ||
171 | // features.set(3, Math.pow(violations, 2)); | ||
172 | |||
173 | return features; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | class MetricDistanceGroup{ | ||
178 | var double mpcDistance; | ||
179 | var double naDistance; | ||
180 | var double outDegreeDistance; | ||
181 | var double nodeTypeDistance; | ||
182 | protected var HashMap<String, Double> nodeTypeInfo; | ||
183 | |||
184 | new(double mpcDistance, double naDistance, double outDegreeDistance, double nodeTypeDistance){ | ||
185 | this.mpcDistance = mpcDistance; | ||
186 | this.naDistance = naDistance; | ||
187 | this.outDegreeDistance = outDegreeDistance; | ||
188 | this.nodeTypeDistance = nodeTypeDistance; | ||
189 | } | ||
190 | |||
191 | new(double mpcDistance, double naDistance, double outDegreeDistance){ | ||
192 | this.mpcDistance = mpcDistance; | ||
193 | this.naDistance = naDistance; | ||
194 | this.outDegreeDistance = outDegreeDistance; | ||
195 | } | ||
196 | |||
197 | def double getNodeTypeDistance(){ | ||
198 | return this.nodeTypeDistance; | ||
199 | } | ||
200 | |||
201 | def double getMPCDistance(){ | ||
202 | return this.mpcDistance | ||
203 | } | ||
204 | |||
205 | def double getNADistance(){ | ||
206 | return this.naDistance | ||
207 | } | ||
208 | |||
209 | def double getOutDegreeDistance(){ | ||
210 | return this.outDegreeDistance | ||
211 | } | ||
212 | |||
213 | def double getNodeTypePercentage(String typeName){ | ||
214 | return nodeTypeInfo.getOrDefault(typeName, 0.0); | ||
215 | } | ||
216 | } \ No newline at end of file | ||