예제 #1
0
        /// <summary>
        /// Assuming the firm implements decision DECF0, this method computes
        /// reported costs for this cost system, which are used to compute the firm's updated decision.
        /// It iterates using the updated decision as the new starting decision until a terminal outcome
        /// (e.g. equilibrium, cycle) is reached.
        /// </summary>
        /// <param name="ip">The current InputParameters object</param>
        /// <param name="DECF0">The starting decision.</param>
        /// <returns>Returns the outcome of iterations and the final decision.</returns>
        public (CostSystemOutcomes stopCode, RowVector DECF1) EquilibriumCheck(InputParameters ip, RowVector DECF0)
        {
            #region Make local copies of firm-level variables

            ColumnVector MXQ = this.firm.MXQ;
            RowVector    SP  = this.firm.SP;

            #endregion

            // The initial vector of production quantities, given
            // starting decision DECF0
            ColumnVector q0 = MXQ.ewMultiply(DECF0);
            // A list of past decisions made during the iteration process.
            // If a decision appears twice on this list, then a cycle exists.
            List <RowVector> pastDecisions = new List <RowVector> {
                DECF0
            };
            // The "next" decision that the firm would make. Assume the firm
            // starts with DECF0, computes resulting resource consumption,
            // and reported costs (through the cost system). Given reported
            // costs, it updates its decision to DECF1.
            RowVector DECF1;

            bool               foundThisDecisionBefore;
            double             MAR_DROP = 1.0 - ip.HYSTERESIS;
            double             MAR_MAKE = 1.0 + ip.HYSTERESIS;
            CostSystemOutcomes stopCode = CostSystemOutcomes.Unassigned;

            bool done;
            do
            {
                RowVector PC_R = CalcReportedCosts(ip, DECF0);

                if (PC_R.Contains(double.NaN))
                {
                    DECF1 = PC_R.Map(x => double.NaN);
                }
                else
                {
                    double[] MAR   = PC_R.Zip(SP, (pc_r, sp) => sp / pc_r).ToArray();
                    var      decf1 = MAR.Zip(q0, (mar, q) =>
                                             (q > 0.0) ? ((mar <= MAR_DROP) ? 0.0 : 1.0) : ((mar > MAR_MAKE) ? 1.0 : 0.0));
                    DECF1 = new RowVector(decf1.ToList());
                }

                ColumnVector q1 = MXQ.ewMultiply(DECF1);
                if (!(foundThisDecisionBefore = pastDecisions.Contains(DECF1)))
                {
                    pastDecisions.Add(DECF1);
                }

                //double ExpectedCosts = PC_R * q1;
                //double TCF0 = this.firm.CalcTotCosts(q1);

                done = true;
                //if (q1 == q0) {
                if (DECF1 == DECF0)
                {
                    stopCode = CostSystemOutcomes.Equilibrium;
                }
                else if (q1.TrueForAll(qty => qty == 0.0))
                {
                    stopCode = CostSystemOutcomes.ZeroMix;
                }
                else if (foundThisDecisionBefore)
                {
                    stopCode = CostSystemOutcomes.Cycle;
                }
                else if (DECF1.Contains(double.NaN))
                {
                    stopCode = CostSystemOutcomes.NaN;
                }
                else
                {
                    done = false;
                }

                if (!done)
                {
                    DECF0 = DECF1;
                    q0    = q1;
                }
            } while (!done);

            return(stopCode, DECF1);
        }
