简体   繁体   English

如何在并行任务中运行 Microsoft Solver Foundation

[英]How to run Microsoft Solver Foundation in parallel tasks

I would like to run Microsoft Solver Foundation in parallel tasks.我想在并行任务中运行 Microsoft Solver Foundation。 I tried with the solution below and it throws an exception "ArgumentException: exePath must be specified when not running inside a stand alone exe.".我尝试了下面的解决方案,但它抛出了一个异常“ArgumentException: exePath must be specified when not running in a standalone exe.”。 It runs fine one after another but I need to run multiple tasks in parallel to speed up the process.它一个接一个地运行良好,但我需要并行运行多个任务以加快进程。

This is my solver method这是我的求解器方法

public List<Decision> SolveDecisions(RaceWager raceWager)
        {
            _logger.Info("Start to solve decisions");
            EnsureInputIsNotNull(raceWager);

            var solver = SolverContext.GetContext(); // Exception throw here

            solver.ClearModel();

            var model = solver.CreateModel();
            _logger.Info("Generate decisions");
            var decisions = GenerateDecisions(Domain.RealNonnegative, "x", raceWager.RunWagers, raceWager.BankRoll);
            model.AddDecisions(decisions.ToArray());

            var decisionNames = decisions.Select(decision => decision.Name).ToList();

            var sumDecisionsExpression = string.Join(" + ", decisionNames);
            model.AddConstraint("budget", $"({sumDecisionsExpression}) <= {raceWager.BankRoll}");

            var expectedProfitFormula = GenerateExpectedProfitSolverExpression(decisionNames, raceWager);
            model.AddGoal("ExpectedProfit", GoalKind.Maximize, expectedProfitFormula);
            _logger.Info("Solve decisions");
            solver.Solve(
                new Directive
                {
                    TimeLimit = int.TryParse(ConfigurationManager.AppSettings["SolverTimeLimit"], out var timeLimit)
                        ? timeLimit
                        : DefaultTimeLimit,
                    WaitLimit = int.TryParse(ConfigurationManager.AppSettings["SolverWaitLimit"], out var waitLimit)
                        ? waitLimit
                        : DefaultWaitTimeLimit
                });
            _logger.Info("End solve decisions");
            return model.Decisions.ToList();
        }

When I try to wrap it in multiple tasks to run in parallel.当我尝试将它包装在多个任务中以并行运行时。

var optimizeTasks = new List<Task>();
                for (var i = 0; i < 2; i++)
                {
                    optimizeTasks.Add(Task.Run(() =>
                    {
                        _optimizeService.SolveDecisions(new RaceWager
                        {
                            BetTypeId = BetTypes.WIN,
                            BankRoll = 50000,
                            UserDefinedOverround = 1,
                            TotalPool = 23529.0,
                            RunWagers = new List<RunWager>
                            {
                                new RunWager {ModelPercentage = 0.119796574f, MarketOdds = 11.5815125f, HorsePool = 1693},
                                new RunWager {ModelPercentage = 0.08600821f, MarketOdds = 12.5931282f, HorsePool = 1557},
                                new RunWager {ModelPercentage = 0.210860476f, MarketOdds = 3.56759453f, HorsePool = 5496},
                                new RunWager {ModelPercentage = 0.07284866f, MarketOdds = 8.792601f, HorsePool = 2230},
                                new RunWager {ModelPercentage = 0.08509313f, MarketOdds = 8.622472f, HorsePool = 2274},
                                new RunWager {ModelPercentage = 0.0636601746f, MarketOdds = 9.83325f, HorsePool = 1994},
                                new RunWager {ModelPercentage = 0.06863576f, MarketOdds = 31.4727135f, HorsePool = 623},
                                new RunWager {ModelPercentage = 0.0714284852f, MarketOdds = 11.4529791f, HorsePool = 1712},
                                new RunWager {ModelPercentage = 0.0970818f, MarketOdds = 7.305328f, HorsePool = 2684},
                                new RunWager {ModelPercentage = 0.0276215617f, MarketOdds = 25.2024422f, HorsePool = 778},
                                new RunWager {ModelPercentage = 0.0531845465f, MarketOdds = 14.7646837f, HorsePool = 1328},
                                new RunWager {ModelPercentage = 0.0437806025f, MarketOdds = 16.903017f, HorsePool = 1160},
                                new RunWager {ModelPercentage = 0.06345806025f, MarketOdds = 15.234017f, HorsePool = 1260, PGIScratching = true}
                            }
                        });
                    }));
                }
await Task.WhenAll(optimizeTasks);

At this line of code will throw an exception在这行代码会抛出异常

var solver = SolverContext.GetContext();
Exception: 'Microsoft Solver Foundation plugin solver configuration exception.'

Message: 'exePath must be specified when not running inside a stand alone exe'

StackTrace:
   at System.Configuration.ConfigurationManager.OpenExeConfigurationImpl(ConfigurationFileMap fileMap, Boolean isMachine, ConfigurationUserLevel userLevel, String exePath, Boolean preLoad)
   at Microsoft.SolverFoundation.Services.PluginSolverCollection.<GetPluginSolverSection>d__7.MoveNext()
   at Microsoft.SolverFoundation.Services.PluginSolverCollection.Initialize()
   at Microsoft.SolverFoundation.Services.PluginSolverCollection.CreatePluginSolverCollection()

Please let me know if you need extra information.如果您需要额外的信息,请告诉我。 Thanks in advance提前致谢

Okay, I'm able to resolve my problem.好的,我能够解决我的问题。 I still don't know what is the root cause but I can fix it by creating a field in the constructor instead of in the task.我仍然不知道根本原因是什么,但我可以通过在构造函数中而不是在任务中创建一个字段来解决它。

Remove this.去掉这个。

var solver = SolverContext.GetContext();

Use this instead改用这个

private readonly ILogger _logger;
private readonly SolverContext _solver;

public OptimizeService(ILogger logger)
{
     _logger = logger;
     _solver = SolverContext.GetContext();
}    

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM