/// <summary>
 /// Deletes all runs associated with the specified journey.
 /// </summary>
 /// <param name="journey"></param>
 public void Clean(Journey journey)
 {
     journey.RunUuids = new string[0];
     string runsDir = string.Format("{0}\\{1}", this.directories[1], journey.Uuid);
     if (Directory.Exists(runsDir))
     {
         new DirectoryInfo(runsDir).Delete(true);
     }
 }
        public void TestSerialization()
        {
            Journey j = new Journey();
            j.ShortName = "Jeff";
            j.Description = "blah";

            j.RunUuids = new[] { "a", "b", "c" };
            var properties = j.Properties;
            var provider = new PtvDataProvider();
            ObjectCache.RegisterObject(provider);
            properties.NetworkDataProviders = new[] { provider };
            properties.PointDataProviders = new[] { new WalkingDataProvider() };
            properties.PopulationSize = 100;
            properties.DepartureTime = DateTime.Now;
            properties.MutationRate = 0.1;
            properties.CrossoverRate = 0.7;

            // properties.Bidirectional = bidir;
            // properties.RouteGenerator = new AlRouteGenerator(properties);
            properties.SearchType = SearchType.Greedy_BiDir;
            properties.RouteGenerator = new DFSRoutePlanner(properties);
            properties.Mutator = new StandardMutator(properties);
            properties.Breeder = new StandardBreeder(properties);
            properties.FitnessFunction = new AlFitnessFunction(properties);
            properties.Database = new MySqlDatabase("20110606fordistributionforrmit");
            properties.SearchType = SearchType.Greedy_BiDir;
            properties.Destination = new PtvNode(4, provider);
            properties.Origin = new PtvNode(4, provider);

            JourneyManager m = new JourneyManager();
            m.Add(j);
            m.Save();
            m = new JourneyManager();
            var j2 = m.GetJourney(j.Uuid);

            Assert.That(j.Uuid == j2.Uuid);
        }
 public string NewJourney(string shortName, string description)
 {
     Journey newJourney = new Journey();
     newJourney.ShortName = shortName;
     newJourney.Description = description;
     newJourney.Properties = new EvolutionaryProperties();
     var jm = ObjectCache.GetObject<JourneyManager>();
     jm.Add(newJourney);
     return newJourney.Uuid;
 }
        public void CloneJourney(string journeyUuid, string newUuid)
        {
            if (journeyUuid == null)
            {
                throw new Exception(Strings.ERR_ANY_NULL);
            }

            var jm = ObjectCache.GetObject<JourneyManager>();
            var j = jm.GetJourney(journeyUuid);
            var newJ = new Journey(newUuid, j.Properties, newUuid, "");
            jm.Add(newJ);
        }
        /// <summary>
        /// The set property.
        /// </summary>
        /// <param name="journey">
        /// The journey.
        /// </param>
        /// <param name="propVal">
        /// The prop val.
        /// </param>
        /// <param name="testOnly">
        /// The test only.
        /// </param>
        /// <returns>
        /// </returns>
        /// <exception cref="Exception">
        /// </exception>
        /// <exception cref="JsonException">
        /// </exception>
        /// <exception cref="JsonException">
        /// </exception>
        /// <exception cref="Exception">
        /// </exception>
        /// <exception cref="Exception">
        /// </exception>
        /// <exception cref="Exception">
        /// </exception>
        private ValidationError SetProperty(Journey journey, PropertyValue propVal, bool testOnly)
        {
            if (propVal.Name == null)
            {
                throw new Exception(
                    "Property value name is null. Cannot proceed with validation. Please check your JSON syntax.");
            }

            if (journey == null && !testOnly)
            {
                throw new JsonException("The journey UUID can only be null if the testOnly attribute is true.");
            }

            // var valErrors = new List<ValidationError>();
            //var jp = ObjectCache.GetObject<JourneyManager>();

            PropertyInfo[] propertyInfos = typeof(EvolutionaryProperties).GetProperties();
            EvolutionaryProperties properties;
            try
            {
                properties = journey.Properties;
            }
            catch (Exception)
            {
                throw new JsonException("The supplied journey UUID was incorrect.");
            }
            {
                // foreach (var propVal in propVals)
                var propertyInfo = propertyInfos.FirstOrDefault(s => s.Name == propVal.Name);

                if (propertyInfo == null)
                {
                    return new ValidationError { Target = propVal.Name, Message = Strings.ERR_PROP_NOT_FOUND };

                    // continue;
                }

                object castVal = null;
                string errMess = string.Empty;
                bool isList = false;
                bool isArray = false;

                if (propertyInfo.PropertyType.IsValueType)
                {
                    try
                    {
                        if (propertyInfo.PropertyType.IsEnum)
                        {
                            castVal = Enum.Parse(propertyInfo.PropertyType, propVal.Value);
                        }
                        else
                        {
                            castVal = Convert.ChangeType(propVal.Value, propertyInfo.PropertyType);
                        }
                    }
                    catch (Exception e)
                    {
                        errMess = e.Message;
                    }
                }
                else
                {
                    try
                    {
                        Type pType = propertyInfo.PropertyType;

                        switch (pType.Name)
                        {
                            case "INetworkNode":

                                if (propVal.Value == null)
                                {
                                    throw new Exception("This field cannot be blank.");
                                }

                                PtvDataProvider provider = ObjectCache.GetObjects<PtvDataProvider>()[0];
                                PtvNode node = null;
                                try
                                {
                                    node = (PtvNode)provider.GetNodeFromId(Convert.ToInt32(propVal.Value));
                                }
                                catch (KeyNotFoundException)
                                {
                                    throw new Exception("There is no such node with the given ID or name.");
                                }

                                    // provider.GetNodeFromName(propVal.Value);
                                if (node == null)
                                {
                                    throw new Exception("No matching node for supplied name.");
                                }

                                castVal = node;
                                break;

                            case "FitnessParameter[]":

                                var objs = propVal.Value.Split(new[] { ',' });
                                var objectives = new FitnessParameter[objs.Length];
                                int i = 0;
                                foreach (var obj in objs)
                                {
                                    FitnessParameter e;
                                    if (!Enum.TryParse(obj, out e))
                                    {
                                        throw new Exception("Cannot parse string into enum.");
                                    }

                                    objectives[i++] = e;
                                }

                                castVal = objectives;

                                break;
                            default:

                                // var pType = new;
                                if (pType.IsGenericType)
                                {
                                    if (pType.Name.Contains("List"))
                                    {
                                        pType = pType.GetGenericArguments()[0];
                                        isList = true;
                                    }
                                }

                                if (pType.IsArray)
                                {
                                    pType = pType.GetElementType();
                                    isArray = true;
                                }

                                try
                                {
                                    var types = Assembly.GetAssembly(pType).GetTypes();
                                    pType = types.Where(t => t.Name == propVal.Value).First();
                                }
                                catch (Exception)
                                {
                                    throw new Exception("Cannot find type in assembly. (" + propVal.Value + ")");
                                }

                                // var pType = Assembly.GetAssembly (propertyInfo.PropertyType).GetType(propVal.Value,true,true);
                                var objects = ObjectCache.GetObjects(pType);
                                if (objects.Length == 0)
                                {
                                    object newObj = null;
                                    try
                                    {
                                        // newObj = pType.InvokeMember("",BindingFlags.CreateInstance,null,null,new[] {properties});
                                        newObj = Activator.CreateInstance(pType, new[] { properties });
                                    }
                                    catch (Exception)
                                    {
                                        // newObj = pType.InvokeMember("",BindingFlags.CreateInstance,null,null,null);
                                        newObj = Activator.CreateInstance(pType);
                                    }

                                    ObjectCache.RegisterObject(newObj);
                                    castVal = newObj;
                                }
                                else
                                {
                                    castVal = objects.First();
                                }

                                if (isArray)
                                {
                                    var array = Array.CreateInstance(pType, 1);
                                    array.SetValue(castVal, 0);
                                    castVal = array;
                                }

                                break;

                                // throw new Exception("No handler for type: " + pType.Name);
                        }
                    }
                    catch (Exception e)
                    {
                        return new ValidationError
                            {
                                Target = propVal.Name,
                                Message = string.Format("{0}: {1}", Strings.ERR_UNSUPP_REFTYPE, e.Message)
                            };
                    }
                }

                if (castVal == null)
                {
                    // ERR_INVALID_CAST
                    return new ValidationError
                        {
                            Target = propVal.Name,
                            Message = string.Format("{0}: {1}", Strings.ERR_INVALID_CAST, errMess)
                        };

                    // continue;
                }

                if (!testOnly)
                {
                    if (isList)
                    {
                        IList a = (IList)propertyInfo.GetValue(properties, null);

                        a.Add(castVal);
                    }
                    else
                    {
                        propertyInfo.SetValue(properties, castVal, null);
                    }
                }
            }

            return new ValidationError { Target = propVal.Name, Message = Strings.VALIDATION_SUCCESS };
        }
 public ValidationError SetProperty(Journey journey, PropertyValue propVal)
 {
     return this.SetProperty(journey, propVal, false);
 }
        /// <summary>
        /// Called internally to process the journey optimisation queue.
        /// </summary>
        private void OptimisationLoop()
        {
            var detailedExportContext = JsonConvert.CreateExportContext();
            var summaryExportContext = JsonConvert.CreateExportContext();
            detailedExportContext.Register(new CritterExporter(CritterExporter.ExportType.Expanded));
            summaryExportContext.Register(new CritterExporter(CritterExporter.ExportType.Summary));
            {
                // try
                while (!this.cTokenSource.IsCancellationRequested)
                {
                    string jUuid = string.Empty;
                    Run run = null;
                    //try
                    {
                        this.currentIteration = 0;

                        this.state = OptimiserState.Waiting;
                        if (this.bc.Count == 0 && this.exitThreadWhenQueueEmpty)
                        {
                            return;
                        }

                        this.Save();

                        jUuid = this.bc.Take(this.cTokenSource.Token);
                        this.state = OptimiserState.Optimising;
                        run = new Run();

                        var journey = this.journeyManager.GetJourney(jUuid);
                        this.currentJourney = journey;
                        run.JourneyUuid = journey.Uuid;
                        run.TimeStarted = DateTime.Now;
                        var planner = new MoeaJourneyPlanner(journey.Properties);
                        var results = new List<Result>(journey.Properties.MaxIterations);
                        this.maxIterations = journey.Properties.MaxIterations;
                        planner.Start();

                        for (int i = 0; i < journey.Properties.MaxIterations; i++)
                        {
                            this.currentIteration++;
                            planner.SolveStep();
                            results.Add((Result)planner.IterationResult.Clone());
                            while (this.paused)
                            {
                                Thread.Sleep(100);
                            }

                            // results.Add(planner.re);
                            if (this.cTokenSource.IsCancellationRequested)
                            {
                                break;
                            }
                        }

                        run.TimeFinished = DateTime.Now;
                        var maxTT = results.Max(r => r.Population.Max(p => p.Fitness.TotalTravelTime)).TotalSeconds;
                        var minTT = results.Min(r => r.Population.Min(p => p.Fitness.TotalTravelTime)).TotalSeconds;
                        var maxJT = results.Max(r => r.Population.Max(p => p.Fitness.TotalJourneyTime)).TotalSeconds;
                        var minJT = results.Min(r => r.Population.Min(p => p.Fitness.TotalJourneyTime)).TotalSeconds;
                        var maxCh = results.Max(r => r.Population.Max(p => p.Fitness.Changes));
                        var minCh = results.Min(r => r.Population.Min(p => p.Fitness.Changes));

                        foreach (var result in results)
                        {
                            foreach (var p in result.Population)
                            {
                                p.Fitness.NormalisedChanges = Math.Min(
                                    1.0f, p.Fitness.Changes / (double)(maxCh - minCh));
                                p.Fitness.NormalisedJourneyTime = Math.Max(
                                    1.0f, p.Fitness.TotalJourneyTime.TotalSeconds / (maxJT - minJT));
                                p.Fitness.NormalisedTravelTime = Math.Max(
                                    1.0f, p.Fitness.TotalTravelTime.TotalSeconds / (maxTT - minTT));
                            }
                        }

                        if (!this.cTokenSource.IsCancellationRequested)
                        {
                            lock (journey.RunUuids)
                            {
                                // TODO: Make this more efficient/better coded
                                var newList = new List<string>(journey.RunUuids);
                                newList.Add(run.Uuid);
                                journey.RunUuids = newList.ToArray();

                                string dir = this.directories[1] + "/" + journey.Uuid + "/";
                                Directory.CreateDirectory(dir + run.Uuid);
                                using (var resultWriter = new StreamWriter(dir + run.Uuid + "/results.csv", false))
                                {
                                    resultWriter.Write("Iteration,Hypervolume,Cardinality,");
                                    foreach (var p in Enum.GetValues(typeof(FitnessParameter)))
                                    {
                                        resultWriter.Write("{0}, ", p);
                                    }

                                    resultWriter.WriteLine();

                                    for (int i = 0; i < results.Count; i++)
                                    {
                                        using (
                                            var writer = new StreamWriter(dir + run.Uuid + "/iteration." + i + ".json"))
                                        {
                                            results[i].Hypervolume = 0.0;

                                            /*results[i].Population.CalculateHyperVolume(
                                                journey.Properties.Objectives,
                                                new double[journey.Properties.Objectives.Length]);*/
                                            var grouped = from p in results[i].Population
                                                          group p by p.Route
                                                              into g
                                                              select g;

                                            var candidates = new List<Critter>();
                                            foreach (var g in grouped)
                                            {
                                                TimeSpan minTime = TimeSpan.MaxValue;
                                                Critter minCrit = null;

                                                foreach (var critter in g)
                                                {
                                                    if (critter.Fitness.TotalJourneyTime < minTime)
                                                    {
                                                        minTime = critter.Fitness.TotalJourneyTime;
                                                        minCrit = critter;
                                                    }
                                                }

                                                candidates.Add(minCrit);
                                            }
                                            var groupedResult = (Result)results[i].Clone(true);
                                            groupedResult.Population = new Population(candidates.OrderBy(c => c.Fitness.TotalJourneyTime));

                                            detailedExportContext.Export(groupedResult, new JsonTextWriter(writer));
                                            resultWriter.Write(
                                                "{0}, {1}, {2}, ", i, results[i].Hypervolume, results[i].Cardinality);
                                            foreach (var p in Enum.GetValues(typeof(FitnessParameter)))
                                            {
                                                resultWriter.Write(
                                                    "{0},",
                                                    results[i].Population.Average(c => c.Fitness[(FitnessParameter)p]));
                                            }

                                            resultWriter.WriteLine();
                                        }

                                        // For the last result entry, Save simplified file.
                                        if (i != results.Count - 1)
                                        {
                                            continue;
                                        }

                                        using (var writer = new StreamWriter(dir + run.Uuid + "/simple.json"))
                                        {
                                            using (var jsonWriter = new JsonTextWriter(writer))
                                            {
                                                var grouped = from p in results[i].Population
                                                              group p by p.Route
                                                              into g
                                                              select g;

                                                var candidates = new List<Critter>();
                                                foreach (var g in grouped)
                                                {
                                                    TimeSpan minTime = TimeSpan.MaxValue;
                                                    Critter minCrit = null;

                                                    foreach (var critter in g)
                                                    {
                                                        if (critter.Fitness.TotalJourneyTime < minTime)
                                                        {
                                                            minTime = critter.Fitness.TotalJourneyTime;
                                                            minCrit = critter;
                                                        }
                                                    }

                                                    candidates.Add(minCrit);
                                                }
                                                summaryExportContext.Export(candidates.OrderBy(c => c.Fitness.TotalJourneyTime), jsonWriter);
                                            }
                                        }
                                    }

                                    using (var writer = new StreamWriter(dir + run.Uuid + ".json"))
                                    {
                                        detailedExportContext.Export(run, new JsonTextWriter(writer));
                                    }

                                    results.Clear();
                                }
                            }

                            this.journeyManager.Save();
                        }

                        this.currentJourney = null;
                        this.currentIteration = 0;
                        this.maxIterations = 0;
                    }
                    /*
                    catch (Exception e)
                    {
                        StreamWriter logWriter = new StreamWriter("Log.txt");
                        logWriter.WriteLine(
                            "Exception: {0} jUUID: {1}, rUUID{2}, ST {3}\n\n",
                            e.Message,
                            jUuid,
                            (run ?? new Run { ErrorCode = -1, JourneyUuid = jUuid }).Uuid,
                            e.StackTrace);
                        logWriter.Close();

                        // throw;
                    }
                     */
                }
            }

            /*
            catch (Exception e)
            {
                //this.thrownException = e;
                throw;
            }
            finally
            {
                this.state = OptimiserState.Idle;
            }
             * */
        }
        public void Remove(Journey journey)
        {
            if (!bc.Contains(journey.Uuid))
                return;

            this.Pause();

            var journeys = new List<string>(bc.Count);
            while (bc.Count > 0)
            {
                journeys.Add(bc.Take());
            }

            foreach (String j in journeys)
            {
                if (j != journey.Uuid)
                {
                    bc.Add(j);
                }
            }

            this.Resume();
        }
 /// <summary>
 /// Enqueues the journey in the optimisation queue.
 /// </summary>
 /// <param name="journey">
 /// The journey you wish to enqueue.
 /// </param>
 /// <param name="runs">
 /// The amount of times to add the journey to the queue.
 /// </param>
 public void EnqueueJourney(Journey journey, int runs)
 {
     EnqueueJourney(journey.Uuid, runs);
 }
 /// <summary>
 /// Returns if this journey manager contains a journey with 
 /// a matching UUID to the specified journey.
 /// </summary>
 /// <param name="journey">The journey which is used for comparison.</param>
 /// <returns>True if the UUIDs match, otherwise false.</returns>
 public bool Contains(Journey journey)
 {
     return this.journeyMap.ContainsKey(journey.Uuid);
 }
 /// <summary>
 /// Add the specified journey to the manager.
 /// </summary>
 /// <param name="journey">
 /// The journey that is to be added to the manager.
 /// </param>
 public void Add(Journey journey)
 {
     this.journeyMap.Add(journey.Uuid, journey);
 }