예제 #1
0
        // DOES NOT DEAL WITH CIRCUITS WITH CYCLES!!!
        private List <Gate> AssignTopologicalRanks()
        {
            // grab an item from the input set
            var inEnum = InputAddrs.GetEnumerator();

            inEnum.MoveNext();
            var gateDeque = new LinkedList <Gate>();

            while (inEnum.MoveNext())
            {
                gateDeque.AddFirst(inEnum.Current.Gate);
            }

            var sortList = new List <Gate>();

            int nextRank = 0;

            while (gateDeque.Count > 0)
            {
                var current = gateDeque.First.Value;

                if (current.TopologicalRank != Gate.NO_RANK)
                {
                    // already assigned a rank to this. can move on to next
                    gateDeque.RemoveFirst();
                    continue;
                }

                // check to see if all of the predecessors have a rank assigned. If any don't then add them to the front of the queue
                bool shouldAssignRank = true;

                for (int i = 0; i < current.InputCount; i++)
                {
                    var addr = current.GetLocalInputAddress(i);
                    if (InputAddrs.Contains(addr))
                    {
                        continue;
                    }

                    var counterparty = InputConnectionCounterparties[addr].Gate;
                    if (counterparty.TopologicalRank == Gate.NO_RANK)
                    {
                        gateDeque.AddFirst(counterparty);
                        shouldAssignRank = false;
                    }
                }

                if (shouldAssignRank)
                {
                    current.TopologicalRank = nextRank;
                    nextRank++;
                    sortList.Add(current);
                    gateDeque.RemoveFirst();

                    // add all successors
                    for (int i = 0; i < current.OutputCount; i++)
                    {
                        var addr = current.GetLocalOutputAddress(i);
                        if (OutputAddrs.Contains(addr))
                        {
                            continue;
                        }

                        gateDeque.AddLast(OutputConnectionCounterparties[addr].Gate);
                    }
                }
                // otherwise a predecessor still needs a rank
            }

            return(sortList);
        }