Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
289a8da3
Commit
289a8da3
authored
Dec 22, 2017
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ml: simplify interfaces of SimulatedAnnealingSolver
parent
09c84a01
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
99 additions
and
208 deletions
+99
-208
ml.hpp
modules/ml/include/opencv2/ml.hpp
+26
-52
ml.inl.hpp
modules/ml/include/opencv2/ml/ml.inl.hpp
+60
-0
ann_mlp.cpp
modules/ml/src/ann_mlp.cpp
+4
-140
travelsalesman.cpp
samples/cpp/travelsalesman.cpp
+9
-16
No files found.
modules/ml/include/opencv2/ml.hpp
View file @
289a8da3
...
...
@@ -1912,75 +1912,49 @@ public:
* Simulated annealing solver *
\****************************************************************************************/
/** @brief The class defines interface for system state used in simulated annealing optimization algorithm.
#ifdef CV_DOXYGEN
/** @brief This class declares example interface for system state used in simulated annealing optimization algorithm.
@
cite Kirkpatrick83 for details
@
note This class is not defined in C++ code and can't be use directly - you need your own implementation with the same methods.
*/
class
CV_EXPORTS
SimulatedAnnealingSolverSystem
struct
SimulatedAnnealingSolverSystem
{
protected
:
inline
SimulatedAnnealingSolverSystem
()
{}
public
:
virtual
~
SimulatedAnnealingSolverSystem
()
{}
/** Give energy value for a state of system.*/
virtual
double
energy
()
const
=
0
;
double
energy
()
const
;
/** Function which change the state of system (random pertubation).*/
v
irtual
void
changeState
()
=
0
;
v
oid
changeState
()
;
/** Function to reverse to the previous state. Can be called once only after changeState(). */
v
irtual
void
reverseState
()
=
0
;
v
oid
reverseState
()
;
};
#endif // CV_DOXYGEN
/** @brief The class implements simulated annealing for optimization.
*
@cite Kirkpatrick83 for details
*/
class
CV_EXPORTS
SimulatedAnnealingSolver
:
public
Algorithm
{
public
:
SimulatedAnnealingSolver
(
const
Ptr
<
SimulatedAnnealingSolverSystem
>&
system
);
inline
~
SimulatedAnnealingSolver
()
{
release
();
}
/** Simulated annealing procedure. */
int
run
();
/** Set/initialize RNG (energy).
@param rng new RNG
*/
void
setEnergyRNG
(
const
RNG
&
rng
);
/** Set initial temperature of simulated annealing procedure.
@param x new initial temperature. x\>0
*/
void
setInitialTemperature
(
double
x
);
/** Set final temperature of simulated annealing procedure.
@param x new final temperature value. 0\<x\<initial temperature
*/
void
setFinalTemperature
(
double
x
);
/** Get final temperature of simulated annealing procedure. */
double
getFinalTemperature
();
/** Set setCoolingRatio of simulated annealing procedure : T(t) = coolingRatio * T(t-1).
@param x new cooling ratio value. 0\<x\<1
*/
void
setCoolingRatio
(
double
x
);
/** Set number iteration per temperature step.
@param ite number of iteration per temperature step ite \> 0
*/
void
setIterPerStep
(
int
ite
);
void
release
();
SimulatedAnnealingSolver
(
const
SimulatedAnnealingSolver
&
);
SimulatedAnnealingSolver
&
operator
=
(
const
SimulatedAnnealingSolver
&
);
struct
Impl
;
friend
struct
Impl
;
protected
:
Impl
*
impl
;
};
@cite Kirkpatrick83 for details
@param solverSystem optimization system (see SimulatedAnnealingSolverSystem)
@param initialTemperature initial temperature
@param finalTemperature final temperature
@param coolingRatio temperature step multiplies
@param iterationsPerStep number of iterations per temperature changing step
@param lastTemperature optional output for last used temperature
@param rngEnergy specify custom random numbers generator (cv::theRNG() by default)
*/
template
<
class
SimulatedAnnealingSolverSystem
>
int
simulatedAnnealingSolver
(
SimulatedAnnealingSolverSystem
&
solverSystem
,
double
initialTemperature
,
double
finalTemperature
,
double
coolingRatio
,
size_t
iterationsPerStep
,
CV_OUT
double
*
lastTemperature
=
NULL
,
cv
::
RNG
&
rngEnergy
=
cv
::
theRNG
()
);
//! @} ml
}
}
#include <opencv2/ml/ml.inl.hpp>
#endif // __cplusplus
#endif // OPENCV_ML_HPP
...
...
modules/ml/include/opencv2/ml/ml.inl.hpp
0 → 100644
View file @
289a8da3
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_ML_INL_HPP
#define OPENCV_ML_INL_HPP
namespace
cv
{
namespace
ml
{
// declared in ml.hpp
template
<
class
SimulatedAnnealingSolverSystem
>
int
simulatedAnnealingSolver
(
SimulatedAnnealingSolverSystem
&
solverSystem
,
double
initialTemperature
,
double
finalTemperature
,
double
coolingRatio
,
size_t
iterationsPerStep
,
CV_OUT
double
*
lastTemperature
,
cv
::
RNG
&
rngEnergy
)
{
CV_Assert
(
finalTemperature
>
0
);
CV_Assert
(
initialTemperature
>
finalTemperature
);
CV_Assert
(
iterationsPerStep
>
0
);
CV_Assert
(
coolingRatio
<
1.0
f
);
double
Ti
=
initialTemperature
;
double
previousEnergy
=
solverSystem
.
energy
();
int
exchange
=
0
;
while
(
Ti
>
finalTemperature
)
{
for
(
size_t
i
=
0
;
i
<
iterationsPerStep
;
i
++
)
{
solverSystem
.
changeState
();
double
newEnergy
=
solverSystem
.
energy
();
if
(
newEnergy
<
previousEnergy
)
{
previousEnergy
=
newEnergy
;
exchange
++
;
}
else
{
double
r
=
rngEnergy
.
uniform
(
0.0
,
1.0
);
if
(
r
<
std
::
exp
(
-
(
newEnergy
-
previousEnergy
)
/
Ti
))
{
previousEnergy
=
newEnergy
;
exchange
++
;
}
else
{
solverSystem
.
reverseState
();
}
}
}
Ti
*=
coolingRatio
;
}
if
(
lastTemperature
)
*
lastTemperature
=
Ti
;
return
exchange
;
}
}}
//namespace
#endif // OPENCV_ML_INL_HPP
modules/ml/src/ann_mlp.cpp
View file @
289a8da3
...
...
@@ -42,41 +42,6 @@
namespace
cv
{
namespace
ml
{
struct
SimulatedAnnealingSolver
::
Impl
{
int
refcount
;
const
Ptr
<
SimulatedAnnealingSolverSystem
>
systemPtr
;
SimulatedAnnealingSolverSystem
&
system
;
RNG
rEnergy
;
double
coolingRatio
;
double
initialT
;
double
finalT
;
int
iterPerStep
;
Impl
(
const
Ptr
<
SimulatedAnnealingSolverSystem
>&
s
)
:
refcount
(
1
),
systemPtr
(
s
),
system
(
*
(
s
.
get
())),
rEnergy
(
12345
)
{
CV_Assert
(
!
systemPtr
.
empty
());
initialT
=
2
;
finalT
=
0.1
;
coolingRatio
=
0.95
;
iterPerStep
=
100
;
}
inline
double
energy
()
{
return
system
.
energy
();
}
inline
void
changeState
()
{
system
.
changeState
();
}
inline
void
reverseState
()
{
system
.
reverseState
();
}
void
addref
()
{
CV_XADD
(
&
refcount
,
1
);
}
void
release
()
{
if
(
CV_XADD
(
&
refcount
,
-
1
)
==
1
)
delete
this
;
}
protected
:
virtual
~
Impl
()
{
CV_Assert
(
refcount
==
0
);
}
};
struct
AnnParams
{
AnnParams
()
...
...
@@ -115,103 +80,7 @@ inline T inBounds(T val, T min_val, T max_val)
return
std
::
min
(
std
::
max
(
val
,
min_val
),
max_val
);
}
SimulatedAnnealingSolver
::
SimulatedAnnealingSolver
(
const
Ptr
<
SimulatedAnnealingSolverSystem
>&
system
)
{
impl
=
new
Impl
(
system
);
}
SimulatedAnnealingSolver
::
SimulatedAnnealingSolver
(
const
SimulatedAnnealingSolver
&
b
)
{
if
(
b
.
impl
)
b
.
impl
->
addref
();
release
();
impl
=
b
.
impl
;
}
void
SimulatedAnnealingSolver
::
release
()
{
if
(
impl
)
{
impl
->
release
();
impl
=
NULL
;
}
}
void
SimulatedAnnealingSolver
::
setIterPerStep
(
int
ite
)
{
CV_Assert
(
impl
);
CV_Assert
(
ite
>
0
);
impl
->
iterPerStep
=
ite
;
}
int
SimulatedAnnealingSolver
::
run
()
{
CV_Assert
(
impl
);
CV_Assert
(
impl
->
initialT
>
impl
->
finalT
);
double
Ti
=
impl
->
initialT
;
double
previousEnergy
=
impl
->
energy
();
int
exchange
=
0
;
while
(
Ti
>
impl
->
finalT
)
{
for
(
int
i
=
0
;
i
<
impl
->
iterPerStep
;
i
++
)
{
impl
->
changeState
();
double
newEnergy
=
impl
->
energy
();
if
(
newEnergy
<
previousEnergy
)
{
previousEnergy
=
newEnergy
;
exchange
++
;
}
else
{
double
r
=
impl
->
rEnergy
.
uniform
(
0.0
,
1.0
);
if
(
r
<
std
::
exp
(
-
(
newEnergy
-
previousEnergy
)
/
Ti
))
{
previousEnergy
=
newEnergy
;
exchange
++
;
}
else
{
impl
->
reverseState
();
}
}
}
Ti
*=
impl
->
coolingRatio
;
}
impl
->
finalT
=
Ti
;
return
exchange
;
}
void
SimulatedAnnealingSolver
::
setEnergyRNG
(
const
RNG
&
rng
)
{
CV_Assert
(
impl
);
impl
->
rEnergy
=
rng
;
}
void
SimulatedAnnealingSolver
::
setInitialTemperature
(
double
x
)
{
CV_Assert
(
impl
);
CV_Assert
(
x
>
0
);
impl
->
initialT
=
x
;
}
void
SimulatedAnnealingSolver
::
setFinalTemperature
(
double
x
)
{
CV_Assert
(
impl
);
CV_Assert
(
x
>
0
);
impl
->
finalT
=
x
;
}
double
SimulatedAnnealingSolver
::
getFinalTemperature
()
{
CV_Assert
(
impl
);
return
impl
->
finalT
;
}
void
SimulatedAnnealingSolver
::
setCoolingRatio
(
double
x
)
{
CV_Assert
(
impl
);
CV_Assert
(
x
>
0
&&
x
<
1
);
impl
->
coolingRatio
=
x
;
}
class
SimulatedAnnealingANN_MLP
:
public
SimulatedAnnealingSolverSystem
class
SimulatedAnnealingANN_MLP
{
protected
:
ml
::
ANN_MLP
&
nn
;
...
...
@@ -228,7 +97,7 @@ public:
initVarMap
();
}
~
SimulatedAnnealingANN_MLP
()
{}
protected
:
void
changeState
()
{
index
=
rIndex
.
uniform
(
0
,
nbVariables
);
...
...
@@ -1075,14 +944,9 @@ public:
}
int
train_anneal
(
const
Ptr
<
TrainData
>&
trainData
)
{
SimulatedAnnealingSolver
t
(
Ptr
<
SimulatedAnnealingANN_MLP
>
(
new
SimulatedAnnealingANN_MLP
(
*
this
,
trainData
)));
t
.
setEnergyRNG
(
params
.
rEnergy
);
t
.
setFinalTemperature
(
params
.
finalT
);
t
.
setInitialTemperature
(
params
.
initialT
);
t
.
setCoolingRatio
(
params
.
coolingRatio
);
t
.
setIterPerStep
(
params
.
itePerStep
);
SimulatedAnnealingANN_MLP
s
(
*
this
,
trainData
);
trained
=
true
;
// Enable call to CalcError
int
iter
=
t
.
run
(
);
int
iter
=
simulatedAnnealingSolver
(
s
,
params
.
initialT
,
params
.
finalT
,
params
.
coolingRatio
,
params
.
itePerStep
,
NULL
,
params
.
rEnergy
);
trained
=
false
;
return
iter
;
}
...
...
samples/cpp/travelsalesman.cpp
View file @
289a8da3
...
...
@@ -2,7 +2,7 @@
using
namespace
cv
;
class
TravelSalesman
:
public
ml
::
SimulatedAnnealingSolverSystem
class
TravelSalesman
{
private
:
const
std
::
vector
<
Point
>&
posCity
;
...
...
@@ -17,11 +17,11 @@ public:
rng
=
theRNG
();
}
/** Give energy value for a state of system.*/
/*virtual*/
double
energy
()
const
;
double
energy
()
const
;
/** Function which change the state of system (random pertubation).*/
/*virtual*/
void
changeState
();
void
changeState
();
/** Function to reverse to the previous state.*/
/*virtual*/
void
reverseState
();
void
reverseState
();
};
...
...
@@ -81,31 +81,24 @@ int main(void)
posCity
[
i
].
y
=
static_cast
<
int
>
(
radius
*
sin
(
theta
))
+
center
.
y
;
next
[
i
]
=
(
i
+
1
)
%
nbCity
;
}
Ptr
<
TravelSalesman
>
ts_system
(
new
TravelSalesman
(
posCity
,
next
));
ml
::
SimulatedAnnealingSolver
ts
(
ts_system
);
TravelSalesman
ts_system
(
posCity
,
next
);
ts
.
setIterPerStep
(
10000
*
nbCity
);
ts
.
setCoolingRatio
(
0.99
);
ts
.
setInitialTemperature
(
100
);
ts
.
setFinalTemperature
(
100
*
0.97
);
DrawTravelMap
(
img
,
posCity
,
next
);
imshow
(
"Map"
,
img
);
waitKey
(
10
);
double
currentTemperature
=
100.0
;
for
(
int
i
=
0
,
zeroChanges
=
0
;
zeroChanges
<
10
;
i
++
)
{
int
changesApplied
=
ts
.
run
(
);
img
=
Mat
::
zeros
(
img
.
size
(),
CV_8UC3
);
int
changesApplied
=
ml
::
simulatedAnnealingSolver
(
ts_system
,
currentTemperature
,
currentTemperature
*
0.97
,
0.99
,
10000
*
nbCity
,
&
currentTemperature
,
rng
);
img
.
setTo
(
Scalar
::
all
(
0
)
);
DrawTravelMap
(
img
,
posCity
,
next
);
imshow
(
"Map"
,
img
);
int
k
=
waitKey
(
10
);
double
ti
=
ts
.
getFinalTemperature
();
std
::
cout
<<
"i="
<<
i
<<
" changesApplied="
<<
changesApplied
<<
" temp="
<<
ti
<<
" result="
<<
ts_system
->
energy
()
<<
std
::
endl
;
std
::
cout
<<
"i="
<<
i
<<
" changesApplied="
<<
changesApplied
<<
" temp="
<<
currentTemperature
<<
" result="
<<
ts_system
.
energy
()
<<
std
::
endl
;
if
(
k
==
27
||
k
==
'q'
||
k
==
'Q'
)
return
0
;
if
(
changesApplied
==
0
)
zeroChanges
++
;
ts
.
setInitialTemperature
(
ti
);
ts
.
setFinalTemperature
(
ti
*
0.97
);
}
std
::
cout
<<
"Done"
<<
std
::
endl
;
waitKey
(
0
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment