【解決方法】乱数と確率分布を使用して Microsoft Solver Foundation Services を使用しようとしています

プログラミングQA


さて、私は今、素晴らしい解決策 (MSDN サブスクリプションで無料、配布可能など) のように見えたものが実際には駄目だったということで、かなり絶望的な気持ちを抱いています。

C# Visual Studio プロジェクトで Microsoft Solver Foundation を使用しようとしています。 最適化で使用されるパラメーターの一部は統計的確率分布からの乱数であるため、RandomParameter タイプを使用する必要があります (RandomParameter は、NormalDistributionParamater などのクラスが派生する抽象基本クラスです)。 事前定義された RandomParameter タイプは少数しかないため、他の統計分布のデータを、AddConstraint メソッドで使用する適切なクラス タイプに変換する方法があるかどうかを考えています。 ScenariosParameter は、おそらくデータを設定できるある種のカスタマイズ可能なクラスのようです。そのため、ポアソン分布データを含む ScenariosParameter クラスを使用するために、インターネットで見つけたコードをいくつか修正しました。 パラメータを作成しようとしました:

C#
ScenariosParameter poissonRandomVals;

コードはコンパイルされますが、行でクラッシュします

C#
model.AddConstraint("demand2", 0.3 * sa + 0.4 * vz + gasBuy >= poissonRandomVals);

私は C# と MSF を初めて使用するため、その理由がわかりません。コード全体を以下に示します。

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.SolverFoundation.Common;
using Microsoft.SolverFoundation.Solvers;
using Microsoft.SolverFoundation.Services;



namespace JLSolver
{
    class Program
    {
        static void Main(string[] args)
        {
            SolverContext context = SolverContext.GetContext();
            context.ClearModel();
            Model model = context.CreateModel();

            // decide how many barrels to buy from each crude oil source
            Decision sa = new Decision(Domain.RealRange(0, 9000), "SA");
            Decision vz = new Decision(Domain.RealRange(0, 6000), "VZ");
            model.AddDecisions(sa, vz);

            // decide how much refined oil to by, this decision must be made after random PD number has been generated,
            // and see if demand can be met without this option, hence recourse
            // so if demand can be met buy purchasing crude oil, no need to buy refined so do not need to make this decision
            RecourseDecision gasBuy = new RecourseDecision(Domain.RealNonnegative, "GasBuy");
            RecourseDecision jetFuelBuy = new RecourseDecision(Domain.RealNonnegative, "JetFuelBuy");
            RecourseDecision lubricantBuy = new RecourseDecision(Domain.RealNonnegative, "LubricantBuy");
            model.AddDecisions(gasBuy, jetFuelBuy, lubricantBuy);

            // goal is to minimise cost of buying crude and refined oil
            model.AddGoal("goal", GoalKind.Minimize, 20 * sa + 15 * vz + (38.4 * gasBuy + 35.2 * jetFuelBuy + 28.8 * lubricantBuy));
            
            // demand for each fraction varies and has a PD
            RandomParameter gasDemand = new NormalDistributionParameter("GasDemand", 1900, 50);
            RandomParameter jetFuelDemand = new NormalDistributionParameter("JetFuelDemand", 1500, 25);
            RandomParameter lubricantDemand = new NormalDistributionParameter("LubricantDemand", 500, 5);
           
            // create a poisson distribution random number generator
            Troschuetz.Random.Generator rndGenerator = new Troschuetz.Random.StandardGenerator();
            Troschuetz.Random.PoissonDistribution poissonDist = new Troschuetz.Random.PoissonDistribution(rndGenerator);
            
            // get an array of 100 poisson distribution random numbers
            Term[] poissonNumbers = new Term[100];
            for (int i = 0; i < 100; i++)
            {
                poissonNumbers[i] = poissonDist.NextDouble(); // returns a poisson distributed random number, no seed defined
            }
            Set poissonSet = new Set(poissonNumbers);
            RandomParameter poissonRandomVals = new ScenariosParameter("RandomParams", poissonSet);
            
            model.AddParameters(gasDemand, jetFuelDemand, lubricantDemand, poissonRandomVals);

            // must buy enough barrels of oil to meet requirements, from crude and refined sources
            model.AddConstraint("demand1", 0.4 * sa + 0.2 * vz + jetFuelBuy >= jetFuelDemand);
            model.AddConstraint("demand2", 0.3 * sa + 0.4 * vz + gasBuy >= poissonRandomVals); // THIS LINE CRASHES !!!
            model.AddConstraint("demand3", 0.2 * sa + 0.3 * vz + lubricantBuy >= lubricantDemand);

            // solve
            Solution solution = context.Solve();
            Report report = solution.GetReport();
            Console.WriteLine(report);
            Console.ReadLine();
        }
    }
}

Solver Foundation の使用方法、特に ScenariosParameter の使用方法に関するドキュメントはほとんどないようです。 誰か良い情報源を知りませんか?

今、自分の人生で何が良かったのか、そしてこれはソフトウェアを楽しい仕事にする「興味深い」問題の 1 つであることを思い出そうとしています :/

解決策 1

こんにちは、
私は現在、Microsoft ソルバー ファウンデーションを使用して確率的最適化問題を解決しようとしています。コードを見つけて、セナリオ パラメーターなどのランダム性パラメーターの使用方法を理解しました。
この問題を解決する方法は見つかりましたか?

コメント

タイトルとURLをコピーしました