#region License Information
/* HeuristicLab
* Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Drawing;
using System.IO;
using HeuristicLab.Common;
using HeuristicLab.Core;
using HeuristicLab.Optimization;
using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
using HeuristicLab.Persistence.Default.Xml;
namespace HeuristicLab.Clients.OKB {
[Item("OKB Experiment", "...")]
[Creatable("Optimization Knowledge Base (OKB)")]
[StorableClass]
public sealed class OKBExperiment : NamedItem, IOptimizer, IStorableContent {
public string Filename { get; set; }
public override Image ItemImage {
get {
if (Algorithm != null) return Algorithm.ItemImage;
else return HeuristicLab.Common.Resources.VSImageLibrary.Event;
}
}
private long algorithmId;
public long AlgorithmId {
get { return algorithmId; }
private set {
if (algorithmId != value) {
algorithmId = value;
OnAlgorithmIdChanged();
}
}
}
private IAlgorithm algorithm;
private IAlgorithm Algorithm {
get { return algorithm; }
set {
DeregisterAlgorithmEvents();
algorithm = value;
RegisterAlgorithmEvents();
if ((algorithm != null) && (problem != null)) {
algorithm.Problem = problem;
algorithm.Prepare(true);
}
}
}
private long problemId;
public long ProblemId {
get { return problemId; }
private set {
if (problemId != value) {
problemId = value;
OnProblemIdChanged();
}
}
}
private IProblem problem;
private IProblem Problem {
get { return problem; }
set {
problem = value;
if ((algorithm != null) && (problem != null)) {
algorithm.Problem = problem;
algorithm.Prepare(true);
}
}
}
public ExecutionState ExecutionState {
get {
if ((Algorithm != null) && (Problem != null)) return Algorithm.ExecutionState;
else return ExecutionState.Stopped;
}
}
public TimeSpan ExecutionTime {
get {
if (Algorithm != null) return Algorithm.ExecutionTime;
else return TimeSpan.Zero;
}
}
public IKeyedItemCollection AlgorithmParameters {
get {
if (Algorithm != null) return Algorithm.Parameters;
else return null;
}
}
public IKeyedItemCollection ProblemParameters {
get {
if (Problem != null) return Problem.Parameters;
else return null;
}
}
public ResultCollection Results {
get {
if (Algorithm != null) return Algorithm.Results;
else return null;
}
}
private RunCollection runs;
public RunCollection Runs {
get { return runs; }
}
#region Persistence Properties
[Storable(Name = "AlgorithmId")]
private long StorableAlgorithmId {
get { return algorithmId; }
set { algorithmId = value; }
}
[Storable(Name = "Algorithm")]
private IAlgorithm StorableAlgorithm {
get { return Algorithm; }
set { Algorithm = value; }
}
[Storable(Name = "ProblemId")]
private long StorableProblemId {
get { return problemId; }
set { problemId = value; }
}
[Storable(Name = "Problem")]
private IProblem StorableProblem {
get { return Problem; }
set { Problem = value; }
}
[Storable(Name = "Runs")]
private RunCollection StorableRuns {
get { return runs; }
set { runs = value; }
}
#endregion
[StorableConstructor]
private OKBExperiment(bool deserializing) : base(deserializing) { }
private OKBExperiment(OKBExperiment original, Cloner cloner)
: base(original, cloner) {
algorithmId = original.algorithmId;
algorithm = cloner.Clone(original.algorithm);
problemId = original.problemId;
problem = cloner.Clone(original.problem);
runs = cloner.Clone(original.runs);
RegisterAlgorithmEvents();
}
public OKBExperiment()
: base() {
name = ItemName;
description = ItemDescription;
runs = new RunCollection();
}
[StorableHook(HookType.AfterDeserialization)]
private void AfterDeserialization() {
RegisterAlgorithmEvents();
}
public override IDeepCloneable Clone(Cloner cloner) {
return new OKBExperiment(this, cloner);
}
public void Load(Algorithm algorithm) {
if (algorithm == null) {
Algorithm = null;
AlgorithmId = 0;
} else {
try {
if (AlgorithmId != algorithm.Id) {
AlgorithmData algorithmData = OKBClient.Instance.GetAlgorithmData(algorithm.Id);
using (MemoryStream stream = new MemoryStream(algorithmData.Data)) {
Algorithm = XmlParser.Deserialize(stream);
Algorithm.StoreAlgorithmInEachRun = true;
}
}
AlgorithmId = algorithm.Id;
}
catch (Exception ex) {
Algorithm = null;
AlgorithmId = 0;
OnExceptionOccurred(ex);
}
}
}
public void Load(Problem problem) {
if (problem == null) {
Problem = null;
ProblemId = 0;
} else {
try {
if (ProblemId != problem.Id) {
ProblemData problemData = OKBClient.Instance.GetProblemData(problem.Id);
using (MemoryStream stream = new MemoryStream(problemData.Data)) {
Problem = XmlParser.Deserialize(stream);
}
}
ProblemId = problem.Id;
}
catch (Exception ex) {
Problem = null;
ProblemId = 0;
OnExceptionOccurred(ex);
}
}
}
public void Prepare(bool clearRuns) {
if (Algorithm != null) Algorithm.Prepare(clearRuns);
}
public void Prepare() {
if (Algorithm != null) Algorithm.Prepare();
}
public void Start() {
if (Algorithm != null) Algorithm.Start();
}
public void Pause() {
if (Algorithm != null) Algorithm.Pause();
}
public void Stop() {
if (Algorithm != null) Algorithm.Stop();
}
#region Events
public event EventHandler AlgorithmIdChanged;
private void OnAlgorithmIdChanged() {
EventHandler handler = AlgorithmIdChanged;
if (handler != null) handler(this, EventArgs.Empty);
}
public event EventHandler ProblemIdChanged;
private void OnProblemIdChanged() {
EventHandler handler = ProblemIdChanged;
if (handler != null) handler(this, EventArgs.Empty);
}
public event EventHandler> ExceptionOccurred;
private void OnExceptionOccurred(Exception exception) {
EventHandler> handler = ExceptionOccurred;
if (handler != null) handler(this, new EventArgs(exception));
}
public event EventHandler ExecutionStateChanged;
private void OnExecutionStateChanged() {
EventHandler handler = ExecutionStateChanged;
if (handler != null) handler(this, EventArgs.Empty);
}
public event EventHandler ExecutionTimeChanged;
private void OnExecutionTimeChanged() {
EventHandler handler = ExecutionTimeChanged;
if (handler != null) handler(this, EventArgs.Empty);
}
public event EventHandler Prepared;
private void OnPrepared() {
EventHandler handler = Prepared;
if (handler != null) handler(this, EventArgs.Empty);
}
public event EventHandler Started;
private void OnStarted() {
EventHandler handler = Started;
if (handler != null) handler(this, EventArgs.Empty);
}
public event EventHandler Paused;
private void OnPaused() {
EventHandler handler = Paused;
if (handler != null) handler(this, EventArgs.Empty);
}
public event EventHandler Stopped;
private void OnStopped() {
EventHandler handler = Stopped;
if (handler != null) handler(this, EventArgs.Empty);
}
private void RegisterAlgorithmEvents() {
if (Algorithm != null) {
Algorithm.ExceptionOccurred += new EventHandler>(algorithm_ExceptionOccurred);
Algorithm.ExecutionStateChanged += new EventHandler(algorithm_ExecutionStateChanged);
Algorithm.ExecutionTimeChanged += new EventHandler(algorithm_ExecutionTimeChanged);
Algorithm.ItemImageChanged += new EventHandler(algorithm_ItemImageChanged);
Algorithm.Paused += new EventHandler(algorithm_Paused);
Algorithm.Prepared += new EventHandler(algorithm_Prepared);
Algorithm.Started += new EventHandler(algorithm_Started);
Algorithm.Stopped += new EventHandler(algorithm_Stopped);
Algorithm.Runs.ItemsAdded += new Collections.CollectionItemsChangedEventHandler(algorithm_Runs_ItemsAdded);
Algorithm.Runs.ItemsRemoved += new Collections.CollectionItemsChangedEventHandler(algorithm_Runs_ItemsRemoved);
Algorithm.Runs.CollectionReset += new Collections.CollectionItemsChangedEventHandler(algorithm_Runs_CollectionReset);
}
}
private void DeregisterAlgorithmEvents() {
if (Algorithm != null) {
Algorithm.ExceptionOccurred -= new EventHandler>(algorithm_ExceptionOccurred);
Algorithm.ExecutionStateChanged -= new EventHandler(algorithm_ExecutionStateChanged);
Algorithm.ExecutionTimeChanged -= new EventHandler(algorithm_ExecutionTimeChanged);
Algorithm.ItemImageChanged -= new EventHandler(algorithm_ItemImageChanged);
Algorithm.Paused -= new EventHandler(algorithm_Paused);
Algorithm.Prepared -= new EventHandler(algorithm_Prepared);
Algorithm.Started -= new EventHandler(algorithm_Started);
Algorithm.Stopped -= new EventHandler(algorithm_Stopped);
Algorithm.Runs.ItemsAdded -= new Collections.CollectionItemsChangedEventHandler(algorithm_Runs_ItemsAdded);
Algorithm.Runs.ItemsRemoved -= new Collections.CollectionItemsChangedEventHandler(algorithm_Runs_ItemsRemoved);
Algorithm.Runs.CollectionReset -= new Collections.CollectionItemsChangedEventHandler(algorithm_Runs_CollectionReset);
}
}
private void algorithm_ExceptionOccurred(object sender, EventArgs e) {
OnExceptionOccurred(e.Value);
}
private void algorithm_ExecutionStateChanged(object sender, EventArgs e) {
OnExecutionStateChanged();
}
private void algorithm_ExecutionTimeChanged(object sender, EventArgs e) {
OnExecutionTimeChanged();
}
private void algorithm_ItemImageChanged(object sender, EventArgs e) {
OnItemImageChanged();
}
private void algorithm_Paused(object sender, EventArgs e) {
OnPaused();
}
private void algorithm_Prepared(object sender, EventArgs e) {
OnPrepared();
}
private void algorithm_Started(object sender, EventArgs e) {
OnStarted();
}
private void algorithm_Stopped(object sender, EventArgs e) {
try {
OKBClient.Instance.AddRun(AlgorithmId, ProblemId, algorithm);
}
catch (Exception ex) {
OnExceptionOccurred(ex);
}
OnStopped();
}
private void algorithm_Runs_ItemsAdded(object sender, Collections.CollectionItemsChangedEventArgs e) {
runs.AddRange(e.Items);
}
private void algorithm_Runs_ItemsRemoved(object sender, Collections.CollectionItemsChangedEventArgs e) {
runs.RemoveRange(e.Items);
}
private void algorithm_Runs_CollectionReset(object sender, Collections.CollectionItemsChangedEventArgs e) {
runs.Clear();
runs.AddRange(algorithm.Runs);
}
#endregion
}
}