예제 #1
0
        /// <summary>
        /// Processes the first available agent in a leaf node.
        /// </summary>
        /// <param name="l">Index of the leaf node to process.</param>
        /// <param name="state">State of the parallel loop.</param>
        /// <param name="doneTick">Whether or not the process cycle has been completed.</param>
        /// <returns>The doneTick variable.</returns>
        private long ProcessLeafSingle(int l, ParallelLoopState state, long toProcess)
        {
            // Get leaf
            LeafNode leaf = Leaves[l];

            // If there is an agent to process
            if (leaf.Out.Count > 0)
            {
                // Get agent from node
                Agent a = leaf.Dequeue();

                // Perform transaction between station and agent
                InteractTerm(leaf.Terminal, a);

                // Get node that agent will travel to next
                GraphNode exit = leaf.GetExit(a);

                // Move agent to node if available, otherwise put back onto leaf
                if (exit != null)
                {
                    exit.Enqueue(a);
                }
                else
                {
                    leaf.Enqueue(a);
                }

                // If there are more agents, then the tick isn't done
                if (leaf.Out.Count > 0)
                {
                    toProcess++;
                }
            }

            return(toProcess);
        }
예제 #2
0
        /// <summary>
        /// Generate a new graph for this object.
        /// </summary>
        /// <param name="rand">The random object to be used for generation.</param>
        /// <param name="total_remain">The total number of nodes in this graph.</param>
        /// <param name="max_children">The max number of children per node.</param>
        /// <param name="offset">The offset from the average.</param>
        public void GenTree(Random rand, int total_remain, int max_children, int offset, int leaf_chance)
        {
            int n_kids_tot, c_kids_tot, n_kids_max, n_kids_min, kids_remain, avg_kpn, real_kpn, tier, tier_index, min;

            GraphNode[]       cur_tier;
            List <GraphNode>  next_tier;
            RootNode          root;
            List <BranchNode> branches;
            List <LeafNode>   leaves;
            GraphNode         current;
            List <int>        tiers;
            bool isRoot;

            // Initialize branches and leaves;
            branches = new List <BranchNode>();
            leaves   = new List <LeafNode>();
            tiers    = new List <int>();
            // Initialize the positioning variables
            tier       = 0;
            tier_index = 0;
            // The head will have one neighbor
            n_kids_tot = 1;
            // Subtract the head and it's neighbor from the remaining total
            total_remain -= n_kids_tot + 1;
            // Initialize the head
            root        = new RootNode();
            root.Layout = new int[] { tier, tier_index };
            tier_index++;
            // Insert head as only node of next tier of nodes to work on
            next_tier = new List <GraphNode>()
            {
                root
            };
            // set first tier bool
            isRoot = true;

            while (n_kids_tot > 0)
            {
                // Set next tier as current tier and get new next tier
                cur_tier  = next_tier.ToArray();
                next_tier = new List <GraphNode>();
                tier++;
                tiers.Add(tier_index);
                tier_index = 0;
                // Set next total to current tier and reset next total
                c_kids_tot = n_kids_tot;
                n_kids_tot = 0;
                // Get total possible nodes for next tier as multiple of nodes to generate times
                // the max number of children each node can have
                n_kids_max = c_kids_tot * max_children;

                // If possible total is larger than total remaining, clamp to later
                if (total_remain < n_kids_max)
                {
                    kids_remain = total_remain;
                }
                // Otherwise set projected total for next tier as a random number between half
                // this tier and the possible total
                else
                {
                    n_kids_min  = c_kids_tot / 2 < 1 ? 1 : c_kids_tot / 2;
                    kids_remain = rand.Next(n_kids_min, n_kids_max + 1);
                }

                // Subtract this tier's total from remaining total
                total_remain -= kids_remain;
                // Get the average number of children per node of this tier
                avg_kpn = kids_remain / c_kids_tot < 1 ? 1 : kids_remain / c_kids_tot;

                // For each node in this tier
                for (int i = 0; i < cur_tier.Length; i++)
                {
                    // For each child of this node
                    for (int j = isRoot ? 0 : 1; j < cur_tier[i].Neighbors.Length; j++)
                    {
                        // If the average is greater than what remains to be generated, then clamp to later
                        if (kids_remain < avg_kpn)
                        {
                            real_kpn = kids_remain;
                        }
                        // Otherwise, random chance for leaf
                        else if (n_kids_tot > 0 && rand.Next(100) < leaf_chance)
                        {
                            real_kpn = 0;
                        }
                        // Otherwise set real number of children to some random offset from the average
                        // and clamp the value to max or the remaining children if necessary
                        else
                        {
                            min      = Math.Min(offset, avg_kpn);
                            real_kpn = Math.Min(avg_kpn + rand.Next(offset + min) - min + 1, Math.Min(max_children, kids_remain));

                            if (real_kpn == 0)
                            {
                                return;
                            }
                        }

                        // Subtract this node's children from remaining children
                        kids_remain -= real_kpn;
                        // Add to total of next tier
                        n_kids_tot += real_kpn;

                        // Generate a node with the calculated number of children
                        if (real_kpn == 0)
                        {
                            current = new LeafNode();
                            leaves.Add((LeafNode)current);
                        }
                        else
                        {
                            current = new BranchNode(real_kpn + 1);
                            branches.Add((BranchNode)current);
                            next_tier.Add(current);
                        }
                        // Position current node
                        current.Layout = new int[] { tier, tier_index };
                        tier_index++;
                        // Add node to graph
                        cur_tier[i].AddNeighbor(current);
                    }
                }
                // Add back on any un-generated children
                total_remain += kids_remain;
                // turn off special head case bool
                if (isRoot)
                {
                    isRoot = false;
                }
            }

            // Set all the finalized values
            Roots = new List <RootNode> {
                root
            };
            Branches = branches;
            Leaves   = leaves;
            Counts   = tiers;
        }