public static ZielonkaResult DetermineWinningRegions(ParityGraph graph) { var result = new ZielonkaResult(); if (graph.IsEmpty()) { return(result); } var vert = graph.NormalStructure.Values.Select(x => x.First()); var maxColor = vert.Max(x => x.Color); var satisfiedPlayer = maxColor % 2 == 0 ? Player.Good : Player.Bad; var notSatisfiedPlayer = satisfiedPlayer == Player.Good ? Player.Bad : Player.Good; var satisfingVert = vert.Where(x => x.Color == maxColor); var attractorOfSatisfingVert = CalculateAttractor(satisfingVert, graph, satisfiedPlayer); var recursiveZielonkaForSatisfied = DetermineWinningRegions(graph.MakeSubGame(attractorOfSatisfingVert)); if (!recursiveZielonkaForSatisfied.GetPlayersRegions(notSatisfiedPlayer).Any()) { result.SetPlayersRegions(satisfiedPlayer, attractorOfSatisfingVert.Union(recursiveZielonkaForSatisfied.GetPlayersRegions(satisfiedPlayer))); result.SetPlayersRegions(notSatisfiedPlayer, new List <Node>()); } else { var attractorOfNotSatisfiedVert = CalculateAttractor(recursiveZielonkaForSatisfied.GetPlayersRegions(notSatisfiedPlayer), graph, notSatisfiedPlayer); var recursiveZielonkaUnsatisfied = DetermineWinningRegions(graph.MakeSubGame(attractorOfNotSatisfiedVert)); result.SetPlayersRegions(satisfiedPlayer, recursiveZielonkaUnsatisfied.GetPlayersRegions(satisfiedPlayer)); result.SetPlayersRegions(notSatisfiedPlayer, recursiveZielonkaUnsatisfied.GetPlayersRegions(notSatisfiedPlayer).Union(attractorOfNotSatisfiedVert)); } return(result); }
internal ParityGraph MakeSubGame(HashSet <Node> attractorOfSatisfingVert) { var result = new ParityGraph(); var indexesToDel = new HashSet <int>(attractorOfSatisfingVert.Select(x => x.Index)); var newNormalStructure = new Dictionary <int, List <Node> >(); var newReversedStructure = new Dictionary <int, List <Node> >(); foreach (var key in NormalStructure.Keys) { if (!indexesToDel.Contains(key)) { newNormalStructure[key] = this.NormalStructure[key].Where(x => !attractorOfSatisfingVert.Contains(x)).ToList(); newReversedStructure[key] = this.ReversedStructure[key].Where(x => !attractorOfSatisfingVert.Contains(x)).ToList(); } } result.NormalStructure = newNormalStructure; result.ReversedStructure = newReversedStructure; return(result); }
static void Main(string[] args) { var basicInfo = Console.ReadLine().Split(' '); var n0 = int.Parse(basicInfo[0]); var n1 = int.Parse(basicInfo[1]); var m = int.Parse(basicInfo[2]); var graph = new ParityGraph(); for (var i = 0; i < n0; i++) { var vertexInfo = Console.ReadLine().Split(' '); graph.LoadVertexToGraph(int.Parse(vertexInfo[0]), int.Parse(vertexInfo[1]), Player.Good); } for (var i = 0; i < n1; i++) { var vertexInfo = Console.ReadLine().Split(' '); graph.LoadVertexToGraph(int.Parse(vertexInfo[0]), int.Parse(vertexInfo[1]), Player.Bad); } for (var i = 0; i < m; i++) { var edgeInfo = Console.ReadLine().Split(' '); graph.AddEgde(int.Parse(edgeInfo[0]), int.Parse(edgeInfo[1])); } var startingIndex = int.Parse(Console.ReadLine()); var startingNode = graph.NormalStructure[startingIndex].First(); var result = ZielonkaAlgorithm.DetermineWinningRegions(graph); //Console.WriteLine("\nPlayer 0 winning regions"); //foreach (var good in result.GoodWinningRegions) //{ // Console.WriteLine(good.Index); //} //Console.WriteLine("\nPlayer 1 winning regions"); //foreach (var bar in result.BadWinningRegions) //{ // Console.WriteLine(bar.Index); //} //Console.WriteLine("\nWinner is: "); Console.WriteLine(result.GoodWinningRegions.Contains(startingNode) ? "0" : "1"); //Console.ReadKey(); }
private static HashSet <Node> CalculateAttractorForSingleVert(Node vert, ParityGraph graph, Player player) { throw new NotImplementedException(); }
private static HashSet <Node> CalculateAttractor(IEnumerable <Node> satisfingVert, ParityGraph graph, Player player) { var nodesInAttractor = new HashSet <Node>(satisfingVert); bool fixedPoint = false; while (!fixedPoint) { var size = nodesInAttractor.Count; var tmpAttractor = new HashSet <Node>(nodesInAttractor); foreach (var vert in tmpAttractor) { var playersNeighbours = graph.ReversedStructure[vert.Index].Where(x => x.Owner == player); var enemiesNieghbours = graph.ReversedStructure[vert.Index].Where(x => x.Owner != player); //we add all of our nodes and the ones of our enemy that have no choice but to end in our attr vert nodesInAttractor.UnionWith(playersNeighbours); nodesInAttractor.UnionWith(enemiesNieghbours.Where(c => graph.NormalStructure[c.Index].Skip(1).All(z => nodesInAttractor.Contains(z)))); } fixedPoint = size == nodesInAttractor.Count; } return(nodesInAttractor); }