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

namespace Algorithms.Nw.PathGenerationAllOds
{
    public class LinkEliminationThenPenalty : PathGenerationAllOdsAlgorithm
    {
        private ShortestPathAlgorithm spa;
        private double penalty;
        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 maxNbPaths, bool keepTime)
        {
            if (keepTime) { base.startTimer(); }

            base.odLstNodeIndices = new List<List<List<int>>>();
            for (int w = 0; w < graph.getNbOdPairs(); w++)
            {
                base.odLstNodeIndices.Add(new List<List<int>>());
                OdPair od = graph.getOdPair(w);
                int nbExistingPaths = od.getPathIndices().Length;
                if (maxNbPaths > nbExistingPaths)
                {
                    PathGeneration.LinkEliminationThenPenalty alg = new PathGeneration.LinkEliminationThenPenalty(spa, penalty, iterLim, perc);
                    alg.setExistingPathLabels(base.getExistingPathLabelsForOd(graph, w));
                    alg.run(graph, od.getOriIndex(), od.getDesIndex(), nbExistingPaths, maxNbPaths, false);
                    base.odLstNodeIndices[w] = alg.getPathsAsNodeIndicesList();
                }
            }
            if (keepTime) { base.stopTimer(); }
        }



    }
}
