private static void AddMessagingConstraints(List <InternodeMessage> messages, Solver.IModel solverModel, Dictionary <A.Message, MessageDecision> msgDecisions, Dictionary <NodeId, NodeDecision> nodeDecisions)
        {
            Func <A.Message, Expr> getTerm = m =>
            {
                Expr ret = new TermExpr()
                {
                    Variable = nodeDecisions[m.Node.NodeId].Decision
                };
                for (; m != null; m = m.Prev)
                {
                    MessageDecision d;
                    if (msgDecisions.TryGetValue(m, out d))
                    {
                        ret = new OperatorExpr()
                        {
                            Op    = OperatorExpr.OpType.Sub,
                            Left  = ret,
                            Right = new TermExpr()
                            {
                                Variable = d.Decision
                            }
                        }
                    }
                    ;
                }
                return(ret);
            };

            foreach (var message in messages)
            {
                var toNodeDecision   = getTerm(message.IncomingMessage);
                var fromNodeDecision = getTerm(message.OutgoingMessage);

                solverModel.AddConstraints(
                    SolverUtils.MakeValidSolverIdentifierFromString("MessageConstraint_" + message.Id),
                    new OperatorExpr()
                {
                    Op   = OperatorExpr.OpType.Get,
                    Left = new OperatorExpr()
                    {
                        Op    = OperatorExpr.OpType.Sub,
                        Left  = toNodeDecision,
                        Right = fromNodeDecision,
                    },
                    Right = new ConstantExpr()
                    {
                        Value = (message.FromTimestamp - message.ToTimestamp).Ticks + 1
                    }
                }
                    );
                nodeDecisions[message.IncomingMessage.Node.NodeId].UsedInConstraint();
                nodeDecisions[message.OutgoingMessage.Node.NodeId].UsedInConstraint();
            }
        }
 private static void AddGoals(IDictionary <NodeId, NodeDecision> nodeDecisions, Solver.IModel solverModel)
 {
     foreach (var nodeDecision in nodeDecisions.Values)
     {
         solverModel.SetMinimizeGoal(
             nodeDecisions.Values.Select(d => d.Decision).ToArray()
             );
     }
 }
 private static void AddGoals(Solver.IModel solverModel, Dictionary <A.Message, MessageDecision> msgDecisions)
 {
     solverModel.SetMinimizeGoal(
         msgDecisions.Values.Select(d => d.Decision).ToArray()
         );
 }
Beispiel #4
0
        public static void AddUnboundNodesConstraints(
            InternodeMessagesMap map,
            IDictionary <NodeId, NodeDecision> nodeDecisions,
            Solver.IModel solverModel)
        {
            for (int i = 0; i < map.NodeIndexes.Count; ++i)
            {
                for (int j = 0; j < map.NodeIndexes.Count; ++j)
                {
                    if (i > j && (map.Map[i, j] != 0) != (map.Map[j, i] != 0))                     // if all internode messages between nodes i and j flow in one direction
                    {
                        var n1 = map.Nodes[i];
                        var n2 = map.Nodes[j];

                        // find the least "steep" internode message
                        var message =
                            n1.Messages
                            .Where(m => m.InternodeMessage != null && m.InternodeMessage.GetOppositeMessage(m).Node == n2)
                            .Where(m => !(m.InternodeMessage.OutgoingMessage.Event is ResponselessNetworkMessageEvent))
                            .Select(m => m.InternodeMessage)
                            .Aggregate(new { D = TimeSpan.MaxValue, M = (InternodeMessage)null }, (rslt, m) =>
                        {
                            var d = m.FromTimestamp - m.ToTimestamp;
                            return(d < rslt.D ? new { D = d, M = m } : rslt);
                        }, rslt => rslt.M);
                        if (message == null)
                        {
                            continue;
                        }

                        // add the constraint that emulates instantaneous response to the found message.
                        // this allows finding solution for the two nodes that would be impossible otherwise.
                        var toNodeDecision   = nodeDecisions[message.To.NodeId];
                        var fromNodeDecision = nodeDecisions[message.From.NodeId];
                        solverModel.AddConstraints(
                            SolverUtils.MakeValidSolverIdentifierFromString(message.Id) + "_reverse",
                            new OperatorExpr()
                        {
                            Op   = OperatorExpr.OpType.Get,
                            Left = new OperatorExpr()
                            {
                                Op   = OperatorExpr.OpType.Sub,
                                Left = new TermExpr()
                                {
                                    Variable = fromNodeDecision.Decision
                                },
                                Right = new TermExpr()
                                {
                                    Variable = toNodeDecision.Decision
                                }
                            },
                            Right = new ConstantExpr()
                            {
                                Value = (message.ToTimestamp - message.FromTimestamp).Ticks - 1
                            }
                        }
                            );
                    }
                }
            }
        }
 private static void AddMessagingConstraints(List <InternodeMessage> messages, IDictionary <NodeId, NodeDecision> nodeDecisions, Solver.IModel solverModel)
 {
     foreach (var message in messages)
     {
         var toNodeDecision   = nodeDecisions[message.To.NodeId];
         var fromNodeDecision = nodeDecisions[message.From.NodeId];
         solverModel.AddConstraints(
             SolverUtils.MakeValidSolverIdentifierFromString(message.Id),
             new OperatorExpr()
         {
             Op   = OperatorExpr.OpType.Get,
             Left = new OperatorExpr()
             {
                 Op   = OperatorExpr.OpType.Sub,
                 Left = new TermExpr()
                 {
                     Variable = toNodeDecision.Decision,
                 },
                 Right = new TermExpr()
                 {
                     Variable = fromNodeDecision.Decision,
                 },
             },
             Right = new ConstantExpr()
             {
                 Value = (message.FromTimestamp - message.ToTimestamp).Ticks + 1
             }
         }
             );
         toNodeDecision.UsedInConstraint();
         fromNodeDecision.UsedInConstraint();
     }
 }
