Exemplo n.º 1
0
        public List <Edge> FindStrictPath(BotTerritory a, BotTerritory b, Dictionary <TerritoryIDType, EdgeHashSet> residual)
        {
            var bestPath = new List <Edge>();
            var visited  = new EdgeHashSet();

            foreach (var path in residual[Start.ID])
            {
                if (path.RemainingFlow() > 0)
                {
                    var candidate = FindStrictPathWithStart(path, visited, residual);
                    if (bestPath.Count == 0 || Eval == null || candidate.Count > 2 && Eval.Compare(candidate[candidate.Count - 2], bestPath[bestPath.Count - 2]) < 0)
                    {
                        bestPath = candidate;
                    }
                }
            }
            return(bestPath);
        }
Exemplo n.º 2
0
        public Dictionary <TerritoryIDType, EdgeHashSet> CreateResidual()
        {
            var residual = new Dictionary <TerritoryIDType, EdgeHashSet>();

            foreach (var key in AdjacencyList.Keys)
            {
                residual[key] = new EdgeHashSet(AdjacencyList[key].Values);
            }
            foreach (var attacker in Attackers)
            {
                var attackerEdges = residual[attacker];
                foreach (var forward in attackerEdges)
                {
                    var backward = new Edge(forward.End, forward.Start, forward.Capacity, forward.IsStrict);
                    backward.Flow = backward.Capacity;
                    residual[backward.Start.ID].Add(backward);
                }
            }
            return(residual);
        }
Exemplo n.º 3
0
        //public void ClearIntermediateEdges()
        //{
        //    foreach (var r in Attackers)
        //        AdjacencyList[r].Clear();
        //    foreach (var r_1 in Targets)
        //    {
        //        var edges = AdjacencyList[r_1];
        //        foreach (var e in edges.Values)
        //            if (e.End.ID != End.ID)
        //                edges.Remove(e.ID);
        //    }
        //}

        public EdgeHashSet GenerateStrictFlow()
        {
            var residual    = CreateResidual();
            var resourceMap = new Dictionary <TerritoryIDType, Edge>();

            foreach (var e in residual[Start.ID])
            {
                resourceMap[e.End.ID] = e;
            }
            var path = FindStrictPath(Start, End, residual);

            while (path.Count > 0)
            {
                var bottleneck = path[0].RemainingFlow();
                foreach (var e_1 in path)
                {
                    if (e_1.RemainingFlow() < bottleneck)
                    {
                        bottleneck = e_1.RemainingFlow();
                    }
                }
                SendFlow(path, residual);
                path = FindStrictPath(Start, End, residual);
            }
            var result = new EdgeHashSet();

            foreach (var attacker in Attackers)
            {
                foreach (var e_1 in residual[attacker])
                {
                    if (e_1.Flow > 0)
                    {
                        result.Add(e_1);
                    }
                }
            }
            return(result);
        }
Exemplo n.º 4
0
        public List <Edge> FindStrictPathWithStart(Edge startEdge, EdgeHashSet visited, Dictionary <TerritoryIDType, EdgeHashSet> residual)
        {
            var resourceMap = new Dictionary <TerritoryIDType, int>();

            foreach (var entryPoint in residual[Start.ID])
            {
                resourceMap[entryPoint.End.ID] = entryPoint.RemainingFlow();
            }
            var discoveredMap = new Dictionary <string, Edge>();
            var pushFlow      = startEdge.RemainingFlow();
            var bestpath      = new List <Edge>();
            var stack         = new Stack <Edge>();

            stack.Push(startEdge);
            while (stack.Count > 0)
            {
                var curr        = stack.Pop();
                var workingFlow = pushFlow;
                if (!IsPositive(curr) && curr.Start.ID != startEdge.End.ID)
                {
                    workingFlow += resourceMap[curr.Start.ID];
                }
                if (visited.Contains(curr))
                {
                    continue;
                }
                if (curr.RemainingFlow() == 0)
                {
                    continue;
                }
                if (!IsPositive(curr) && curr.RemainingFlow() > workingFlow)
                {
                    continue;
                }
                if (!IsPositive(curr))
                {
                    pushFlow = curr.RemainingFlow();
                }
                if (curr.End.ID == End.ID)
                {
                    var candidate = new List <Edge>();
                    var temp      = curr;
                    while (temp != null)
                    {
                        candidate.Insert(0, temp);
                        temp = discoveredMap.GetOr(temp.ID, null);
                    }
                    if (candidate.Count > 2)
                    {
                        if (bestpath.Count == 0 || Eval == null || Eval.Compare(candidate[candidate.Count - 2], bestpath[bestpath.Count - 2]) < 0)
                        {
                            bestpath = candidate;
                        }
                    }
                }
                else
                {
                    visited.Add(curr);
                    var edges = new List <Edge>(residual[curr.End.ID]);
                    if (IsPositive(curr) && Eval != null)
                    {
                        edges.Sort(Eval);
                    }
                    for (var i = edges.Count - 1; i >= 0; i--)
                    {
                        var neighbor = edges[i];
                        if (!visited.Contains(neighbor))
                        {
                            stack.Push(neighbor);
                            discoveredMap[neighbor.ID] = curr;
                        }
                    }
                }
            }
            return(bestpath);
        }