using Algorithms.Nw.ShortestPath;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using U.Graph;

namespace Algorithms.Nw.PathGeneration
{
    public class LinkEliminationThenPenalty : PathGenerationAlgorithm
    {
        private ShortestPathAlgorithm spa;
        private double penalty; // if 0.05 means that fftt of 100 will be 105
        private long iterLim;
        private double perc;
        public LinkEliminationThenPenalty(ShortestPathAlgorithm shortestPathAlgorithm, double penalty, long iterationLimitForPenaltyAlgorithm, double percOfPathsForFirstMethod)
        {
            this.spa = shortestPathAlgorithm;
            this.penalty = penalty;
            this.iterLim = iterationLimitForPenaltyAlgorithm;
            this.perc = Math.Min(1.0, percOfPathsForFirstMethod);
        }



        public override void run(Graph graph, int oriIndex, int desIndex, int nbExistingPaths, int maxNbPaths, bool keepTime)
        {
            if (keepTime) { base.startTimer(); }
            base.lstNodeIndices = new List<List<int>>();
            if (nbExistingPaths >= maxNbPaths) { return; }
            int nbPathsToGenerate = maxNbPaths - nbExistingPaths;
            int firstMethodLimit = Convert.ToInt16(Math.Round(maxNbPaths * perc, 0));

            LinkElimination first = new LinkElimination(spa);
            first.setExistingPathLabels(existingPathLabels);
            first.run(graph, oriIndex, desIndex, nbExistingPaths, firstMethodLimit, false);
            base.lstNodeIndices.AddRange(first.getPathsAsNodeIndicesList());

            LinkPenalty second = new LinkPenalty(spa, penalty, iterLim);
            second.setExistingPathLabels(first.existingPathLabels);
            second.run(graph, oriIndex, desIndex, nbExistingPaths + base.lstNodeIndices.Count, maxNbPaths - base.lstNodeIndices.Count, false);
            base.lstNodeIndices.AddRange(second.getPathsAsNodeIndicesList());

            if (keepTime) { stopTimer(); }
        }
    }
}
