File size: 3,420 Bytes
d347290
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import gradio as gr
import logging

from gradio_log import Log
from numpy import asarray
from numpy import exp
from numpy.random import randn
from numpy.random import rand
from numpy.random import seed
from matplotlib import pyplot

# setup logging

LOG_FILE = "sim-ann.log"
logging.basicConfig(
    filename=LOG_FILE,
    level=logging.INFO,
    format="%(levelname)s: %(asctime)s %(message)s",
    datefmt="%m/%d/%Y %I:%M:%S",
)

# clear the log file
with open(LOG_FILE, "w"):
    pass


# Define the objective function
def objective(x):
    return x[0] ** 2.0


# Simulated Annealing algorithm
def simulated_annealing(objective, bounds, n_iterations, step_size, temp):
    # Generate an initial point
    best = bounds[:, 0] + rand(len(bounds)) * (bounds[:, 1] - bounds[:, 0])
    # Evaluate the initial point
    best_eval = objective(best)
    # Current working solution
    curr, curr_eval = best, best_eval
    scores = list()
    # Run the algorithm
    for i in range(n_iterations):
        # Take a step
        candidate = curr + randn(len(bounds))
        candidate = curr + randn(len(bounds)) * step_size
        # Evaluate the candidate point
        candidate_eval = objective(candidate)
        # Check for a new best solution
        if candidate_eval < best_eval:
            # Store the new best point
            best, best_eval = candidate, candidate_eval
            # Keep track of scores
            scores.append(best_eval)
            # Report progress
            logging.info(">%d f(%s) = %.10f" % (i, best, best_eval))
            # Difference between candidate and current point evaluation
            diff = candidate_eval - curr_eval
            # Calculate temperature for the current epoch
            t = temp / float(i + 1)
            # Calculate Metropolis acceptance criterion
            metropolis = exp(-diff / t)
            # Check if we should keep the new point
            if diff < 0 or rand() < metropolis:
                # Store the new current point
                curr, curr_eval = candidate, candidate_eval
    return [best, best_eval, scores]


def run(s=1, l_bound=-0.5, u_bound=0.5, n_iterations=1000, step_size=0.1, temp=10):

    # Seed the pseudorandom number generator
    seed(s)
    # Define the range for input
    bounds = asarray([[l_bound, u_bound]])
    # Perform the simulated annealing search
    best, score, scores = simulated_annealing(
        objective, bounds, n_iterations, step_size, temp
    )
    logging.info("Done!")
    logging.info("f(%s) = %.10f" % (best, score))


with gr.Blocks(title="Simulated Annealing") as demo:
    title = gr.Markdown("## Simulated Annealing")
    with gr.Row():
        with gr.Column():
            s = gr.Number(label="Seed", value=1)
            l_bound = gr.Number(label="Lower Bound", value=-0.5)
            u_bound = gr.Number(label="Upper Bound", value=0.5)
        with gr.Column():
            n_iterations = gr.Number(label="# Iterations", value=1000)
            step_size = gr.Number(label="Step Size", value=0.1)
            temp = gr.Number(label="Temperature", value=10)
        # output = gr.Textbox()
    with gr.Row():
        btn = gr.Button("Run")
    btn.click(
        fn=run,
        inputs=[s, l_bound, u_bound, n_iterations, step_size, temp],
        # outputs=[output],
    )
    Log(LOG_FILE, dark=True, xterm_font_size=12)

if __name__ == "__main__":
    demo.launch(share=True)