예제 #1
0
            private static void rationalityConstrPlayer2(State s, Func <State, Action, Action, double> getQ, Dictionary <Tuple <Action, Action>, Decision> actDecisions, Model model, string constPrefix)
            {
                var rotList = new Queue <Action>();

                foreach (Action action in Enum.GetValues(typeof(Action)))
                {
                    rotList.Enqueue(action);
                }

                var cons_cnt = 0;

                for (var i = 0; i < Enum.GetValues(typeof(Action)).Length; ++i)
                {
                    var    constRowSum   = new SumTermBuilder(5);
                    var    isConstrow    = true;
                    Action contextAction = Action.N;

                    foreach (Action player2Action in rotList)
                    {
                        var otherRowSum = new SumTermBuilder(5);

                        if (isConstrow)
                        {
                            contextAction = player2Action;
                        }

                        foreach (Action currentAction in Enum.GetValues(typeof(Action)))
                        {
                            var policy = getActDecision(currentAction, contextAction, actDecisions);

                            if (isConstrow)
                            {
                                var qValue = getQ(s, currentAction, player2Action);

                                constRowSum.Add(policy * qValue);
                            }
                            else
                            {
                                var qValue = getQ(s, currentAction, player2Action);

                                otherRowSum.Add(policy * qValue);
                            }
                        }

                        if (!isConstrow)
                        {
                            model.AddConstraint(constPrefix + "const" + cons_cnt, constRowSum.ToTerm() >= otherRowSum.ToTerm());
                            cons_cnt++;
                        }

                        isConstrow = false;
                    }

                    //Rotate list
                    var elementToRotate = rotList.Dequeue();
                    rotList.Enqueue(elementToRotate);
                }
            }
예제 #2
0
파일: T2Logic.cs 프로젝트: Podlewski/TPD
        public static Tuple <double, List <double> > PlayerBStrategy(List <List <int> > matrix)
        {
            SolverContext context = SolverContext.GetContext();

            context.ClearModel();
            Model model = context.CreateModel();

            List <Decision> decicionList = new List <Decision>();

            for (int j = 0; j < matrix[0].Count; j++)
            {
                decicionList.Add(new Decision(Domain.RealNonnegative, "B" + j));
            }

            foreach (var decision in decicionList)
            {
                model.AddDecision(decision);
            }

            for (int i = 0; i < matrix.Count; i++)
            {
                SumTermBuilder rowSum = new SumTermBuilder(decicionList.Count);

                for (int j = 0; j < decicionList.Count; j++)
                {
                    rowSum.Add(decicionList[j] * matrix[i][j]);
                }

                model.AddConstraint("con" + i, rowSum.ToTerm() <= 1);
            }

            SumTermBuilder decisionSum = new SumTermBuilder(decicionList.Count);

            for (int j = 0; j < decicionList.Count; j++)
            {
                model.AddConstraint("nonneg" + j, decicionList[j] >= 0);
                decisionSum.Add(decicionList[j]);
            }

            model.AddGoal("max", GoalKind.Maximize, decisionSum.ToTerm());

            Solution solution = context.Solve(new SimplexDirective());

            double        gameValue          = 1 / solution.Goals.First().ToDouble();
            List <double> parsedDecicionList = new List <double>();

            foreach (var decision in decicionList)
            {
                parsedDecicionList.Add(decision.ToDouble() * gameValue);
            }

            return(new Tuple <double, List <double> >(gameValue, parsedDecicionList));
        }
예제 #3
0
            private static void ObjFunctermAdd(State s, CorrelatedQTable q, Dictionary <Tuple <Action, Action>, Decision> actDecisions, SumTermBuilder objectSum)
            {
                foreach (Action currentAction in Enum.GetValues(typeof(Action)))
                {
                    foreach (Action player2Action in Enum.GetValues(typeof(Action)))
                    {
                        var policy = getActDecision(currentAction, player2Action, actDecisions);
                        var qValue = q.getCurrPQvalue(s, currentAction, player2Action);

                        objectSum.Add(policy * qValue);
                    }
                }

                foreach (Action currentAction in Enum.GetValues(typeof(Action)))
                {
                    foreach (Action player2Action in Enum.GetValues(typeof(Action)))
                    {
                        var policy    = getActDecision(currentAction, player2Action, actDecisions);
                        var player2Qv = q.getPlayer2Qval(s, currentAction, player2Action);

                        objectSum.Add(policy * player2Qv);
                    }
                }
            }
