using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EvoBoat.EvoAlg;
using EvoBoat.EvoAlg.ZOProg;

namespace KnapsackTest
{
    public class KnapsackProblem : ZeroOneProgProblem<VecSolution<BoolVector, bool>>
    {
        public int PenalWeight = 99999;

        protected int capacity;
        public int Capacity { get { return capacity; } }

        protected int[] weights;
        public int[] Weights { get { return weights; } }

        protected int[] profits;
        public int[] Profits { get { return profits; } } 
        protected int upper;       
        
        public KnapsackProblem(int capacity, int[] weights, int[] profits, double? optimum = null)
        {
            Name = "Knapsack";
            dimension = weights.Length;
            this.capacity = capacity;
            this.weights = weights;
            this.profits = profits;
            if (optimum == null)
                upper = profits.Sum();
            else
            {
                this.optimum = optimum;
                upper = (int)optimum;
            }
            this.Func = Evaluate;
        }

        public override double Evaluate(BoolVector x)
        {
            int ew = BoolVector.SumSel(x, weights) - capacity;
            return upper - BoolVector.SumSel(x, profits) + ((ew <= 0) ? 0 : PenalWeight * ew);
        }

        public override bool IsFeasible(BoolVector x)
        {
            return BoolVector.SumSel(x, weights) <= capacity;
        }
    }
}
