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
70e1b4dd
Unverified
Commit
70e1b4dd
authored
Dec 15, 2017
by
Alexander Alekhin
Committed by
GitHub
Dec 15, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #10319 from catree:move_SimulatedAnnealingSolver_Impl_cpp
Move SimulatedAnnealingSolver::Impl in cpp file
parents
bab86d65
aef30191
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
198 additions
and
178 deletions
+198
-178
ml.hpp
modules/ml/include/opencv2/ml.hpp
+55
-51
ann_mlp.cpp
modules/ml/src/ann_mlp.cpp
+102
-93
test_mltests2.cpp
modules/ml/test/test_mltests2.cpp
+6
-1
travelsalesman.cpp
samples/cpp/travelsalesman.cpp
+35
-33
No files found.
modules/ml/include/opencv2/ml.hpp
View file @
70e1b4dd
...
...
@@ -1528,6 +1528,9 @@ public:
/** @copybrief getAnnealItePerStep @see getAnnealItePerStep */
CV_WRAP
void
setAnnealItePerStep
(
int
val
);
/** @brief Set/initialize anneal RNG */
void
setAnnealEnergyRNG
(
const
RNG
&
rng
);
/** possible activation functions */
enum
ActivationFunctions
{
/** Identity function: \f$f(x)=x\f$ */
...
...
@@ -1875,101 +1878,102 @@ class CV_EXPORTS_W ANN_MLP_ANNEAL : public ANN_MLP
{
public
:
/** @see setAnnealInitialT */
CV_WRAP
virtual
double
getAnnealInitialT
()
const
;
CV_WRAP
virtual
double
getAnnealInitialT
()
const
=
0
;
/** @copybrief getAnnealInitialT @see getAnnealInitialT */
CV_WRAP
virtual
void
setAnnealInitialT
(
double
val
);
CV_WRAP
virtual
void
setAnnealInitialT
(
double
val
)
=
0
;
/** ANNEAL: Update final temperature.
It must be \>=0 and less than initialT. Default value is 0.1.*/
/** @see setAnnealFinalT */
CV_WRAP
virtual
double
getAnnealFinalT
()
const
;
CV_WRAP
virtual
double
getAnnealFinalT
()
const
=
0
;
/** @copybrief getAnnealFinalT @see getAnnealFinalT */
CV_WRAP
virtual
void
setAnnealFinalT
(
double
val
);
CV_WRAP
virtual
void
setAnnealFinalT
(
double
val
)
=
0
;
/** ANNEAL: Update cooling ratio.
It must be \>0 and less than 1. Default value is 0.95.*/
/** @see setAnnealCoolingRatio */
CV_WRAP
virtual
double
getAnnealCoolingRatio
()
const
;
CV_WRAP
virtual
double
getAnnealCoolingRatio
()
const
=
0
;
/** @copybrief getAnnealCoolingRatio @see getAnnealCoolingRatio */
CV_WRAP
virtual
void
setAnnealCoolingRatio
(
double
val
);
CV_WRAP
virtual
void
setAnnealCoolingRatio
(
double
val
)
=
0
;
/** ANNEAL: Update iteration per step.
It must be \>0 . Default value is 10.*/
/** @see setAnnealItePerStep */
CV_WRAP
virtual
int
getAnnealItePerStep
()
const
;
CV_WRAP
virtual
int
getAnnealItePerStep
()
const
=
0
;
/** @copybrief getAnnealItePerStep @see getAnnealItePerStep */
CV_WRAP
virtual
void
setAnnealItePerStep
(
int
val
);
/** @brief Creates empty model
Use StatModel::train to train the model, Algorithm::load\<ANN_MLP\>(filename) to load the pre-trained model.
Note that the train method has optional flags: ANN_MLP::TrainFlags.
*/
// CV_WRAP static Ptr<ANN_MLP> create();
CV_WRAP
virtual
void
setAnnealItePerStep
(
int
val
)
=
0
;
/** @brief Set/initialize anneal RNG */
virtual
void
setAnnealEnergyRNG
(
const
RNG
&
rng
)
=
0
;
};
/****************************************************************************************\
* Simulated annealing solver *
\****************************************************************************************/
/** @brief The class defines interface for system state used in simulated annealing optimization algorithm.
@cite Kirkpatrick83 for details
*/
class
CV_EXPORTS
SimulatedAnnealingSolverSystem
{
protected
:
inline
SimulatedAnnealingSolverSystem
()
{}
public
:
virtual
~
SimulatedAnnealingSolverSystem
()
{}
/** Give energy value for a state of system.*/
virtual
double
energy
()
const
=
0
;
/** Function which change the state of system (random pertubation).*/
virtual
void
changeState
()
=
0
;
/** Function to reverse to the previous state. Can be called once only after changeState(). */
virtual
void
reverseState
()
=
0
;
};
/** @brief The class implements simulated annealing for optimization.
*
@cite Kirkpatrick83 for details
*/
class
CV_EXPORTS
SimulatedAnnealingSolver
:
public
Algorithm
{
public
:
SimulatedAnnealingSolver
()
{
init
();
};
~
SimulatedAnnealingSolver
();
/** Give energy value for a state of system.*/
virtual
double
energy
()
=
0
;
/** Function which change the state of system (random pertubation).*/
virtual
void
changedState
()
=
0
;
/** Function to reverse to the previous state.*/
virtual
void
reverseChangedState
()
=
0
;
/** Simulated annealing procedure. */
SimulatedAnnealingSolver
(
const
Ptr
<
SimulatedAnnealingSolverSystem
>&
system
);
inline
~
SimulatedAnnealingSolver
()
{
release
();
}
/** Simulated annealing procedure. */
int
run
();
/** Set intial temperature of simulated annealing procedure.
*@param x new initial temperature. x\>0
/** 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
@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
@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
@param ite number of iteration per temperature step ite \> 0
*/
void
setIterPerStep
(
int
ite
);
struct
Impl
;
protected
:
void
init
();
void
release
();
SimulatedAnnealingSolver
(
const
SimulatedAnnealingSolver
&
);
SimulatedAnnealingSolver
&
operator
=
(
const
SimulatedAnnealingSolver
&
);
struct
Impl
;
friend
struct
Impl
;
protected
:
Impl
*
impl
;
};
struct
SimulatedAnnealingSolver
::
Impl
{
RNG
rEnergy
;
double
coolingRatio
;
double
initialT
;
double
finalT
;
int
iterPerStep
;
Impl
()
{
initialT
=
2
;
finalT
=
0.1
;
coolingRatio
=
0.95
;
iterPerStep
=
100
;
refcount
=
1
;
}
int
refcount
;
~
Impl
()
{
refcount
--
;
CV_Assert
(
refcount
==
0
);
}
};
//! @} ml
...
...
modules/ml/src/ann_mlp.cpp
View file @
70e1b4dd
...
...
@@ -42,6 +42,40 @@
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
{
...
...
@@ -53,7 +87,7 @@ struct AnnParams
rpDW0
=
0.1
;
rpDWPlus
=
1.2
;
rpDWMinus
=
0.5
;
rpDWMin
=
FLT_EPSILON
;
rpDWMax
=
50.
;
initialT
=
10
;
finalT
=
0.1
,
coolingRatio
=
0.95
;
itePerStep
=
10
;
rEnergy
=
cv
::
RNG
(
12345
);
}
TermCriteria
termCrit
;
...
...
@@ -72,6 +106,7 @@ struct AnnParams
double
finalT
;
double
coolingRatio
;
int
itePerStep
;
RNG
rEnergy
;
};
template
<
typename
T
>
...
...
@@ -80,48 +115,60 @@ inline T inBounds(T val, T min_val, T max_val)
return
std
::
min
(
std
::
max
(
val
,
min_val
),
max_val
);
}
SimulatedAnnealingSolver
::
~
SimulatedAnnealingSolver
(
)
SimulatedAnnealingSolver
::
SimulatedAnnealingSolver
(
const
Ptr
<
SimulatedAnnealingSolverSystem
>&
system
)
{
i
f
(
impl
)
delete
impl
;
i
mpl
=
new
Impl
(
system
)
;
}
void
SimulatedAnnealingSolver
::
init
(
)
SimulatedAnnealingSolver
::
SimulatedAnnealingSolver
(
const
SimulatedAnnealingSolver
&
b
)
{
impl
=
new
SimulatedAnnealingSolver
::
Impl
();
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
=
energy
();
double
previousEnergy
=
impl
->
energy
();
int
exchange
=
0
;
while
(
Ti
>
impl
->
finalT
)
{
for
(
int
i
=
0
;
i
<
impl
->
iterPerStep
;
i
++
)
{
changed
State
();
double
newEnergy
=
energy
();
impl
->
change
State
();
double
newEnergy
=
impl
->
energy
();
if
(
newEnergy
<
previousEnergy
)
{
previousEnergy
=
newEnergy
;
//??? exchange++;
}
else
{
double
r
=
impl
->
rEnergy
.
uniform
(
double
(
0.0
),
double
(
1.0
)
);
if
(
r
<
exp
(
-
(
newEnergy
-
previousEnergy
)
/
Ti
))
double
r
=
impl
->
rEnergy
.
uniform
(
0.0
,
1.0
);
if
(
r
<
std
::
exp
(
-
(
newEnergy
-
previousEnergy
)
/
Ti
))
{
previousEnergy
=
newEnergy
;
exchange
++
;
}
else
reverseChangedState
();
{
impl
->
reverseState
();
}
}
}
...
...
@@ -131,33 +178,43 @@ int SimulatedAnnealingSolver::run()
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
ml
::
SimulatedAnnealingSolver
class
SimulatedAnnealingANN_MLP
:
public
SimulatedAnnealingSolverSystem
{
p
ublic
:
ml
::
ANN_MLP
*
nn
;
p
rotected
:
ml
::
ANN_MLP
&
nn
;
Ptr
<
ml
::
TrainData
>
data
;
int
nbVariables
;
vector
<
double
*>
adrVariables
;
...
...
@@ -165,32 +222,37 @@ public:
RNG
rIndex
;
double
varTmp
;
int
index
;
SimulatedAnnealingANN_MLP
(
ml
::
ANN_MLP
*
x
,
Ptr
<
ml
::
TrainData
>
d
)
:
nn
(
x
),
data
(
d
)
public
:
SimulatedAnnealingANN_MLP
(
ml
::
ANN_MLP
&
x
,
const
Ptr
<
ml
::
TrainData
>&
d
)
:
nn
(
x
),
data
(
d
)
{
initVarMap
();
};
void
changedState
()
}
~
SimulatedAnnealingANN_MLP
()
{}
protected
:
void
changeState
()
{
index
=
rIndex
.
uniform
(
0
,
nbVariables
);
double
dv
=
rVar
.
uniform
(
-
1.0
,
1.0
);
varTmp
=
*
adrVariables
[
index
];
*
adrVariables
[
index
]
=
dv
;
};
void
reverseChangedState
()
}
void
reverseState
()
{
*
adrVariables
[
index
]
=
varTmp
;
};
double
energy
()
{
return
nn
->
calcError
(
data
,
false
,
noArray
());
}
}
double
energy
()
const
{
return
nn
.
calcError
(
data
,
false
,
noArray
());
}
protected
:
void
initVarMap
()
{
Mat
l
=
nn
->
getLayerSizes
();
Mat
l
=
nn
.
getLayerSizes
();
nbVariables
=
0
;
adrVariables
.
clear
();
for
(
int
i
=
1
;
i
<
l
.
rows
-
1
;
i
++
)
{
Mat
w
=
nn
->
getWeights
(
i
);
Mat
w
=
nn
.
getWeights
(
i
);
for
(
int
j
=
0
;
j
<
w
.
rows
;
j
++
)
{
for
(
int
k
=
0
;
k
<
w
.
cols
;
k
++
,
nbVariables
++
)
...
...
@@ -274,6 +336,13 @@ void ANN_MLP::setAnnealItePerStep(int val)
this_
->
setAnnealItePerStep
(
val
);
}
void
ANN_MLP
::
setAnnealEnergyRNG
(
const
RNG
&
rng
)
{
ANN_MLP_ANNEAL
*
this_
=
dynamic_cast
<
ANN_MLP_ANNEAL
*>
(
this
);
if
(
!
this_
)
CV_Error
(
Error
::
StsNotImplemented
,
"the class is not ANN_MLP_ANNEAL"
);
this_
->
setAnnealEnergyRNG
(
rng
);
}
class
ANN_MLPImpl
:
public
ANN_MLP_ANNEAL
{
...
...
@@ -301,6 +370,9 @@ public:
CV_IMPL_PROPERTY
(
double
,
AnnealCoolingRatio
,
params
.
coolingRatio
)
CV_IMPL_PROPERTY
(
int
,
AnnealItePerStep
,
params
.
itePerStep
)
//CV_IMPL_PROPERTY(RNG, AnnealEnergyRNG, params.rEnergy)
inline
void
setAnnealEnergyRNG
(
const
RNG
&
val
)
{
params
.
rEnergy
=
val
;
}
void
clear
()
{
min_val
=
max_val
=
min_val1
=
max_val1
=
0.
;
...
...
@@ -1018,7 +1090,8 @@ public:
}
int
train_anneal
(
const
Ptr
<
TrainData
>&
trainData
)
{
SimulatedAnnealingANN_MLP
t
(
this
,
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
);
...
...
@@ -1665,70 +1738,6 @@ Ptr<ANN_MLP> ANN_MLP::load(const String& filepath)
return
ann
;
}
double
ANN_MLP_ANNEAL
::
getAnnealInitialT
()
const
{
const
ANN_MLPImpl
*
this_
=
dynamic_cast
<
const
ANN_MLPImpl
*>
(
this
);
if
(
!
this_
)
CV_Error
(
Error
::
StsNotImplemented
,
"the class is not ANN_MLP_ANNEAL"
);
return
this_
->
getAnnealInitialT
();
}
void
ANN_MLP_ANNEAL
::
setAnnealInitialT
(
double
val
)
{
ANN_MLPImpl
*
this_
=
dynamic_cast
<
ANN_MLPImpl
*>
(
this
);
if
(
!
this_
)
CV_Error
(
Error
::
StsNotImplemented
,
"the class is not ANN_MLP_ANNEAL"
);
this_
->
setAnnealInitialT
(
val
);
}
double
ANN_MLP_ANNEAL
::
getAnnealFinalT
()
const
{
const
ANN_MLPImpl
*
this_
=
dynamic_cast
<
const
ANN_MLPImpl
*>
(
this
);
if
(
!
this_
)
CV_Error
(
Error
::
StsNotImplemented
,
"the class is not ANN_MLP_ANNEAL"
);
return
this_
->
getAnnealFinalT
();
}
void
ANN_MLP_ANNEAL
::
setAnnealFinalT
(
double
val
)
{
ANN_MLPImpl
*
this_
=
dynamic_cast
<
ANN_MLPImpl
*>
(
this
);
if
(
!
this_
)
CV_Error
(
Error
::
StsNotImplemented
,
"the class is not ANN_MLP_ANNEAL"
);
this_
->
setAnnealFinalT
(
val
);
}
double
ANN_MLP_ANNEAL
::
getAnnealCoolingRatio
()
const
{
const
ANN_MLPImpl
*
this_
=
dynamic_cast
<
const
ANN_MLPImpl
*>
(
this
);
if
(
!
this_
)
CV_Error
(
Error
::
StsNotImplemented
,
"the class is not ANN_MLP_ANNEAL"
);
return
this_
->
getAnnealCoolingRatio
();
}
void
ANN_MLP_ANNEAL
::
setAnnealCoolingRatio
(
double
val
)
{
ANN_MLPImpl
*
this_
=
dynamic_cast
<
ANN_MLPImpl
*>
(
this
);
if
(
!
this_
)
CV_Error
(
Error
::
StsNotImplemented
,
"the class is not ANN_MLP_ANNEAL"
);
this_
->
setAnnealInitialT
(
val
);
}
int
ANN_MLP_ANNEAL
::
getAnnealItePerStep
()
const
{
const
ANN_MLPImpl
*
this_
=
dynamic_cast
<
const
ANN_MLPImpl
*>
(
this
);
if
(
!
this_
)
CV_Error
(
Error
::
StsNotImplemented
,
"the class is not ANN_MLP_ANNEAL"
);
return
this_
->
getAnnealItePerStep
();
}
void
ANN_MLP_ANNEAL
::
setAnnealItePerStep
(
int
val
)
{
ANN_MLPImpl
*
this_
=
dynamic_cast
<
ANN_MLPImpl
*>
(
this
);
if
(
!
this_
)
CV_Error
(
Error
::
StsNotImplemented
,
"the class is not ANN_MLP_ANNEAL"
);
this_
->
setAnnealInitialT
(
val
);
}
}}
/* End of file. */
modules/ml/test/test_mltests2.cpp
View file @
70e1b4dd
...
...
@@ -41,6 +41,8 @@
#include "test_precomp.hpp"
//#define GENERATE_TESTDATA
using
namespace
cv
;
using
namespace
std
;
...
...
@@ -248,7 +250,7 @@ TEST(ML_ANN, ActivationFunction)
#endif
}
}
//#define GENERATE_TESTDATA
TEST
(
ML_ANN
,
Method
)
{
String
folder
=
string
(
cvtest
::
TS
::
ptr
()
->
get_data_path
());
...
...
@@ -275,6 +277,7 @@ TEST(ML_ANN, Method)
methodName
.
push_back
(
"_anneal"
);
// methodName.push_back("_backprop"); -----> NO BACKPROP TEST
#ifdef GENERATE_TESTDATA
{
Ptr
<
ml
::
ANN_MLP
>
xx
=
ml
::
ANN_MLP_ANNEAL
::
create
();
Mat_
<
int
>
layerSizesXX
(
1
,
4
);
layerSizesXX
(
0
,
0
)
=
tdata
->
getNVars
();
...
...
@@ -290,6 +293,7 @@ TEST(ML_ANN, Method)
fs
.
open
(
dataname
+
"_init_weight.yml.gz"
,
FileStorage
::
WRITE
+
FileStorage
::
BASE64
);
xx
->
write
(
fs
);
fs
.
release
();
}
#endif
for
(
size_t
i
=
0
;
i
<
methodType
.
size
();
i
++
)
{
...
...
@@ -300,6 +304,7 @@ TEST(ML_ANN, Method)
x
->
setTrainMethod
(
methodType
[
i
]);
if
(
methodType
[
i
]
==
ml
::
ANN_MLP
::
ANNEAL
)
{
x
->
setAnnealEnergyRNG
(
RNG
(
CV_BIG_INT
(
0xffffffff
)));
x
->
setAnnealInitialT
(
12
);
x
->
setAnnealFinalT
(
0.15
);
x
->
setAnnealCoolingRatio
(
0.96
);
...
...
samples/cpp/travelsalesman.cpp
View file @
70e1b4dd
#include <opencv2/opencv.hpp>
using
namespace
std
;
using
namespace
cv
;
void
DrawTravelMap
(
Mat
&
img
,
vector
<
Point
>
&
p
,
vector
<
int
>
&
n
);
class
TravelSalesman
:
public
ml
::
SimulatedAnnealingSolver
class
TravelSalesman
:
public
ml
::
SimulatedAnnealingSolverSystem
{
private
:
vector
<
Point
>
&
posCity
;
vector
<
int
>
&
next
;
const
std
::
vector
<
Point
>&
posCity
;
std
::
vector
<
int
>&
next
;
RNG
rng
;
int
d0
,
d1
,
d2
,
d3
;
public
:
TravelSalesman
(
vector
<
Point
>
&
p
,
vector
<
int
>
&
n
)
:
posCity
(
p
),
next
(
n
)
TravelSalesman
(
std
::
vector
<
Point
>
&
p
,
std
::
vector
<
int
>
&
n
)
:
posCity
(
p
),
next
(
n
)
{
rng
=
theRNG
();
}
;
}
/** Give energy value for a state of system.*/
virtual
double
energy
()
;
/*virtual*/
double
energy
()
const
;
/** Function which change the state of system (random pertubation).*/
virtual
void
changed
State
();
/*virtual*/
void
change
State
();
/** Function to reverse to the previous state.*/
virtual
void
reverseChanged
State
();
/*virtual*/
void
reverse
State
();
};
void
TravelSalesman
::
change
d
State
()
void
TravelSalesman
::
changeState
()
{
d0
=
rng
.
uniform
(
0
,
static_cast
<
int
>
(
posCity
.
size
()));
d1
=
next
[
d0
];
d2
=
next
[
d1
];
d3
=
next
[
d2
];
int
d0Tmp
=
d0
;
int
d1Tmp
=
d1
;
int
d2Tmp
=
d2
;
next
[
d0
Tmp
]
=
d2
;
next
[
d2
Tmp
]
=
d1
;
next
[
d1
Tmp
]
=
d3
;
next
[
d0
]
=
d2
;
next
[
d2
]
=
d1
;
next
[
d1
]
=
d3
;
}
void
TravelSalesman
::
reverse
Changed
State
()
void
TravelSalesman
::
reverseState
()
{
next
[
d0
]
=
d1
;
next
[
d1
]
=
d2
;
next
[
d2
]
=
d3
;
}
double
TravelSalesman
::
energy
()
double
TravelSalesman
::
energy
()
const
{
double
e
=
0
;
double
e
=
0
;
for
(
size_t
i
=
0
;
i
<
next
.
size
();
i
++
)
{
e
+=
norm
(
posCity
[
i
]
-
posCity
[
next
[
i
]]);
e
+=
norm
(
posCity
[
i
]
-
posCity
[
next
[
i
]]);
}
return
e
;
}
void
DrawTravelMap
(
Mat
&
img
,
vector
<
Point
>
&
p
,
vector
<
int
>
&
n
)
static
void
DrawTravelMap
(
Mat
&
img
,
std
::
vector
<
Point
>
&
p
,
std
::
vector
<
int
>
&
n
)
{
for
(
size_t
i
=
0
;
i
<
n
.
size
();
i
++
)
{
...
...
@@ -74,12 +68,12 @@ int main(void)
{
int
nbCity
=
40
;
Mat
img
(
500
,
500
,
CV_8UC3
,
Scalar
::
all
(
0
));
RNG
&
rng
=
theRNG
(
);
RNG
rng
(
123456
);
int
radius
=
static_cast
<
int
>
(
img
.
cols
*
0.45
);
Point
center
(
img
.
cols
/
2
,
img
.
rows
/
2
);
vector
<
Point
>
posCity
(
nbCity
);
vector
<
int
>
next
(
nbCity
);
std
::
vector
<
Point
>
posCity
(
nbCity
);
std
::
vector
<
int
>
next
(
nbCity
);
for
(
size_t
i
=
0
;
i
<
posCity
.
size
();
i
++
)
{
double
theta
=
rng
.
uniform
(
0.
,
2
*
CV_PI
);
...
...
@@ -87,25 +81,33 @@ int main(void)
posCity
[
i
].
y
=
static_cast
<
int
>
(
radius
*
sin
(
theta
))
+
center
.
y
;
next
[
i
]
=
(
i
+
1
)
%
nbCity
;
}
TravelSalesman
ts
(
posCity
,
next
);
Ptr
<
TravelSalesman
>
ts_system
(
new
TravelSalesman
(
posCity
,
next
));
ml
::
SimulatedAnnealingSolver
ts
(
ts_system
);
ts
.
setIterPerStep
(
10000
*
nbCity
);
ts
.
setCoolingRatio
(
0.99
);
ts
.
setInitialTemperature
(
100
);
ts
.
setIterPerStep
(
10000
*
nbCity
);
ts
.
setFinalTemperature
(
100
*
0.97
);
DrawTravelMap
(
img
,
posCity
,
next
);
imshow
(
"Map"
,
img
);
waitKey
(
10
);
for
(
int
i
=
0
;
i
<
10
0
;
i
++
)
for
(
int
i
=
0
,
zeroChanges
=
0
;
zeroChanges
<
1
0
;
i
++
)
{
ts
.
run
();
int
changesApplied
=
ts
.
run
();
img
=
Mat
::
zeros
(
img
.
size
(),
CV_8UC3
);
DrawTravelMap
(
img
,
posCity
,
next
);
imshow
(
"Map"
,
img
);
waitKey
(
10
);
int
k
=
waitKey
(
10
);
double
ti
=
ts
.
getFinalTemperature
();
cout
<<
ti
<<
" -> "
<<
ts
.
energy
()
<<
"
\n
"
;
std
::
cout
<<
"i="
<<
i
<<
" changesApplied="
<<
changesApplied
<<
" temp="
<<
ti
<<
" 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
);
return
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