예제 #2
0
        static void Main(string[] args)
        {
            #region Console header

            DrawASCIIart();

            #endregion

            #region Read input file and create InputParameters object

            FileInfo inputFile = new FileInfo(Environment.CurrentDirectory + @"\input.txt");

            if (!inputFile.Exists)
            {
                Console.WriteLine("Could not find input file: \n{0}", inputFile.FullName);
                Console.WriteLine("Aborting. Press ENTER to end the program.");
                Console.ReadLine();
                return;
            }

            InputParameters ip = new InputParameters(inputFile);

            #endregion

            #region Make a copy of the input file

            // We found it helpful to make a copy of the input file every time we ran the
            // simulation. We stamp the copy's filename with the date and time so that
            // we know which results files correspond to which input file.
            DateTime dt = DateTime.Now;
            string   inputFileCopyName =
                String.Format(
                    "input {0:D2}-{1:D2}-{2:D4} {3:D2}h {4:D2}m {5:D2}s, seed {6:G}.txt",
                    dt.Month,
                    dt.Day,
                    dt.Year,
                    dt.Hour,
                    dt.Minute,
                    dt.Second,
                    GenRandNumbers.GetSeed()
                    );
            FileInfo inputFileCopy = new FileInfo(Environment.CurrentDirectory + @"\" + inputFileCopyName);
            inputFile.CopyTo(inputFileCopy.FullName, true);
            File.SetCreationTime(inputFileCopy.FullName, dt);
            File.SetLastWriteTime(inputFileCopy.FullName, dt);

            #endregion

            #region Create output files

            Output.CreateOutputFiles(ip);

            #endregion

            #region Generate Sample of Firms and their Cost Systems

            Firm[] sampleFirms = new Firm[ip.NUM_FIRMS];

            for (int firmID = 1; firmID <= ip.NUM_FIRMS; ++firmID)
            {
                Console.WriteLine(
                    "Starting firm {0:D3} of {1}",
                    firmID + 1, sampleFirms.Length
                    );

                Firm f = new Firm(ip, firmID);
                sampleFirms[firmID - 1] = f;

                for (int a_indx = 0; a_indx < ip.ACP.Count; ++a_indx)
                {
                    int a = ip.ACP[a_indx];

                    for (int p_indx = 0; p_indx < ip.PACP.Count; ++p_indx)
                    {
                        int p = ip.PACP[p_indx];

                        for (int r_indx = 0; r_indx < ip.PDR.Count; ++r_indx)
                        {
                            int r = ip.PDR[r_indx];

                            // Create a cost system
                            CostSys costsys = new CostSys(ip, f, a, p, r);
                            f.costSystems.Add(costsys);
                            int costSysID = f.costSystems.Count;
                            Output.LogCostSys(costsys, firmID, costSysID);

                            // Generate a starting decision for the cost system.
                            RowVector startingDecision;
                            if (ip.STARTMIX == 0)
                            {
                                startingDecision = f.CalcOptimalDecision();
                            }
                            else
                            {
                                var ones = Enumerable.Repeat(1.0, ip.CO).ToList();
                                startingDecision = new RowVector(ones);
                                for (int i = 0; i < startingDecision.Dimension; ++i)
                                {
                                    if (GenRandNumbers.GenUniformDbl() < ip.EXCLUDE)
                                    {
                                        startingDecision[i] = 0.0;
                                    }
                                }
                            }

                            /* Examine error in cost from implementing this decision.
                             * Assume the firm implements the decision startingDecision. Upon
                             * doing so, it will observe total resource consumption. It will then
                             * allocate resources to cost pools, as per the B parameter of the cost
                             * system, choose drivers as per the D parameter of the cost system,
                             * and then allocate resources to cost objects and compute reported costs.
                             * The reported costs are returned as PC_R. The difference
                             * between these and the true benchmark costs (PC_B) is used to compute
                             * the mean percent error in costs.
                             */
                            RowVector PC_R = costsys.CalcReportedCosts(ip, startingDecision);
                            RowVector PC_B = f.CalcTrueProductCosts();
                            double    MPE  = PC_B.Zip(PC_R, (pc_b, pc_r) => Math.Abs(pc_b - pc_r) / pc_b).Sum() / PC_B.Dimension;
                            Output.LogCostSysError(costsys, firmID, costSysID, startingDecision, PC_B, PC_R, MPE);

                            /* Assume the firm implements the decision startingDecision. Upon
                             * doing so, it will observe total resource consumption. It will then
                             * allocate resources to cost pools, as per the B parameter of the cost
                             * system, choose drivers as per the D parameter of the cost system,
                             * and then allocate resources to cost objects and compute reported costs.
                             * The reported costs are returned as PC_R. Upon observing the
                             * reported costs, the firm may wish to update its original decision. When
                             * it implements the updated decision, costs will change again. The outcome
                             * of this process will either be an equilibrium decision (fixed point), or
                             * a cycle of decisions.
                             */
                            (CostSystemOutcomes stopCode, RowVector endingDecision) = costsys.EquilibriumCheck(ip, startingDecision);
                            Output.LogCostSysLoop(costsys, firmID, costSysID, startingDecision, endingDecision, stopCode);
                        }
                    }
                }
            }

            #endregion

            Console.WriteLine("Writing output files...");
            Output.WriteOutput();
            Console.WriteLine("Done!");
        }