Index: branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/Helper.cs
===================================================================
--- branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/Helper.cs	(revision 11402)
+++ branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/Helper.cs	(revision 11405)
@@ -64,4 +64,27 @@
         permutations: permDict.Count > 0 ? permDict : null);
     }
+
+    internal static void Write(IScope scope, ParameterVector vector) {
+      foreach (var param in vector.BinaryNames) {
+        if (scope.Variables.ContainsKey(param))
+          scope.Variables[param].Value = vector.BinaryVector(param);
+        else scope.Variables.Add(new Variable(param, vector.BinaryVector(param)));
+      }
+      foreach (var param in vector.IntegerNames) {
+        if (scope.Variables.ContainsKey(param))
+          scope.Variables[param].Value = vector.IntegerVector(param);
+        else scope.Variables.Add(new Variable(param, vector.IntegerVector(param)));
+      }
+      foreach (var param in vector.RealNames) {
+        if (scope.Variables.ContainsKey(param))
+          scope.Variables[param].Value = vector.RealVector(param);
+        else scope.Variables.Add(new Variable(param, vector.RealVector(param)));
+      }
+      foreach (var param in vector.PermutationNames) {
+        if (scope.Variables.ContainsKey(param))
+          scope.Variables[param].Value = vector.Permutation(param);
+        else scope.Variables.Add(new Variable(param, vector.Permutation(param)));
+      }
+    }
   }
 }
Index: branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/HeuristicLab.Problems.Programmable-3.3.csproj
===================================================================
--- branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/HeuristicLab.Problems.Programmable-3.3.csproj	(revision 11402)
+++ branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/HeuristicLab.Problems.Programmable-3.3.csproj	(revision 11405)
@@ -159,4 +159,5 @@
     <Compile Include="Interfaces\IProblemDefinition.cs" />
     <Compile Include="Interfaces\ISingleObjectiveProblemDefinition.cs" />
+    <Compile Include="Operators\SingleObjectiveParameterVectorImprover.cs" />
     <Compile Include="ProblemDefinition.cs" />
     <Compile Include="ProblemDefinitionScript.cs" />