예제 #4
0
        public SimplexMethod(double[,] table) : this()
        {
            M = table.GetLength(0);
            N = table.GetLength(1);
            var decisionsA = new Decision[M];

            ResultsA = new double[M];
            for (int i = 0; i < M; i++)
            {
                decisionsA[i] = new Decision(Domain.RealNonnegative, $"A{i}");
            }
            _model.AddDecisions(decisionsA);
            var decisionsB = new Decision[N];

            ResultsB = new double[N];
            for (int j = 0; j < N; j++)
            {
                decisionsB[j] = new Decision(Domain.RealNonnegative, $"B{j}");
            }
            _model.AddDecisions(decisionsB);
            for (int j = 0; j < N; j++)
            {
                var sum = new SumTermBuilder(M);
                for (int i = 0; i < M; i++)
                {
                    sum.Add(decisionsA[i] * table[i, j]);
                }
                _model.AddConstraint($"C_A{j}", sum.ToTerm() >= 1);
            }
            for (int i = 0; i < M; i++)
            {
                var sum = new SumTermBuilder(N);
                for (int j = 0; j < N; j++)
                {
                    sum.Add(decisionsB[j] * table[i, j]);
                }
                _model.AddConstraint($"C_B{i}", sum.ToTerm() <= 1);
            }
            var summinA = new SumTermBuilder(N);

            for (int i = 0; i < M; i++)
            {
                summinA.Add(decisionsA[i]);
            }
            _model.AddGoal("resA", GoalKind.Minimize, summinA.ToTerm());
            var summinB = new SumTermBuilder(N);

            for (int j = 0; j < N; j++)
            {
                summinB.Add(decisionsB[j]);
            }
            _model.AddGoal("resB", GoalKind.Maximize, summinB.ToTerm());
            _solver.Solve();
            var gpsumA = 0.0;

            for (int i = 0; i < M; i++)
            {
                ResultsA[i] = decisionsA[i].GetDouble();
                gpsumA     += ResultsA[i];
            }
            GamePriceA = 1 / gpsumA;
            var gpsumB = 0.0;

            for (int j = 0; j < N; j++)
            {
                ResultsB[j] = decisionsB[j].GetDouble();
                gpsumB     += ResultsB[j];
            }
            GamePriceB = 1 / gpsumB;
            _solver.ClearModel();
        }
예제 #5
0
            public static Tuple <double, double> GetValue(State s, CorrelatedQTable q)
            {
                var contxt = SolverContext.GetContext();

                contxt.ClearModel();
                var model = contxt.CreateModel();

                var actDecisions = new Dictionary <Tuple <Action, Action>, Decision>();

                foreach (Action currentAction in Enum.GetValues(typeof(Action)))
                {
                    foreach (Action player2Action in Enum.GetValues(typeof(Action)))
                    {
                        var decision = new Decision(Domain.RealNonnegative, currentAction.ToString() + player2Action.ToString());
                        model.AddDecisions(decision);
                        actDecisions.Add(new Tuple <Action, Action>(currentAction, player2Action), decision);
                    }
                }

                var actDecisionSum = new SumTermBuilder(25);

                foreach (var decision in actDecisions.Values)
                {
                    actDecisionSum.Add(decision);
                }

                model.AddConstraint("probSumConst", actDecisionSum.ToTerm() == 1.0);

                rationalconsts(s, q.getCurrPQvalue, actDecisions, model, "A");
                rationalityConstrPlayer2(s, q.getPlayer2Qval, actDecisions, model, "B");

                var objectSum = new SumTermBuilder(10);

                //Add my terms from my Q table to objective function
                ObjFunctermAdd(s, q, actDecisions, objectSum);

                model.AddGoal("MaximizeV", GoalKind.Maximize, objectSum.ToTerm());

                var sol = contxt.Solve(new SimplexDirective());



                if (sol.Quality != SolverQuality.Optimal)
                {
                    contxt.ClearModel();
                    return(new Tuple <double, double>(1.0, 1.0));
                }

                double Player1nextVal = 0.0;
                double Player2nextVal = 0.0;

                foreach (Action currentAction in Enum.GetValues(typeof(Action)))
                {
                    foreach (Action player2Action in Enum.GetValues(typeof(Action)))
                    {
                        var policy = getActDecision(currentAction, player2Action, actDecisions);
                        var qValue = q.getCurrPQvalue(s, currentAction, player2Action);
                        Player1nextVal += policy.ToDouble() * qValue;
                        var player2Qv = q.getPlayer2Qval(s, currentAction, player2Action);
                        Player2nextVal += policy.ToDouble() * player2Qv;
                    }
                }

                return(new Tuple <double, double>(Player1nextVal, Player2nextVal));
            }
