/// <summary> /// Generates a LexFS ordering of G used to find a path /// Used for finding an circle if G is not chordal /// </summary> /// <param name="triple">A triple containing u, v and w</param> /// <returns>An ordering leading to a path from v to w avoiding u</returns> private Person[] LexBFSFindAPath(Person[] triple) { //Initialize data structures LinkedList <SetList <Person> > listOfSets = new LinkedList <SetList <Person> >(); Dictionary <Person, LinkedListNode <SetList <Person> > > setPointers = new Dictionary <Person, LinkedListNode <SetList <Person> > >(); Dictionary <Person, LinkedListNode <Person> > positionPointers = new Dictionary <Person, LinkedListNode <Person> >(); //Set that have to be unflagged after the iteration List <LinkedListNode <SetList <Person> > > setsToCheck = new List <LinkedListNode <SetList <Person> > >(); Person[] outputArray = new Person[this.Persons.Count]; //Set for all node without N(u)\{v,w}; w is at the first position SetList <Person> firstSet = new SetList <Person>(); listOfSets.AddFirst(firstSet); //Set for N(u)\{v,w}; after the first set -> gets labeled last SetList <Person> secondSet = new SetList <Person>(); listOfSets.AddFirst(secondSet); //Adds w so w gets labeled first positionPointers[triple[2]] = firstSet.AddFirst(triple[2]); setPointers[triple[2]] = listOfSets.Last; //Adds v separately positionPointers[triple[1]] = firstSet.AddLast(triple[1]); setPointers[triple[1]] = listOfSets.Last; //Set origin distance triple[2].Distance = 0; //Add N(u)\{v,w} foreach (Person person in triple[0].Neighbors) { if (person != triple[1] || person != triple[2]) { positionPointers[person] = secondSet.AddFirst(person); setPointers[person] = listOfSets.First; } } //Add u positionPointers[triple[0]] = secondSet.AddFirst(triple[0]); setPointers[triple[0]] = listOfSets.First; //Get all persons ready foreach (Person person in Persons) { person.Position = -1; //Don't add neighbors of u, u, v or w if (!setPointers.ContainsKey(person)) { positionPointers[person] = firstSet.AddLast(person); setPointers[person] = listOfSets.Last; } } //Label all persons for (int i = 0; i < Persons.Count; i++) { //Select current person for labeling and remove it from its set Person currentPerson = listOfSets.Last.Value.First.Value; listOfSets.Last.Value.RemoveFirst(); positionPointers.Remove(currentPerson); //Remove set if empty if (listOfSets.Last.Value.Count == 0) { listOfSets.Remove(listOfSets.Last); } //Assign label currentPerson.Position = i; outputArray[i] = currentPerson; //Assign new sets to all neighbors foreach (Person neighbor in currentPerson.Neighbors) { //Ignore labeled neighbors if (neighbor.Position == -1) { //Get current set of neighbor LinkedListNode <SetList <Person> > currentSet = setPointers[neighbor]; //If currentSet has no replacement generate replacement set generate one if (!currentSet.Value.HasReplacement) { currentSet.Value.HasReplacement = true; SetList <Person> newSet = new SetList <Person>(); listOfSets.AddAfter(currentSet, newSet); setsToCheck.Add(currentSet); } //Put neighbor in a set one level higher currentSet.Value.Remove(positionPointers[neighbor]); setPointers[neighbor] = currentSet.Next; positionPointers[neighbor] = currentSet.Next.Value.AddLast(neighbor); //Set distance of current neighbor neighbor.Distance = currentPerson.Distance + 1; } } //Unflag all previously flagged set and delete them if empty foreach (LinkedListNode <SetList <Person> > setList in setsToCheck) { if (setList.Value.Count == 0) { listOfSets.Remove(setList); } else { setList.Value.HasReplacement = false; } } setsToCheck.Clear(); } return(outputArray); }
/// <summary> /// Perform an LexBFS ordering on G /// </summary> /// <param name="direction">Direction of the ordering (forwards/backwards)</param> /// <returns>An order of G</returns> private Person[] LexBFS(Direction direction) { //Initialize data structures LinkedList <SetList <Person> > listOfSets = new LinkedList <SetList <Person> >(); Dictionary <Person, LinkedListNode <SetList <Person> > > setPointers = new Dictionary <Person, LinkedListNode <SetList <Person> > >(); Dictionary <Person, LinkedListNode <Person> > positionPointers = new Dictionary <Person, LinkedListNode <Person> >(); //Set that have to be unflagged after the iteration List <LinkedListNode <SetList <Person> > > setsToCheck = new List <LinkedListNode <SetList <Person> > >(); Person[] outputArray = new Person[this.Persons.Count]; //Generate first set (represents all persons without label) SetList <Person> firstSet = new SetList <Person>(); listOfSets.AddFirst(firstSet); //Get all persons ready foreach (Person person in Persons) { person.Position = -1; positionPointers[person] = firstSet.AddLast(person); setPointers[person] = listOfSets.First; } //Determine startindex depending on direction int i = (direction == Direction.Backwards ? this.Persons.Count - 1 : 0); //Label all persons while (direction == Direction.Backwards ? i >= 0 : i < this.Persons.Count) { //Select current person for labeling and remove it from its set Person currentPerson = listOfSets.Last.Value.First.Value; positionPointers.Remove(currentPerson); listOfSets.Last.Value.RemoveFirst(); //Remove set if empty if (listOfSets.Last.Value.Count == 0) { listOfSets.Remove(listOfSets.Last); } //Assign label currentPerson.Position = i; outputArray[i] = currentPerson; //Assign new sets to all neighbors foreach (Person neighbor in currentPerson.Neighbors) { //Ignore labeled neighbors if (neighbor.Position == -1) { //Get current set of neighbor LinkedListNode <SetList <Person> > currentSet = setPointers[neighbor]; //If currentSet has no replacement generate replacement set generate one if (!currentSet.Value.HasReplacement) { currentSet.Value.HasReplacement = true; SetList <Person> newSet = new SetList <Person>(); listOfSets.AddAfter(currentSet, newSet); setsToCheck.Add(currentSet); } //Put neighbor in a set one level higher currentSet.Value.Remove(positionPointers[neighbor]); setPointers[neighbor] = currentSet.Next; positionPointers[neighbor] = currentSet.Next.Value.AddLast(neighbor); } } //Unflag all previously flagged set and delete them if empty foreach (LinkedListNode <SetList <Person> > setList in setsToCheck) { if (setList.Value.Count == 0) { listOfSets.Remove(setList); } else { setList.Value.HasReplacement = false; } } setsToCheck.Clear(); i = i + (direction == Direction.Backwards ? -1 : 1); } return(outputArray); }