Skip to content

Commit c788e81

Browse files
committed
Added variants of coupled simulated annealing
1 parent 74e037d commit c788e81

File tree

5 files changed

+47
-12
lines changed

5 files changed

+47
-12
lines changed

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ packageDescription := "DynaML is a scala library/repl for implementing and worki
1212
"which can be extended easily to implement advanced models for small and large scale applications.\n\n"+
1313
"But the library can also be used as an educational/research tool for data analysis."
1414

15-
val mainVersion = "v1.4-beta.31"
15+
val mainVersion = "v1.4-beta.32"
1616

1717
val dataDirectory = settingKey[File]("The directory holding the data files for running example scripts")
1818

dynaml-core/src/main/scala-2.11/io/github/mandar2812/dynaml/optimization/CoupledSimulatedAnnealing.scala

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ under the License.
1919
package io.github.mandar2812.dynaml.optimization
2020

2121
import breeze.stats.distributions.CauchyDistribution
22+
import spire.implicits._
2223

2324
import scala.util.Random
2425

@@ -33,6 +34,8 @@ class CoupledSimulatedAnnealing[M <: GloballyOptimizable](model: M)
3334

3435
protected var MAX_ITERATIONS: Int = 10
3536

37+
var variant = CoupledSimulatedAnnealing.MuSA
38+
3639
def setMaxIterations(m: Int) = {
3740
MAX_ITERATIONS = m
3841
this
@@ -53,9 +56,7 @@ class CoupledSimulatedAnnealing[M <: GloballyOptimizable](model: M)
5356
this
5457
}
5558

56-
protected val acceptance = (energy: Double,
57-
coupling: Double,
58-
temperature: Double) => {
59+
protected def acceptance(energy: Double, oldEnergy: Double, coupling: Double, temperature: Double) = {
5960
val prob = math.exp(-1.0*energy/temperature)
6061
prob/(prob+coupling)
6162
}
@@ -74,6 +75,9 @@ class CoupledSimulatedAnnealing[M <: GloballyOptimizable](model: M)
7475
def mutationTemperature(initialTemp: Double)(k: Int): Double =
7576
initialTemp/k.toDouble
7677

78+
def gamma(landscape: Seq[Double])(accTemp: Double): Double =
79+
CoupledSimulatedAnnealing.couplingFactor(variant)(landscape, accTemp)
80+
7781
override def optimize(initialConfig: Map[String, Double],
7882
options: Map[String, String] = Map()) = {
7983

@@ -85,28 +89,29 @@ class CoupledSimulatedAnnealing[M <: GloballyOptimizable](model: M)
8589
val energyLandscape = getEnergyLandscape(initialConfig, options)
8690

8791
var currentEnergyLandscape = energyLandscape
88-
var newEnergyLandscape = energyLandscape
8992

90-
(1 to MAX_ITERATIONS).foreach((iteration) => {
93+
cfor(1)(iteration => iteration < MAX_ITERATIONS, iteration => iteration + 1)( iteration => {
9194
logger.info("**************************")
9295
logger.info("CSA Iteration: "+iteration)
9396
//mutate each element of the grid with
9497
//the generating distribution
9598
//and accept using the acceptance distribution
9699
mutTemp = mutationTemperature(iTemp)(iteration)
97100
accTemp = acceptanceTemperature(iTemp)(iteration)
98-
val couplingFactor = currentEnergyLandscape.map(c => math.exp(-1.0*c._1/accTemp)).sum
101+
102+
val maxEnergy = currentEnergyLandscape.map(_._1).max
103+
104+
val couplingFactor = gamma(currentEnergyLandscape.map(t => t._1 - maxEnergy))(accTemp)
99105
//Now mutate each solution and accept/reject
100106
//according to the acceptance probability
101-
102-
newEnergyLandscape = currentEnergyLandscape.map((config) => {
107+
val newEnergyLandscape = currentEnergyLandscape.map((config) => {
103108
//mutate this config
104109
val new_config = mutate(config._2, mutTemp)
105110
val new_energy = system.energy(new_config, options)
106111
val ans = if(new_energy < config._1) {
107112
(new_energy, new_config)
108113
} else {
109-
val acc = acceptance(new_energy, couplingFactor, accTemp)
114+
val acc = acceptance(new_energy - maxEnergy, config._1, couplingFactor, accTemp)
110115
if(Random.nextDouble <= acc) (new_energy, new_config) else config
111116
}
112117
ans
@@ -126,3 +131,33 @@ class CoupledSimulatedAnnealing[M <: GloballyOptimizable](model: M)
126131
(system, landscape(optimum))
127132
}
128133
}
134+
135+
136+
object CoupledSimulatedAnnealing {
137+
138+
val MuSA = "CSA-MuSA"
139+
val BA = "CSA-BA"
140+
val M = "CSA-M"
141+
val MwVC = "CSA-MwVC"
142+
val SA = "SA"
143+
144+
def couplingFactor(variant: String)(landscape: Seq[Double], Tacc: Double): Double = {
145+
if(variant == MuSA || variant == BA)
146+
landscape.map(energy => math.exp(-1.0*energy/Tacc)).sum
147+
else if (variant == M || variant == MwVC)
148+
landscape.map(energy => math.exp(energy/Tacc)).sum
149+
else 1.0
150+
}
151+
152+
def acceptanceProbability(variant: String)(energy: Double, oldEnergy: Double, gamma: Double, temperature: Double) = {
153+
if(variant == MuSA )
154+
math.exp(-1.0*energy/temperature)/(math.exp(-1.0*energy/temperature)+gamma)
155+
else if (variant == BA)
156+
1.0 - (math.exp(-1.0*oldEnergy/temperature)/gamma)
157+
else if (variant == M || variant == MwVC)
158+
math.exp(oldEnergy/temperature)/gamma
159+
else gamma/(1.0 + math.exp((energy - oldEnergy)/temperature))
160+
}
161+
162+
163+
}

project/Dependencies.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import sbt._
22

33
object Dependencies {
44

5-
val scala = "2.11.7"
5+
val scala = "2.11.8"
66

77
val baseDependencies = Seq(
88
"org.scala-lang" % "scala-compiler" % scala % "compile",
@@ -38,7 +38,7 @@ object Dependencies {
3838
)
3939

4040
val replDependency = Seq(
41-
"com.lihaoyi" % "ammonite-repl_2.11.7" % "0.5.8"
41+
"com.lihaoyi" % "ammonite-repl_2.11.8" % "0.5.8"
4242
)
4343

4444
val tinkerpopDependency = Seq(

0 commit comments

Comments
 (0)