예제 #6
0
            private static void AddObjectiveFunctionTerms(State s, CorrelatedQTable q, Dictionary <Tuple <Action, Action>, Decision> actionDecisions, SumTermBuilder objectiveSum)
            {
                foreach (Action currentAction in Enum.GetValues(typeof(Action)))
                {
                    foreach (Action opponentAction in Enum.GetValues(typeof(Action)))
                    {
                        var pi     = GetActionDecision(currentAction, opponentAction, actionDecisions);
                        var qValue = q.GetCurrentPlayerQValue(s, currentAction, opponentAction);

                        objectiveSum.Add(pi * qValue);
                    }
                }

                foreach (Action currentAction in Enum.GetValues(typeof(Action)))
                {
                    foreach (Action opponentAction in Enum.GetValues(typeof(Action)))
                    {
                        var pi             = GetActionDecision(currentAction, opponentAction, actionDecisions);
                        var opponentQValue = q.GetOpponentQValue(s, currentAction, opponentAction);

                        objectiveSum.Add(pi * opponentQValue);
                    }
                }
            }
예제 #7
0
            public static Tuple <double, double> GetValue(State s, CorrelatedQTable q)
            {
                var context = SolverContext.GetContext();

                context.ClearModel();
                var model = context.CreateModel();

                var actionDecisions = new Dictionary <Tuple <Action, Action>, Decision>();

                foreach (Action currentAction in Enum.GetValues(typeof(Action)))
                {
                    foreach (Action opponentAction in Enum.GetValues(typeof(Action)))
                    {
                        var decision = new Decision(Domain.RealNonnegative, currentAction.ToString() + opponentAction.ToString());
                        model.AddDecisions(decision);
                        actionDecisions.Add(new Tuple <Action, Action>(currentAction, opponentAction), decision);
                    }
                }

                var actionDecisionSum = new SumTermBuilder(25);

                foreach (var decision in actionDecisions.Values)
                {
                    actionDecisionSum.Add(decision);
                }

                model.AddConstraint("probSumConst", actionDecisionSum.ToTerm() == 1.0);

                SetupRationalityConstraints(s, q.GetCurrentPlayerQValue, actionDecisions, model, "A");
                SetupRationalityConstraintsOpponent(s, q.GetOpponentQValue, actionDecisions, model, "B");

                var objectiveSum = new SumTermBuilder(10);

                //Add my terms from my Q table to objective function
                AddObjectiveFunctionTerms(s, q, actionDecisions, objectiveSum);

                model.AddGoal("MaximizeV", GoalKind.Maximize, objectiveSum.ToTerm());

                var solution = context.Solve(new SimplexDirective());

                //Console.WriteLine(solution.GetReport());

                if (solution.Quality != SolverQuality.Optimal)
                {
                    context.ClearModel();
                    return(new Tuple <double, double>(1.0, 1.0));
                }

                double currentPlayerNextValue = 0.0;
                double opponentNextValue      = 0.0;

                foreach (Action currentAction in Enum.GetValues(typeof(Action)))
                {
                    foreach (Action opponentAction in Enum.GetValues(typeof(Action)))
                    {
                        var pi     = GetActionDecision(currentAction, opponentAction, actionDecisions);
                        var qValue = q.GetCurrentPlayerQValue(s, currentAction, opponentAction);
                        currentPlayerNextValue += pi.ToDouble() * qValue;
                        var opponentQValue = q.GetOpponentQValue(s, currentAction, opponentAction);
                        opponentNextValue += pi.ToDouble() * opponentQValue;
                    }
                }

                return(new Tuple <double, double>(currentPlayerNextValue, opponentNextValue));
            }