Index: branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/Operators/SingleObjectiveAnalyzer.cs
===================================================================
--- branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/Operators/SingleObjectiveAnalyzer.cs	(revision 11402)
+++ branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/Operators/SingleObjectiveAnalyzer.cs	(revision 11405)
@@ -49,5 +49,5 @@
     public override IOperation Apply() {
       var host = ProblemDefinitionParameter.ActualValue;
-      if (host.Instance == null) throw new InvalidOperationException("Script instance is null, maybe the code doesn't compile.");
+      if (host.Instance == null) throw new InvalidOperationException("Problem definition is not available.");
       var config = ConfigurationParameter.ActualValue;
       var results = ResultsParameter.ActualValue;
Index: branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/Operators/SingleObjectiveEvaluator.cs
===================================================================
--- branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/Operators/SingleObjectiveEvaluator.cs	(revision 11402)
+++ branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/Operators/SingleObjectiveEvaluator.cs	(revision 11405)
@@ -67,5 +67,5 @@
       var random = RandomParameter.ActualValue;
       var host = ProblemDefinitionParameter.ActualValue;
-      if (host.Instance == null) throw new InvalidOperationException("Script instance is null, maybe the code doesn't compile.");
+      if (host.Instance == null) throw new InvalidOperationException("Problem definition is not available.");
       var config = ConfigurationParameter.ActualValue;
       var vector = Helper.Extract(ExecutionContext.Scope, config);
Index: branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/Operators/SingleObjectiveParameterVectorImprover.cs
===================================================================
--- branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/Operators/SingleObjectiveParameterVectorImprover.cs	(revision 11405)
+++ branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/Operators/SingleObjectiveParameterVectorImprover.cs	(revision 11405)
@@ -0,0 +1,101 @@
+﻿using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.Programmable {
+  [Item("Single-objective ParameterVector Improver", "Improves a solution by calling GetNeighbors and Evaluate of the corresponding problem definition.")]
+  [StorableClass]
+  public sealed class SingleObjectiveParameterVectorImprover : SingleSuccessorOperator, ISingleObjectiveImprovementOperator, IStochasticOperator {
+    public IValueLookupParameter<IItem> SolutionParameter {
+      get { return new ValueLookupParameter<IItem>("notused"); }
+    }
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public ILookupParameter<ISingleObjectiveProblemDefinitionHost> ProblemDefinitionParameter {
+      get { return (ILookupParameter<ISingleObjectiveProblemDefinitionHost>)Parameters["ProblemDefinition"]; }
+    }
+
+    public ILookupParameter<Configuration> ConfigurationParameter {
+      get { return (ILookupParameter<Configuration>)Parameters["Configuration"]; }
+    }
+
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+
+    public IValueLookupParameter<IntValue> ImprovementAttemptsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["ImprovementAttempts"]; }
+    }
+
+    public IValueLookupParameter<IntValue> SampleSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["SampleSize"]; }
+    }
+
+    public ILookupParameter<IntValue> LocalEvaluatedSolutionsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["LocalEvaluatedSolutions"]; }
+    }
+
+    [StorableConstructor]
+    private SingleObjectiveParameterVectorImprover(bool deserializing) : base(deserializing) { }
+    private SingleObjectiveParameterVectorImprover(SingleObjectiveParameterVectorImprover original, Cloner cloner) : base(original, cloner) { }
+    public SingleObjectiveParameterVectorImprover() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Parameters.Add(new LookupParameter<ISingleObjectiveProblemDefinitionHost>("ProblemDefinition", "The host that holds the problem definition."));
+      Parameters.Add(new LookupParameter<Configuration>("Configuration", "An item that holds the problem's configuration."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the parameter vector."));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "Whether the problem should be minimized or maximized."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("ImprovementAttempts", "The number of improvement attempts the operator should perform.", new IntValue(100)));
+      Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "The number of samples to draw from the neighborhood function at maximum.", new IntValue(300)));
+      Parameters.Add(new LookupParameter<IntValue>("LocalEvaluatedSolutions", "The number of solution evaluations that have been performed."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SingleObjectiveParameterVectorImprover(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var random = RandomParameter.ActualValue;
+      var host = ProblemDefinitionParameter.ActualValue;
+      if (host.Instance == null) throw new InvalidOperationException("Problem definition is not available.");
+      var config = ConfigurationParameter.ActualValue;
+      var maximize = MaximizationParameter.ActualValue.Value;
+      var maxAttempts = ImprovementAttemptsParameter.ActualValue.Value;
+      var sampleSize = SampleSizeParameter.ActualValue.Value;
+      var vector = Helper.Extract(ExecutionContext.Scope, config);
+      var quality = QualityParameter.ActualValue == null ? host.Instance.Evaluate(random, vector) : QualityParameter.ActualValue.Value;
+
+      var count = 0;
+      for (var i = 0; i < maxAttempts; i++) {
+        ParameterVector best = null;
+        var bestQuality = quality;
+        foreach (var neighbor in host.Instance.GetNeighbors(random, vector).Take(sampleSize)) {
+          var q = host.Instance.Evaluate(random, neighbor);
+          count++;
+          if (maximize && bestQuality > q || !maximize && bestQuality < q) continue;
+          best = neighbor;
+          bestQuality = q;
+        }
+        if (best == null) break;
+        vector = best;
+        quality = bestQuality;
+      }
+
+      LocalEvaluatedSolutionsParameter.ActualValue = new IntValue(count);
+      Helper.Write(ExecutionContext.Scope, vector);
+      return base.Apply();
+    }
+  }
+}
Index: branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/SingleObjectiveProgrammableProblem.cs
===================================================================
--- branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/SingleObjectiveProgrammableProblem.cs	(revision 11402)
+++ branches/ProgrammableProblem/HeuristicLab.Problems.Programmable/3.3/SingleObjectiveProgrammableProblem.cs	(revision 11405)
@@ -171,4 +171,5 @@
         UpdateMultiVectorEncodingOperators(solutionCreators, configuration);
       }
+      UpdateImprovementOperators();
       UpdateMoveOperators();
     }
@@ -852,4 +853,15 @@
     }
 
+    protected virtual void UpdateImprovementOperators() {
+      if (!Operators.Any(x => x is SingleObjectiveParameterVectorImprover))
+        Operators.Add(new SingleObjectiveParameterVectorImprover());
+      foreach (var improver in Operators.OfType<SingleObjectiveParameterVectorImprover>()) {
+        improver.ConfigurationParameter.ActualName = ConfigurationParameter.Name;
+        improver.MaximizationParameter.ActualName = MaximizationParameter.Name;
+        improver.ProblemDefinitionParameter.ActualName = ProblemDefinitionParameter.Name;
+        improver.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
+      }
+    }
+
     protected virtual void UpdateMoveOperators() {
       Operators.RemoveAll(x => x is IParameterVectorMoveOperator);
