Class TspDemoView

All Implemented Interfaces:
IFeedbackProvider, ISimulationHost, IAcceptedMoveListener, ITspDemoResettable, SimulationListener, IFileDropHandler, ComponentListener, FocusListener, MouseListener, ImageObserver, MenuContainer, Serializable, EventListener, Accessible, RootPaneContainer, WindowConstants

public class TspDemoView extends SimulationView implements ITspDemoResettable, IAcceptedMoveListener
Traveling Salesperson Problem (TSP) simulated annealing demo, hosted in an MDI SimulationView.

What this demo shows

The view displays a set of randomly placed cities connected by their current best tour (a closed Hamiltonian cycle). As the annealer runs, the tour progressively untangles from its initial random spaghetti into a near-optimal route. The optional "river" (a vertical blue line) adds a configurable penalty or bonus for each edge that crosses it, changing the shape of the optimal solution.

An Energy vs. Temperature scatter plot in the right-hand diagnostics panel shows accepted moves as a gray point cloud and best solutions as connected red squares. Together these reveal the Metropolis acceptance criterion operating across the full temperature range.

Layout

The view uses the standard SimulationView diagnostics split:

  • Left (60%): world-coordinate canvas showing cities and tour.
  • Right (40%): EvsTPlotPanel (E vs T scatter plot).
  • South: TspDemoControlPanel with media buttons, city/penalty sliders, and a Reset button.

Threading model

The annealing algorithm runs on the simulation thread. The view receives two kinds of callbacks on the EDT:

The before/after draw hooks run on the EDT during each repaint and read only the volatile model and bestTourSnapshot snapshots — they never touch mutable simulation internals directly.

Construction pattern

Because super(...) must be the first statement and the SimulationEngine holds its Simulation as a final field, the simulation and model must be created before super() is called. A ThreadLocal (BUNDLE_TL) is used to smuggle the newly created TspModel across the super() boundary so the constructor can retrieve it immediately after.

Reset

Reset is handled by SimulationView.requestEngineReset(java.util.function.Supplier<edu.cnu.mdi.sim.Simulation>, java.util.function.Consumer<edu.cnu.mdi.sim.SimulationEngine>, boolean, boolean), which stops the current engine (if running), builds a new simulation via the supplied factory, swaps it in, and restarts. The after-swap hook detaches the IAcceptedMoveListener from the old simulation and attaches it to the new one, ensuring the E vs T plot continues to receive data correctly.

See Also:
  • Field Details

    • DEFAULT_NUM_CITY

      public static final int DEFAULT_NUM_CITY
      Default number of cities for a new random problem.
      See Also:
    • DEFAULT_RIVER_PENALTY

      public static final float DEFAULT_RIVER_PENALTY
      Default river crossing penalty (positive = penalty, negative = bonus).
      See Also:
  • Constructor Details

    • TspDemoView

      public TspDemoView(Object... keyVals)
      Create the TSP demo view.

      The constructor calls createSimulationAndStashBundle(int, double, long) to build the initial simulation and stash the model in BUNDLE_TL, then passes the simulation to super(...). After super() returns it recovers the model from the thread-local and wires up the remaining references.

      Parameters:
      keyVals - standard BaseView key-value args
  • Method Details

    • getViewInfo

      public AbstractViewInfo getViewInfo()
      Get an information object describing this view, used in the UI and for help.
      Overrides:
      getViewInfo in class BaseView
      Returns:
      view info, or null
    • requestReset

      public void requestReset(int cityCount, double riverPenalty)
      Request a reset/reinitialization of the demo with the provided parameters.

      Implementations should only honor this request when the simulation is in a safe state (typically READY or TERMINATED).

      Clears the E vs T plot immediately (before the engine stops, so stale data disappears at once), then delegates to SimulationView.requestEngineReset(java.util.function.Supplier<edu.cnu.mdi.sim.Simulation>, java.util.function.Consumer<edu.cnu.mdi.sim.SimulationEngine>, boolean, boolean). The after-swap hook:

      1. Recovers the new model from BUNDLE_TL.
      2. Moves the IAcceptedMoveListener from the old simulation to the new one.
      3. Updates model, sim, and bestTourSnapshot.
      4. Attaches an engine-backed feedback channel to the new simulation.
      Specified by:
      requestReset in interface ITspDemoResettable
      Parameters:
      cityCount - number of cities (e.g. 10..500)
      riverPenalty - penalty/bonus for crossing the river (e.g. -1..+1)
    • onSimulationProgress

      protected void onSimulationProgress(SimulationContext ctx, ProgressInfo progress)
      Refresh the best tour snapshot from the simulation's current best solution.

      Called on the EDT at the rate set by SimulatedAnnealingConfig.progressEverySteps(), providing a backstop refresh in case newBest(double, double) misses a repaint. This also handles the initial state where bestTourSnapshot is null — the first progress callback will always populate it.

      Overrides:
      onSimulationProgress in class SimulationView
      Parameters:
      ctx - simulation context
      progress - current progress info
    • acceptedMove

      public void acceptedMove(double temperature, double energy)
      Called on the Swing EDT for the latest coalesced accepted move.

      Forwards the (temperature, energy) point to the E vs T scatter plot as a gray accepted-move point.

      Specified by:
      acceptedMove in interface IAcceptedMoveListener
      Parameters:
      temperature - current annealing temperature
      energy - current solution energy (may be higher than best)
    • newBest

      public void newBest(double temperature, double energy)
      Called on the Swing EDT for the latest coalesced new-best notification.

      Two things happen here:

      1. The best tour snapshot is updated immediately via a volatile reference write, so the next repaint shows the improved tour without waiting for the next progress callback. This gives responsive visual feedback during the early fast-improving phase of annealing when new bests arrive frequently.
      2. The (temperature, energy) point is added to the E vs T plot as a red best-solution square.
      Specified by:
      newBest in interface IAcceptedMoveListener
      Parameters:
      temperature - temperature at which the new best was found
      energy - energy of the new best solution