用Microsoft.Solver.Foundation進行線性規劃,為WPF應用添加智能
阿新 • • 發佈:2018-09-25
代碼 程序 因子 edev add context eight 創建 mini 原文:用Microsoft.Solver.Foundation進行線性規劃,為WPF應用添加智能
在管理信息系統的開發過程中,往往會涉及到一些線性規劃數學模型,例如資源配置優化。微軟的Microsoft.Solver.Foundation是一個數學庫,可以很好的對線性規劃問題進行求解。關於它的細節,可以自行百度,話不多說,以例題來學習如何用Microsoft.Solver.Foundation進行線性規劃:
題目(來自網絡),如下圖:
為了解決上述線性規劃問題,先要下載並安裝Microsoft.Solver.Foundation庫,關於安裝細節這裏不贅述。
1、VS2012建立一個WPF應用程序WpfLPDemo(WinForm也是可以的),新建一個libs文件夾和images文件夾,並將Microsoft.Solver.Foundation.dll拷貝到libs(註意添加dll引用),如下圖:
images下放的圖片為題目截圖。
2、編輯MainWindow.xaml文件,在設計界面上放一個Image展示例題截圖、TextBlock用於顯示優化結果、Button用於觸發計算事件,代碼如下:
1 <Window x:Class="WpfLPDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="424.03" Width="711.269"> 5 <Grid> 6 <Image HorizontalAlignment="Left" Height="290" Margin="4,10,0,0" VerticalAlignment="Top" Width="695" Source="images/1.png" Stretch="Fill" /> 7 <TextBlock Name="answer" HorizontalAlignment="Left" Margin="33,352,0,0"TextWrapping="Wrap" VerticalAlignment="Top" Text="線性規劃答案為:" FontFamily="Verdana" FontSize="14" /> 8 <Button Content="計算" HorizontalAlignment="Left" Margin="604,305,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_calc" FontSize="15" /> 9 10 </Grid> 11 </Window>
3、編輯MainWindow.xaml.cs文件,註意添加using Microsoft.SolverFoundation.Services; using Microsoft.SolverFoundation.Solvers;代碼如下(核心代碼已經做了註釋,可了解一下用法):
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Windows; 7 using System.Windows.Controls; 8 using System.Windows.Data; 9 using System.Windows.Documents; 10 using System.Windows.Input; 11 using System.Windows.Media; 12 using System.Windows.Media.Imaging; 13 using System.Windows.Navigation; 14 using System.Windows.Shapes; 15 using Microsoft.SolverFoundation; 16 namespace WpfLPDemo 17 { 18 using Microsoft.SolverFoundation.Services; 19 using Microsoft.SolverFoundation.Solvers; 20 /// <summary> 21 /// MainWindow.xaml 的交互邏輯 22 /// </summary> 23 public partial class MainWindow : Window 24 { 25 public MainWindow() 26 { 27 InitializeComponent(); 28 } 29 public object OPT() 30 { 31 SolverContext context = SolverContext.GetContext(); 32 //創建模型 33 Model model = context.CreateModel(); 34 //優化決策因子,變量為實數,Domain.Integer|Domain.IntegerNonnegative為整數優化 35 Decision x = new Decision(Domain.Real, "x"); 36 Decision y = new Decision(Domain.Real, "y"); 37 //添加 38 model.AddDecisions(x, y); 39 //x,y變量範圍 40 // model.AddConstraints("變量範圍", 41 // double.NegativeInfinity < x <= double.PositiveInfinity, 42 //double.NegativeInfinity < y <= double.PositiveInfinity); 43 44 model.AddConstraints("約束", 45 double.NegativeInfinity < x <= double.PositiveInfinity, 46 double.NegativeInfinity < y <= double.PositiveInfinity, 47 2*x + y - 2 >=0, 48 x - 2*y + 4 >=0, 49 3*x - y -3 <= 0); 50 //目標函數 min z=x * x + y * y , GoalKind.Minimize最小值 51 Goal gmin= model.AddGoal("zmin", GoalKind.Minimize, x * x + y * y); 52 53 //優化 54 Solution solution = context.Solve(); 55 //優化報告 56 // Report report = solution.GetReport(); 57 58 string s = string.Format("min [ x={0:N2},y={1:N2}", x.ToDouble().ToString("0.00"), y.ToDouble().ToString("0.00")); 59 s += string.Format(",min={0} ] " ,solution.Goals.First<Goal>().ToDouble().ToString("0.00")); 60 61 //================================================================= 62 model.RemoveGoal(gmin); 63 Goal gmax = model.AddGoal("zmax", GoalKind.Maximize, x * x + y * y); 64 //優化 65 solution = context.Solve(); 66 s += string.Format("| max[ x={0:N2},y={1:N2}", x.ToDouble().ToString("0.00"), y.ToDouble().ToString("0.00")); 67 s += string.Format(",max={0} ] " ,solution.Goals.First<Goal>().ToDouble().ToString("0.00")); 68 //-------------------------------------------------------------------------------------------------------------------------------- 69 70 context.ClearModel(); 71 return s; 72 73 } 74 private void Button_Click_calc(object sender, RoutedEventArgs e) 75 { 76 this.answer.Text = OPT().ToString(); 77 } 78 79 80 } 81 }
4、保存並運行程序,成功的話應該如下圖:
5、單擊計算按鈕,即可輸出結構,如下圖:
可見計算的答案和例題給出的答案是一致的。為了構建根據通用的程序,可以從UI上動態傳入模型以及模型的值進行優化求解,從而更好的具有實用性。
用Microsoft.Solver.Foundation進行線性規劃,為WPF應用添加智能