예제 #8
0
        private void InitializeConstraints(Project project, int eventCount)
        {
            // Establish the makespan: the maximum finish time over all activities.
            model.AddConstraint("c35",
                                Model.ForEach(events1ToN, e =>
                                              Model.ForEach(tasks, i =>
                                                            makespan >= start[e] + (isActive[i, e] - isActive[i, e - 1]) * duration[i])
                                              ));

            //   model.AddConstraint("ValidDeliveryDate",
            //   Model.ForEach(tasks, e => start[e] + duration[e] <= entrega[e]));

            //   model.AddConstraint("ModelSwitchPause", Model.ForEach(events1ToN, (t) =>
            // start[t] >= start[t - 1] + duration[t - 1] + Model.If(molde[t] != molde[t - 1], 1, 0)
            //));



            // The first event starts at time 0.
            model.AddConstraint("c_36", start[0] == 0);
            // Link the isActive decision to the starts of each event and task durations.
            model.AddConstraint("c_37",
                                Model.ForEach(events1ToN, e =>
                                              Model.ForEachWhere(events, f =>
                                                                 Model.ForEach(tasks, i =>
                                                                               start[f] >= start[e] + ((isActive[i, e] - isActive[i, e - 1]) - (isActive[i, f] - isActive[i, f - 1]) - 1) * duration[i]
                                                                               ), f => f > e)));

            // Link the isActive decision with the first event. This constraint is missing in the original
            // paper.
            model.AddConstraint("c_37_e0",
                                Model.ForEach(events1ToN, f =>
                                              Model.ForEach(tasks, i =>
                                                            start[f] >= start[0] + (isActive[i, 0] - (isActive[i, f] - isActive[i, f - 1]) - 1) * duration[i]
                                                            )));

            // Order the events.
            model.AddConstraint("c_38", Model.ForEach(events1ToN, e => start[e] >= start[e - 1]));

            // Ensure adjacency of events for an in-progress task.
            SumTermBuilder sum = new SumTermBuilder(eventCount);

            for (int i = 0; i < project.Tasks.Count; i++)
            {
                for (int e = 1; e < eventCount; e++)
                {
                    sum.Add(isActive[i, e - 1]);
                    model.AddConstraint("c_39_" + i + "_" + e,
                                        sum.ToTerm() <= e * (1 - (isActive[i, e] - isActive[i, e - 1])));
                }
                sum.Clear();
            }

            sum = new SumTermBuilder(eventCount);
            for (int i = 0; i < project.Tasks.Count; i++)
            {
                for (int e = 1; e < eventCount; e++)
                {
                    for (int e1 = e; e1 < eventCount; e1++)
                    {
                        sum.Add(isActive[i, e1]); // (it's inefficient to reconstruct this for each value of e.)
                    }
                    model.AddConstraint("c_40_" + i + "_" + e,
                                        sum.ToTerm() <= e * (1 + (isActive[i, e] - isActive[i, e - 1])));
                    sum.Clear();
                }
            }

            // All activities must be active during the project.
            model.AddConstraint("c_41", Model.ForEach(tasks, i =>
                                                      Model.Sum(Model.ForEach(events, e => isActive[i, e])) >= 1));

            // A link (i, j) means that the start of task j must be after the finish of task i.
            int c42 = 0;

            foreach (TaskDependency link in project.Dependencies)
            {
                int i = link.Source.ID;
                int j = link.Destination.ID;
                sum = new SumTermBuilder(eventCount);
                for (int e = 0; e < eventCount; e++)
                {
                    sum.Add(isActive[j, e]); // sum now has isActive[j, 0] .. isActive[j, e].
                    model.AddConstraint("c_42_" + c42++, isActive[i, e] + sum.ToTerm() <= 1 + e * (1 - isActive[i, e]));
                }
            }
            // Resource usage during each event must not exceed resource capacity.
            Dictionary <Resource, int> resToId = new Dictionary <Resource, int>(project.Resources.Count);

            for (int k = 0; k < project.Resources.Count; k++)
            {
                resToId[project.Resources[k]] = k;
            }
            SumTermBuilder[] totalResWork = new SumTermBuilder[project.Resources.Count];
            int c43 = 0;

            for (int e = 0; e < eventCount; e++)
            {
                for (int taskID = 0; taskID < project.Tasks.Count; taskID++)
                {
                    foreach (var assn in project.Tasks[taskID].Assignments)
                    {
                        int resID = resToId[assn.Resource];
                        if (totalResWork[resID] == null)
                        {
                            totalResWork[resID] = new SumTermBuilder(5); // most tasks will have <= 4 assignments.
                        }
                        totalResWork[resID].Add(assn.Units * isActive[taskID, e]);
                    }
                }

                for (int resID = 0; resID < totalResWork.Length; resID++)
                {
                    if (totalResWork[resID] != null)
                    {
                        model.AddConstraint("c43_" + c43++, totalResWork[resID].ToTerm() <= project.Resources[resID].MaxUnits);
                        totalResWork[resID] = null; // note: memory churn...
                    }
                }
            }
        }
        public Solution alternative_solve(out Dictionary <Models.Shift, Decision> shiftsN, out Dictionary <Models.Shift, Decision> shiftsO)
        {
            SolverContext SC    = SolverContext.GetContext();
            Model         model = SC.CreateModel();

            var maxRq = HalfHourRequirements.Max(x => x.RequiredForce);

            shiftsN = shiftsO = null;

            //split shifts into two Dictionaries (each dict holds each Shift as key and the Decision variable as Value)
            var normal_shifts = new Dictionary <Models.Shift, Decision>(); //for normal shifts
            int i             = 0;

            Shifts.ForEach(x => {
                Decision des = new Decision(Domain.IntegerRange(0, maxRq), string.Format("{0}_{1}", x.Name, i));
                normal_shifts.Add(x, des);
                model.AddDecision(des);
                i++;
            });

            var overtime_shifts = new Dictionary <Models.Shift, Decision>(); //for overtime shifts

            i = 0;
            OvertimeShifts.ForEach(x => {
                Decision des = new Decision(Domain.IntegerRange(0, maxRq), string.Format("{0}_{1}", x.Name, i));
                overtime_shifts.Add(x, des);
                model.AddDecision(des);
                i++;
            });

            List <Decision> excess = new List <Decision>(); //used to calculate sum of excess values

            HalfHourRequirements.ForEach(hh =>
            {
                var ShiftsActive = new List <Decision>();
                foreach (var entry in normal_shifts)
                {
                    if (entry.Key.IncludesHalfHour(hh.Start))
                    {
                        ShiftsActive.Add(entry.Value);
                        excess.Add(entry.Value);
                    }
                }
                foreach (var entry in overtime_shifts)
                {
                    if (entry.Key.IncludesHalfHour(hh.Start))
                    {
                        ShiftsActive.Add(entry.Value);
                        excess.Add(entry.Value);
                    }
                }

                //add constraint for sum of force of active shifts on that halfhour
                //if we need agents but no shifts exists for a halfhour, do not add a constraint
                if (ShiftsActive.Count > 0)
                {
                    var sum_constr = new SumTermBuilder(ShiftsActive.Count);
                    ShiftsActive.ForEach(s => sum_constr.Add(s));

                    var constr = sum_constr.ToTerm() >= hh.RequiredForce;
                    model.AddConstraint(string.Format("_{0:hh}{0:mm}", hh.Start), constr);

                    //constr = sum_constr.ToTerm() <= hh.RequiredForce * 2.0;
                    //model.AddConstraint(string.Format("limitconst_for_{0:hh}{0:mm}", hh.Start), constr);
                }
            });

            //Constrain maximum number of agents working 8hour shifts
            var max_agents_constraint = new SumTermBuilder(Shifts.Count);

            foreach (var entry in normal_shifts)
            {
                max_agents_constraint.Add(entry.Value);
            }
            var ma_constr = max_agents_constraint.ToTerm() <= MaxAgents;

            model.AddConstraint("Max_agents_constraint", ma_constr);

            //1st goal: Minimize overtime shifts (if work manageable by normal shifts, no overtime shifts will be used)
            var overtime_obj = new SumTermBuilder(OvertimeShifts.Count);

            foreach (var entry in overtime_shifts)
            {
                overtime_obj.Add(entry.Value);
            }
            model.AddGoal("Minimize_overtime", GoalKind.Minimize, overtime_obj.ToTerm());

            //2st goal: Minimize normal shifts
            var normal_obj = new SumTermBuilder(Shifts.Count);

            foreach (var entry in normal_shifts)
            {
                normal_obj.Add(entry.Value);
            }
            model.AddGoal("Minimize_normal", GoalKind.Minimize, normal_obj.ToTerm());

            //3rd goal: Try to minimize excess
            var sumReqs = HalfHourRequirements.Sum(x => x.RequiredForce);

            model.AddGoal("Minimize_excess", GoalKind.Minimize, Model.Sum(excess.ToArray()) - sumReqs);

            SimplexDirective simplex  = new SimplexDirective();
            Solution         solution = SC.Solve(simplex);

            shiftsN = normal_shifts;
            shiftsO = overtime_shifts;

            return(solution);
        }
예제 #10
0
 public static Term makeSum(int capacity, LoopSum sumDelegate)
 {
     var sum = new SumTermBuilder(capacity);
     sumDelegate(sum);
     return sum.ToTerm();
 }