Beispiel #6
0
 public static void AddFixedConstraints(List <NodesConstraint> fixedConstraints, IDictionary <NodeId, NodeDecision> nodeDecisions, Solver.IModel solverModel)
 {
     foreach (var constraint in fixedConstraints)
     {
         var toNodeDecision   = nodeDecisions[constraint.Node1];
         var fromNodeDecision = nodeDecisions[constraint.Node2];
         solverModel.AddConstraints(
             SolverUtils.MakeValidSolverIdentifierFromString(string.Format("fixed-diff-{0}-{1}", constraint.Node1, constraint.Node2)),
             new OperatorExpr()
         {
             Op   = OperatorExpr.OpType.Eq,
             Left = new OperatorExpr()
             {
                 Op   = OperatorExpr.OpType.Sub,
                 Left = new TermExpr()
                 {
                     Variable = toNodeDecision.Decision
                 },
                 Right = new TermExpr()
                 {
                     Variable = fromNodeDecision.Decision
                 },
             },
             Right = new ConstantExpr()
             {
                 Value = constraint.Value.Ticks
             }
         }
             );
         toNodeDecision.UsedInConstraint();
         fromNodeDecision.UsedInConstraint();
     }
 }
Beispiel #7
0
        public static void AddIsolatedRoleInstancesConstraints(
            InternodeMessagesMap map,
            IDictionary <NodeId, NodeDecision> nodeDecisions,
            HashSet <string> allowedRoles,
            Solver.IModel solverModel)
        {
            var handledBadDomains = new HashSet <ISet <int> >();

            foreach (var roleGroup in map.NodeIndexes
                     .Where(x => allowedRoles.Contains(x.Key.NodeId.Role))
                     .GroupBy(x => x.Key.NodeId.Role))
            {
                // domain -> [{node, node index}]  where all nodes are instances of to one role
                var domainGroups = roleGroup
                                   .GroupBy(inst => map.NodeDomains[inst.Value])
                                   .ToDictionary(domainGroup => domainGroup.Key, domainGroup => domainGroup.ToList());

                // skip the role if all instances of it belong to one domain
                if (domainGroups.Count < 2)
                {
                    continue;
                }

                // good is the domain that consists of more than one node
                var goodDomain = domainGroups.FirstOrDefault(d => d.Key.Count > 1);
                if (goodDomain.Key == null)
                {
                    continue;
                }

                foreach (var badDomain in domainGroups
                         .Where(d => d.Key.Count == 1)
                         .Where(d => !handledBadDomains.Contains(d.Key)))
                {
                    var goodDomainDecision = nodeDecisions[goodDomain.Value[0].Key.NodeId];
                    var badDomainDecision  = nodeDecisions[badDomain.Value[0].Key.NodeId];
                    solverModel.AddConstraints(
                        "isolated_domain_link_" + SolverUtils.MakeValidSolverIdentifierFromString(string.Join("_", badDomain.Key)),
                        new OperatorExpr()
                    {
                        Op   = OperatorExpr.OpType.Eq,
                        Left = new OperatorExpr()
                        {
                            Op   = OperatorExpr.OpType.Sub,
                            Left = new TermExpr()
                            {
                                Variable = goodDomainDecision.Decision
                            },
                            Right = new TermExpr()
                            {
                                Variable = badDomainDecision.Decision
                            }
                        },
                        Right = new ConstantExpr()
                        {
                            Value = 0
                        }
                    }
                        );
                    handledBadDomains.Add(badDomain.Key);
                }
            }
            ;
        }
Beispiel #8
0
 public MessageDecision(Solver.IModel model, A.Message m) : base(model, "MessageDecision_" + m.Key.ToString())
 {
     this.Message = m;
 }
Beispiel #9
0
 public NodeDecision(Solver.IModel model, Node n) : base(model, "NodeDecision_" + n.NodeId.ToString())
 {
     this.Node = n;
 }
Beispiel #10
0
 public DecisionBase(Solver.IModel model, string decisionName)
 {
     this.Decision = model.CreateDecision(SolverUtils.MakeValidSolverIdentifierFromString(decisionName));
 }