Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
Comparing the query complexity of active learning algorithms for deterministic finite automata
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Muhammad Raufu Miah
Comparing the query complexity of active learning algorithms for deterministic finite automata
Commits
b944be90
Commit
b944be90
authored
1 year ago
by
Muhammad Raufu Miah
Browse files
Options
Downloads
Patches
Plain Diff
Add new file
parent
e9218196
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
ExperimentsScaleState.java
+355
-0
355 additions, 0 deletions
ExperimentsScaleState.java
with
355 additions
and
0 deletions
ExperimentsScaleState.java
0 → 100644
+
355
−
0
View file @
b944be90
import
de.learnlib.acex.AcexAnalyzer
;
import
de.learnlib.algorithm.kv.dfa.KearnsVaziraniDFA
;
import
de.learnlib.algorithm.kv.dfa.KearnsVaziraniDFABuilder
;
import
de.learnlib.algorithm.lstar.dfa.ClassicLStarDFABuilder
;
import
de.learnlib.algorithm.observationpack.dfa.OPLearnerDFA
;
import
de.learnlib.algorithm.observationpack.dfa.OPLearnerDFABuilder
;
import
de.learnlib.algorithm.rivestschapire.RivestSchapireDFA
;
import
de.learnlib.algorithm.ttt.base.AbstractTTTLearner
;
import
de.learnlib.algorithm.ttt.dfa.TTTLearnerDFA
;
import
de.learnlib.algorithm.ttt.dfa.TTTLearnerDFABuilder
;
import
de.learnlib.filter.statistic.oracle.DFACounterOracle
;
import
de.learnlib.oracle.EquivalenceOracle
;
import
de.learnlib.oracle.MembershipOracle
;
import
de.learnlib.oracle.equivalence.DFASimulatorEQOracle
;
import
de.learnlib.oracle.equivalence.WMethodEQOracle
;
import
de.learnlib.oracle.membership.DFASimulatorOracle
;
import
de.learnlib.query.DefaultQuery
;
import
net.automatalib.alphabet.Alphabet
;
import
net.automatalib.alphabet.Alphabets
;
import
net.automatalib.automaton.fsa.DFA
;
import
de.learnlib.algorithm.lstar.dfa.ClassicLStarDFA
;
import
de.learnlib.algorithm.rivestschapire.RivestSchapireDFABuilder
;
import
net.automatalib.word.Word
;
import
org.knowm.xchart.QuickChart
;
import
org.knowm.xchart.SwingWrapper
;
import
org.knowm.xchart.XYChart
;
import
org.knowm.xchart.XYSeries
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Random
;
import
java.util.stream.Collectors
;
public
class
ExperimentsScaleState
{
public
static
void
main
(
String
[]
args
)
{
// Define configurations
double
[]
yValues
=
{
0.5
};
int
[]
zValues
=
{
5
};
int
[]
xValues
=
{
10
,
20
,
30
,
40
,
50
,
60
,
70
,
80
,
90
,
100
};
// Declare arrays to store the average membership queries and average equivalence queries
double
[]
avgMemQueriesLstar
=
new
double
[
xValues
.
length
];
double
[]
avgMemQueriesRS
=
new
double
[
xValues
.
length
];
double
[]
avgMemQueriesKV
=
new
double
[
xValues
.
length
];
double
[]
avgMemQueriesOP
=
new
double
[
xValues
.
length
];
double
[]
avgMemQueriesTTT
=
new
double
[
xValues
.
length
];
double
[]
avgEqQueriesLstar
=
new
double
[
xValues
.
length
];
double
[]
avgEqQueriesRS
=
new
double
[
xValues
.
length
];
double
[]
avgEqQueriesKV
=
new
double
[
xValues
.
length
];
double
[]
avgEqQueriesOP
=
new
double
[
xValues
.
length
];
double
[]
avgEqQueriesTTT
=
new
double
[
xValues
.
length
];
// Iterate over each configuration: y denotes the size of the alphabet of the target DFA, z denotes the size of the target DFA, x denotes the acceptance ratio of the target DFA
for
(
double
y:
yValues
)
{
for
(
int
z
:
zValues
)
{
int
k
=
0
;
for
(
int
x
:
xValues
)
{
// Create the alphabet
Alphabet
<
Integer
>
alphabet
=
Alphabets
.
integers
(
0
,
z
-
1
);
int
memCounterLstar
=
0
;
int
memCounterRS
=
0
;
int
memCounterKV
=
0
;
int
memCounterOP
=
0
;
int
memCounterTTT
=
0
;
int
eqCounterLstar
=
0
;
int
eqCounterRS
=
0
;
int
eqCounterKV
=
0
;
int
eqCounterOP
=
0
;
int
eqCounterTTT
=
0
;
// Generate 100 random DFAs for each configuration
for
(
int
i
=
0
;
i
<
20
;
i
++)
{
System
.
out
.
println
(
"Generating random DFA "
+
i
+
" for configuration (x,y,z):"
+
z
+
","
+
y
+
","
+
x
);
Random
rand
=
new
Random
();
ExampleRandomDFA
example
=
new
ExampleRandomDFA
(
rand
,
z
,
x
,
y
,
alphabet
);
DFA
<?,
Integer
>
dfa
=
example
.
getReferenceAutomaton
();
// Initialize the Query Counters and the Oracles - we used the white-box oracles
EquivalenceOracle
<
DFA
<?,
Integer
>,
Integer
,
Boolean
>
eqOracleLstar
=
new
DFASimulatorEQOracle
<>(
dfa
);
EQCounterOracle
<
DFA
<?,
Integer
>,
Integer
,
Boolean
>
eqCounterOracleLstar
=
new
EQCounterOracle
<>(
eqOracleLstar
);
MembershipOracle
.
DFAMembershipOracle
<
Integer
>
memOracleLstar
=
new
DFASimulatorOracle
<>(
dfa
);
DFACounterOracle
<
Integer
>
memCounterOracleLstar
=
new
DFACounterOracle
<>(
memOracleLstar
);
EquivalenceOracle
<
DFA
<?,
Integer
>,
Integer
,
Boolean
>
eqOracleRS
=
new
DFASimulatorEQOracle
<>(
dfa
);
EQCounterOracle
<
DFA
<?,
Integer
>,
Integer
,
Boolean
>
eqCounterOracleRS
=
new
EQCounterOracle
<>(
eqOracleRS
);
MembershipOracle
.
DFAMembershipOracle
<
Integer
>
memOracleRS
=
new
DFASimulatorOracle
<>(
dfa
);
DFACounterOracle
<
Integer
>
memCounterOracleRS
=
new
DFACounterOracle
<>(
memOracleRS
);
EquivalenceOracle
<
DFA
<?,
Integer
>,
Integer
,
Boolean
>
eqOracleKV
=
new
DFASimulatorEQOracle
<>(
dfa
);
EQCounterOracle
<
DFA
<?,
Integer
>,
Integer
,
Boolean
>
eqCounterOracleKV
=
new
EQCounterOracle
<>(
eqOracleKV
);
MembershipOracle
.
DFAMembershipOracle
<
Integer
>
memOracleKV
=
new
DFASimulatorOracle
<>(
dfa
);
DFACounterOracle
<
Integer
>
memCounterOracleKV
=
new
DFACounterOracle
<>(
memOracleKV
);
EquivalenceOracle
<
DFA
<?,
Integer
>,
Integer
,
Boolean
>
eqOracleOP
=
new
DFASimulatorEQOracle
<>(
dfa
);
EQCounterOracle
<
DFA
<?,
Integer
>,
Integer
,
Boolean
>
eqCounterOracleOP
=
new
EQCounterOracle
<>(
eqOracleOP
);
MembershipOracle
.
DFAMembershipOracle
<
Integer
>
memOracleOP
=
new
DFASimulatorOracle
<>(
dfa
);
DFACounterOracle
<
Integer
>
memCounterOracleOP
=
new
DFACounterOracle
<>(
memOracleOP
);
EquivalenceOracle
<
DFA
<?,
Integer
>,
Integer
,
Boolean
>
eqOracleTTT
=
new
DFASimulatorEQOracle
<>(
dfa
);
EQCounterOracle
<
DFA
<?,
Integer
>,
Integer
,
Boolean
>
eqCounterOracleTTT
=
new
EQCounterOracle
<>(
eqOracleTTT
);
MembershipOracle
.
DFAMembershipOracle
<
Integer
>
memOracleTTT
=
new
DFASimulatorOracle
<>(
dfa
);
DFACounterOracle
<
Integer
>
memCounterOracleTTT
=
new
DFACounterOracle
<>(
memOracleTTT
);
// Learn the DFA using each learning algorithm
learnWithClassicLStarDFA
(
dfa
,
alphabet
,
eqCounterOracleLstar
,
memCounterOracleLstar
);
learnWithRivestShapireDFA
(
dfa
,
alphabet
,
eqCounterOracleRS
,
memCounterOracleRS
);
learnWithKearnsVauiraniDFA
(
dfa
,
alphabet
,
eqCounterOracleKV
,
memCounterOracleKV
);
learnWithOPLearnerDFA
(
dfa
,
alphabet
,
eqCounterOracleOP
,
memCounterOracleOP
);
learnWithTTTLearnerDFA
(
dfa
,
alphabet
,
eqCounterOracleTTT
,
memCounterOracleTTT
);
// Update the counters
memCounterLstar
+=
memCounterOracleLstar
.
getQueryCounter
().
getCount
();
memCounterRS
+=
memCounterOracleRS
.
getQueryCounter
().
getCount
();
memCounterKV
+=
memCounterOracleKV
.
getQueryCounter
().
getCount
();
memCounterOP
+=
memCounterOracleOP
.
getQueryCounter
().
getCount
();
memCounterTTT
+=
memCounterOracleTTT
.
getQueryCounter
().
getCount
();
eqCounterLstar
+=
eqCounterOracleLstar
.
getCounter
();
eqCounterRS
+=
eqCounterOracleRS
.
getCounter
();
eqCounterKV
+=
eqCounterOracleKV
.
getCounter
();
eqCounterOP
+=
eqCounterOracleOP
.
getCounter
();
eqCounterTTT
+=
eqCounterOracleTTT
.
getCounter
();
}
//Calculate average for configuration (x,y,z) for the counters
System
.
out
.
println
(
"For configuration (x,y,z):"
+
z
+
","
+
y
+
","
+
x
+
" :"
);
System
.
out
.
println
(
"Average memCounterLstar: "
+
memCounterLstar
/
20
);
System
.
out
.
println
(
"Average memCounterRS: "
+
memCounterRS
/
20
);
System
.
out
.
println
(
"Average memCounterKV: "
+
memCounterKV
/
20
);
System
.
out
.
println
(
"Average memCounterOP: "
+
memCounterOP
/
20
);
System
.
out
.
println
(
"Average memCounterTTT: "
+
memCounterTTT
/
20
);
System
.
out
.
println
(
"Average eqCounterLstar: "
+
eqCounterLstar
/
20
);
System
.
out
.
println
(
"Average eqCounterRS: "
+
eqCounterRS
/
20
);
System
.
out
.
println
(
"Average eqCounterKV: "
+
eqCounterKV
/
20
);
System
.
out
.
println
(
"Average eqCounterOP: "
+
eqCounterOP
/
20
);
System
.
out
.
println
(
"Average eqCounterTTT: "
+
eqCounterTTT
/
20
);
// Calculate the averages and store them in the arrays
avgMemQueriesLstar
[
k
]
=
memCounterLstar
/
20.0
;
avgMemQueriesRS
[
k
]
=
memCounterRS
/
20.0
;
avgMemQueriesKV
[
k
]
=
memCounterKV
/
20.0
;
avgMemQueriesOP
[
k
]
=
memCounterOP
/
20.0
;
avgMemQueriesTTT
[
k
]
=
memCounterTTT
/
20.0
;
avgEqQueriesLstar
[
k
]
=
eqCounterLstar
/
20.0
;
avgEqQueriesRS
[
k
]
=
eqCounterRS
/
20.0
;
avgEqQueriesKV
[
k
]
=
eqCounterKV
/
20.0
;
avgEqQueriesOP
[
k
]
=
eqCounterOP
/
20.0
;
avgEqQueriesTTT
[
k
]
=
eqCounterTTT
/
20.0
;
k
++;
}
double
[]
xValuesDouble
=
new
double
[
xValues
.
length
];
for
(
int
i
=
0
;
i
<
xValues
.
length
;
i
++)
{
xValuesDouble
[
i
]
=
(
double
)
xValues
[
i
];
}
// Calculate upper bound values
double
[]
upperboundmqRSValues
=
new
double
[
xValues
.
length
];
double
[]
upperboundmqKVValues
=
new
double
[
xValues
.
length
];
double
[]
upperboundmqLStarValues
=
new
double
[
xValues
.
length
];
double
[]
upperboundeqValues
=
new
double
[
xValues
.
length
];
for
(
int
i
=
0
;
i
<
xValues
.
length
;
i
++)
{
int
j
=
5
;
int
n
=
xValues
[
i
];
upperboundmqRSValues
[
i
]
=
upperboundmqRS
(
n
,
j
);
upperboundmqKVValues
[
i
]
=
upperboundmqKV
(
n
,
j
);
upperboundmqLStarValues
[
i
]
=
upperboundmqLStar
(
n
,
j
);
upperboundeqValues
[
i
]
=
upperboundeq
(
n
);
}
// Extend series names
String
[]
extendedSeriesNames1
=
{
"LStar"
,
"RS"
,
"KV"
,
"OP"
,
"TTT"
,
"upperboundRS"
,
"upperboundKV"
,
"upperboundLStar"
};
String
[]
extendedSeriesNames2
=
{
"LStar"
,
"RS"
,
"KV"
,
"OP"
,
"TTT"
,
"upperboundEQ"
};
// Create the first XY chart (membership queries) with extended series
XYChart
chart1
=
QuickChart
.
getChart
(
"Average Membership Queries, k=5, Acceptence Ratio = 0.5"
,
"States"
,
"Queries"
,
extendedSeriesNames1
,
xValuesDouble
,
new
double
[][]{
avgMemQueriesLstar
,
avgMemQueriesRS
,
avgMemQueriesKV
,
avgMemQueriesOP
,
avgMemQueriesTTT
,
upperboundmqRSValues
,
upperboundmqKVValues
,
upperboundmqLStarValues
});
new
SwingWrapper
(
chart1
).
displayChart
();
// Exclude upperboundmqLStar from series names
String
[]
extendedSeriesNamesExcludingLS
=
{
"LStar"
,
"RS"
,
"KV"
,
"OP"
,
"TTT"
,
"upperboundRS"
,
"upperboundKV"
};
// Exclude upperboundmqLStar from series data
XYChart
chartExcludingLS
=
QuickChart
.
getChart
(
"Average Membership Queries, k=5, Acceptence Ratio = 0.5"
,
"States"
,
"Queries"
,
extendedSeriesNamesExcludingLS
,
xValuesDouble
,
new
double
[][]{
avgMemQueriesLstar
,
avgMemQueriesRS
,
avgMemQueriesKV
,
avgMemQueriesOP
,
avgMemQueriesTTT
,
upperboundmqRSValues
,
upperboundmqKVValues
});
new
SwingWrapper
(
chartExcludingLS
).
displayChart
();
// Exclude upper bounds from series names
String
[]
seriesNamesNoUpperBounds
=
{
"LStar"
,
"RS"
,
"KV"
,
"OP"
,
"TTT"
};
// Create the XY chart (membership queries) without upper bounds
XYChart
chartNoUpperBounds
=
QuickChart
.
getChart
(
"Average Membership Queries, k=5, Acceptence Ratio = 0.5"
,
"States"
,
"Queries"
,
seriesNamesNoUpperBounds
,
xValuesDouble
,
new
double
[][]{
avgMemQueriesLstar
,
avgMemQueriesRS
,
avgMemQueriesKV
,
avgMemQueriesOP
,
avgMemQueriesTTT
});
new
SwingWrapper
(
chartNoUpperBounds
).
displayChart
();
// Create the XY chart (equivalence queries) without upper bounds
XYChart
chart2NoUpperBounds
=
QuickChart
.
getChart
(
"Average Equivalence Queries, k=5, Acceptence Ratio = 0.5"
,
"States"
,
"Queries"
,
seriesNamesNoUpperBounds
,
xValuesDouble
,
new
double
[][]{
avgEqQueriesLstar
,
avgEqQueriesRS
,
avgEqQueriesKV
,
avgEqQueriesOP
,
avgEqQueriesTTT
});
new
SwingWrapper
(
chart2NoUpperBounds
).
displayChart
();
// Create the second XY chart (equivalence queries) with extended series
XYChart
chart2
=
QuickChart
.
getChart
(
"Average Equivalence Queries, k=5, Acceptence Ratio = 0.5"
,
"States"
,
"Queries"
,
extendedSeriesNames2
,
xValuesDouble
,
new
double
[][]{
avgEqQueriesLstar
,
avgEqQueriesRS
,
avgEqQueriesKV
,
avgEqQueriesOP
,
avgEqQueriesTTT
,
upperboundeqValues
});
new
SwingWrapper
(
chart2
).
displayChart
();
printXYChartPairs
(
chart1
);
printXYChartPairs
(
chart2
);
printXYChartPairs
(
chartExcludingLS
);
printXYChartPairs
(
chartNoUpperBounds
);
printXYChartPairs
(
chart2NoUpperBounds
);
}
}
}
// Define the learning methods
public
static
void
learnWithClassicLStarDFA
(
DFA
<?,
Integer
>
dfa
,
Alphabet
<
Integer
>
alphabet
,
EquivalenceOracle
<
DFA
<?,
Integer
>,
Integer
,
Boolean
>
eqOracleLstar
,
MembershipOracle
.
DFAMembershipOracle
<
Integer
>
memOracleLstar
)
{
// Create an instance of the ClassicLStar algorithm
ClassicLStarDFA
<
Integer
>
learner
=
new
ClassicLStarDFABuilder
<
Integer
>().
withAlphabet
(
alphabet
)
// input alphabet
.
withOracle
(
memOracleLstar
)
// membership oracle
.
create
();
// Start the learning process
learner
.
startLearning
();
// Perform equivalence queries until no counterexample is found
DefaultQuery
<
Integer
,
Boolean
>
counterexample
;
while
((
counterexample
=
eqOracleLstar
.
findCounterExample
(
learner
.
getHypothesisModel
(),
alphabet
))
!=
null
)
{
learner
.
refineHypothesis
(
counterexample
);
}
}
public
static
void
learnWithRivestShapireDFA
(
DFA
<?,
Integer
>
dfa
,
Alphabet
<
Integer
>
alphabet
,
EquivalenceOracle
<
DFA
<?,
Integer
>,
Integer
,
Boolean
>
eqOracleRS
,
MembershipOracle
.
DFAMembershipOracle
<
Integer
>
memOracleRS
)
{
// Implement learning with RivestShapireDFA
RivestSchapireDFABuilder
<
Integer
>
rsBuilder
=
new
RivestSchapireDFABuilder
<>();
rsBuilder
.
withAlphabet
(
alphabet
);
// input alphabet
rsBuilder
.
withOracle
(
memOracleRS
);
// membership oracle
RivestSchapireDFA
<
Integer
>
learner
=
rsBuilder
.
create
();
learner
.
startLearning
();
DefaultQuery
<
Integer
,
Boolean
>
counterexample
;
while
((
counterexample
=
eqOracleRS
.
findCounterExample
(
learner
.
getHypothesisModel
(),
alphabet
))
!=
null
)
{
learner
.
refineHypothesis
(
counterexample
);
}
}
public
static
void
learnWithKearnsVauiraniDFA
(
DFA
<?,
Integer
>
dfa
,
Alphabet
<
Integer
>
alphabet
,
EquivalenceOracle
<
DFA
<?,
Integer
>,
Integer
,
Boolean
>
eqOracleKV
,
MembershipOracle
.
DFAMembershipOracle
<
Integer
>
memOracleKV
)
{
KearnsVaziraniDFABuilder
<
Integer
>
kol
=
new
KearnsVaziraniDFABuilder
<
Integer
>();
kol
.
withAlphabet
(
alphabet
);
kol
.
withOracle
(
memOracleKV
);
kol
.
withRepeatedCounterexampleEvaluation
(
true
);
KearnsVaziraniDFA
<
Integer
>
learner
=
kol
.
create
();
learner
.
startLearning
();
DefaultQuery
<
Integer
,
Boolean
>
counterexample
;
while
((
counterexample
=
eqOracleKV
.
findCounterExample
(
learner
.
getHypothesisModel
(),
alphabet
))
!=
null
)
{
learner
.
refineHypothesis
(
counterexample
);
}
}
public
static
void
learnWithOPLearnerDFA
(
DFA
<?,
Integer
>
dfa
,
Alphabet
<
Integer
>
alphabet
,
EquivalenceOracle
<
DFA
<?,
Integer
>,
Integer
,
Boolean
>
eqOracleOP
,
MembershipOracle
.
DFAMembershipOracle
<
Integer
>
memOracleOP
)
{
OPLearnerDFABuilder
<
Integer
>
opBuilder
=
new
OPLearnerDFABuilder
<>();
opBuilder
.
withAlphabet
(
alphabet
);
opBuilder
.
withOracle
(
memOracleOP
);
opBuilder
.
setRepeatedCounterexampleEvaluation
(
true
);
OPLearnerDFA
<
Integer
>
learner
=
opBuilder
.
create
();
// Perform equivalence queries until no counterexample is found
DefaultQuery
<
Integer
,
Boolean
>
counterexample
;
learner
.
startLearning
();
while
((
counterexample
=
eqOracleOP
.
findCounterExample
(
learner
.
getHypothesisModel
(),
alphabet
))
!=
null
)
{
learner
.
refineHypothesis
(
counterexample
);
}
}
public
static
void
learnWithTTTLearnerDFA
(
DFA
<?,
Integer
>
dfa
,
Alphabet
<
Integer
>
alphabet
,
EquivalenceOracle
<
DFA
<?,
Integer
>,
Integer
,
Boolean
>
oracle
,
MembershipOracle
.
DFAMembershipOracle
<
Integer
>
mem
)
{
TTTLearnerDFA
<
Integer
>
learner
=
new
TTTLearnerDFABuilder
<
Integer
>().
withAlphabet
(
alphabet
)
.
withOracle
(
mem
)
.
create
();
learner
.
startLearning
();
// Perform equivalence queries until no counterexample is found
DefaultQuery
counterexample
;
while
((
counterexample
=
oracle
.
findCounterExample
(
learner
.
getHypothesisModel
(),
alphabet
))
!=
null
)
{
learner
.
refineHypothesis
(
counterexample
);
}
}
public
static
int
upperboundmqRS
(
int
n
,
int
k
)
{
return
k
*
n
*
n
+
n
*
(
int
)
Math
.
log
(
n
);
}
public
static
int
upperboundmqKV
(
int
n
,
int
k
)
{
return
k
*
n
*
n
+
(
n
*
n
)
*
(
int
)
Math
.
log
(
n
);
}
public
static
int
upperboundmqLStar
(
int
n
,
int
k
)
{
if
(
n
>
700
){
n
=
700
;}
//to avoid overflow
return
k
*
n
*
n
*
n
;
}
public
static
int
upperboundeq
(
int
n
)
{
return
n
;
}
public
static
void
printXYChartPairs
(
XYChart
chart
)
{
// Get all series in the chart
System
.
out
.
println
(
"Chart: "
+
chart
.
getTitle
());
List
<
XYSeries
>
seriesList
=
chart
.
getSeriesMap
().
values
().
stream
().
collect
(
Collectors
.
toList
());
// Iterate over each series
for
(
XYSeries
series
:
seriesList
)
{
System
.
out
.
println
(
"Series: "
+
series
.
getName
());
// Get x and y data
double
[]
xData
=
series
.
getXData
();
double
[]
yData
=
series
.
getYData
();
// Ensure x and y data are of the same size
if
(
xData
.
length
!=
yData
.
length
)
{
System
.
out
.
println
(
"Mismatch in data size for series: "
+
series
.
getName
());
continue
;
}
// Print (x, y) pairs
for
(
int
i
=
0
;
i
<
xData
.
length
;
i
++)
{
System
.
out
.
println
(
"("
+
xData
[
i
]
+
", "
+
yData
[
i
]
+
")"
);
}
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment