Loading...
Searching...
No Matches
Form1.cs
1using System;
2using System.Collections.Generic;
3using System.ComponentModel;
4using System.Data;
5using System.Drawing;
6using System.Linq;
7using System.Text;
8using System.Windows.Forms;
9using GAMS;
10using System.Windows.Forms.DataVisualization.Charting;
11using System.Diagnostics;
12using System.Data.OleDb;
13using System.Reflection;
14
15namespace TransportGUI
16{
24 public partial class Form1 : Form
25 {
26 private Dictionary<Tuple<string, string>, double> distance = new Dictionary<Tuple<string, string>, double>()
27 {
28 { new Tuple<string,string> ("Seattle", "New-York"), 2.5 },
29 { new Tuple<string,string> ("Seattle", "Chicago"), 1.7 },
30 { new Tuple<string,string> ("Seattle", "Topeka"), 1.8 },
31 { new Tuple<string,string> ("San-Diego", "New-York"), 2.5 },
32 { new Tuple<string,string> ("San-Diego", "Chicago"), 1.8 },
33 { new Tuple<string,string> ("San-Diego", "Topeka"), 1.4 }
34 };
35
36 private Dictionary<string, double> capacity = new Dictionary<string, double>()
37 {
38 { "Seattle", 350},
39 { "San-Diego", 600}
40 };
41
42 private Dictionary<string, double> demand = new Dictionary<string, double>()
43 {
44 { "New-York", 325},
45 { "Chicago", 300},
46 { "Topeka", 275}
47 };
48
49 private double phiMin = 0.2;
50 private double phiMax = 1.0;
51 private double phiSteps = 0.05;
52
53 private Dictionary<string, List<Tuple<String,String,double>>> resultX;
54
55 public Form1()
56 {
57 InitializeComponent();
58 this.chart1.Series.Clear();
59 this.chart1.Visible = false;
60 this.chart1.ChartAreas[0].AxisY.Title = "$ (x1000)";
61 this.chart1.ChartAreas[0].AxisY.TextOrientation = TextOrientation.Horizontal;
62 this.chart1.ChartAreas[0].AxisX.Title = "phi";
63 this.chart1.ChartAreas[0].AxisX.TextOrientation = TextOrientation.Horizontal;
64 // bind default data to data grids
65 foreach (Tuple<string, string> t in distance.Keys)
66 this.dataGridDistance.Rows.Add(new string[]{ t.Item1, t.Item2, distance[t].ToString()} );
67 foreach (string t in capacity.Keys)
68 this.dataGridCapacity.Rows.Add(new string[] { t, capacity[t].ToString() });
69 foreach (string t in demand.Keys)
70 this.dataGridDemand.Rows.Add(new string[] { t, demand[t].ToString() });
71 this.dataGridPhi.Rows.Add(new string[] { phiMin.ToString(), phiMax.ToString(), phiSteps.ToString() });
72 }
73
74 private void button1_Click(object sender, EventArgs e)
75 {
76 this.dataGridView1.Rows.Clear();
77 this.chart1.Series.Clear();
78 this.chart1.ResetAutoValues();
79 this.chart1.Visible = true;
80 this.chart1.Series.Add("cost");
81
82 this.resultX = new Dictionary<string, List<Tuple<string, string, double>>>();
83
85
86 // get data from user input
87 GAMSDatabase data = ws.AddDatabase("data");
88
89 GAMSParameter d = data.AddParameter("d", 2, "distance in thousands of miles");
90 foreach (DataGridViewRow row in this.dataGridDistance.Rows)
91 d.AddRecord(row.Cells[0].Value.ToString(), row.Cells[1].Value.ToString()).Value = Convert.ToDouble(row.Cells[2].Value);
92
93 GAMSSet i = data.AddSet("i", 1, "canning plants");
94 GAMSParameter a = data.AddParameter("a", 1, "capacity of plant i in cases");
95 for (int idx = 0; idx < this.dataGridCapacity.Rows.Count - 1; idx++)
96 {
97 i.AddRecord(this.dataGridCapacity.Rows[idx].Cells[0].Value.ToString());
98 a.AddRecord(this.dataGridCapacity.Rows[idx].Cells[0].Value.ToString()).Value = Convert.ToDouble(this.dataGridCapacity.Rows[idx].Cells[1].Value);
99 }
100
101 GAMSSet j = data.AddSet("j", 1, "markets");
102 GAMSParameter b = data.AddParameter("b", 1, "demand at market j in cases");
103 for (int idx = 0; idx < this.dataGridDemand.Rows.Count - 1; idx++)
104 {
105 j.AddRecord(this.dataGridDemand.Rows[idx].Cells[0].Value.ToString());
106 b.AddRecord(this.dataGridDemand.Rows[idx].Cells[0].Value.ToString()).Value = Convert.ToDouble(this.dataGridDemand.Rows[idx].Cells[1].Value);
107 }
108
109 // initialize a GAMSCheckpoint by running a GAMSJob
110 GAMSOptions opt = ws.AddOptions();
111 opt.AllModelTypes = "conopt";
112 GAMSJob t7 = ws.AddJobFromString(GetModelText());
113 GAMSCheckpoint cp = ws.AddCheckpoint();
114 t7.Run(opt, cp, data);
115
116 // create a GAMSModelInstance and solve it multiple times with different scalar phi
118
119 GAMSParameter phi = mi.SyncDB.AddParameter("phi", 0, "demand and cost elasticity factor");
120
121 // instantiate the GAMSModelInstance and pass a model definition and GAMSModifier to declare phi mutable
122 mi.Instantiate("transport us nlp min z", opt, new GAMSModifier(phi));
123
124 phi.AddRecord();
125 List<double> philist = new List<double>();
126 double v = Convert.ToDouble(this.dataGridPhi.Rows[0].Cells[0].Value); // phiMin
127 do
128 {
129 philist.Add(v);
130 v += Convert.ToDouble(this.dataGridPhi.Rows[0].Cells[2].Value); // v+= phiSteps
131 } while (v < Convert.ToDouble(this.dataGridPhi.Rows[0].Cells[1].Value) + 1e-10); // v <= phiMax
132
133 foreach (double phiValue in philist)
134 {
135 phi.FirstRecord().Value = phiValue;
136 mi.Solve();
137 double obj = mi.SyncDB.GetVariable("z").FindRecord().Level;
138 string[] row = new string[] { phiValue.ToString("0.00"), mi.ModelStatus.ToString(), mi.SolveStatus.ToString(), obj.ToString("0.00") };
139 this.dataGridView1.Rows.Add(row);
140
141 List<Tuple<String,String, double>> l = new List<Tuple<String,String, double>>();
142 foreach(GAMSVariableRecord rec in mi.SyncDB.GetVariable("x"))
143 l.Add(new Tuple<string, string, double>(rec.Key(0),rec.Key(1),rec.Level));
144
145 this.resultX.Add(phiValue.ToString("0.00"), l);
146
147 if (mi.ModelStatus == ModelStat.OptimalGlobal || mi.ModelStatus == ModelStat.OptimalLocal)
148 {
149 this.chart1.Series["cost"].Points.AddXY(phiValue, obj);
150 this.chart1.Update();
151 }
152 }
153 this.updateResultX();
154 }
155
156 private void button2_Click(object sender, EventArgs e)
157 {
158 OpenFileDialog browser = new OpenFileDialog();
159
160 browser.DefaultExt = "accdb";
161 browser.Filter = "Access Database (*.accdb)|*.accdb";
162 browser.InitialDirectory = Environment.CurrentDirectory;
163
164 if (browser.ShowDialog() == DialogResult.OK)
165 {
166 // read from access database
167 OleDbConnection connection = null;
168 try
169 {
170 connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + browser.FileName);
171
172 // read distance
173 this.dataGridDistance.Rows.Clear();
174 OleDbCommand cmd = new OleDbCommand("SELECT Plant, Market, Distance FROM Distance", connection);
175 connection.Open();
176 OleDbDataReader reader = cmd.ExecuteReader();
177 while (reader.Read())
178 this.dataGridDistance.Rows.Add(new string[] { reader.GetString(0), reader.GetString(1), reader.GetValue(2).ToString() });
179
180 // read capacity
181 this.dataGridCapacity.Rows.Clear();
182 cmd = new OleDbCommand("SELECT Plant, Capacity FROM Plant", connection);
183 reader = cmd.ExecuteReader();
184 while (reader.Read())
185 this.dataGridCapacity.Rows.Add(new string[] { reader.GetString(0), reader.GetValue(1).ToString() });
186
187 // read demand
188 this.dataGridDemand.Rows.Clear();
189 cmd = new OleDbCommand("SELECT Market, Demand FROM Market", connection);
190 reader = cmd.ExecuteReader();
191 while (reader.Read())
192 this.dataGridDemand.Rows.Add(new string[] { reader.GetString(0), reader.GetValue(1).ToString() });
193 connection.Close();
194 }
195 catch (Exception ex)
196 {
197 MessageBox.Show("Error reading data from database. \n" + ex.Message);
198 connection.Close();
199 Environment.Exit(1);
200 }
201 }
202 }
203
204 private void dgvCellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
205 {
206 ((DataGridView)sender).Tag = ((DataGridView)sender).Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
207 }
208
209 private void dgvCellEndEdit(object sender, DataGridViewCellEventArgs e)
210 {
211 DataGridView dgv = ((DataGridView)sender);
212 object value = dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
213
214 // a set element was added or changed
215 if (e.ColumnIndex == 0)
216 {
217 int colIdx;
218 if (dgv.Equals(this.dataGridCapacity))
219 colIdx = 0;
220 else
221 colIdx = 1;
222
223 // a new row was added
224 if ((dgv.Tag == null || dgv.Tag.Equals(String.Empty)) && value != null && !value.Equals(String.Empty))
225 {
226 // we added to capacity
227 if (colIdx == 0)
228 for (int i = 0; i < this.dataGridDemand.Rows.Count - 1; i++)
229 this.dataGridDistance.Rows.Add(value, this.dataGridDemand.Rows[i].Cells[0].Value);
230 // we added to demand
231 else
232 for (int i = 0; i < this.dataGridCapacity.Rows.Count - 1; i++)
233 this.dataGridDistance.Rows.Add(this.dataGridCapacity.Rows[i].Cells[0].Value, value);
234 }
235
236 // we changed an already existing set element
237 else
238 {
239 foreach (DataGridViewRow r in this.dataGridDistance.Rows)
240 if (r.Cells[colIdx].Value.Equals(dgv.Tag))
241 r.Cells[colIdx].Value = dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
242 }
243 }
244 }
245
246 private void dgvSelectionChanged(object sender, EventArgs e)
247 {
248 if (((DataGridView)sender).SelectedRows.Count != 0)
249 ((DataGridView)sender).Tag = ((DataGridView)sender).SelectedRows[0].Cells[0].Value;
250 }
251
252 private void dgvRowsRemoved(object sender, DataGridViewRowEventArgs e)
253 {
254 DataGridView dgv = ((DataGridView)sender);
255 int colIdx;
256 if (dgv.Equals(this.dataGridCapacity))
257 colIdx = 0;
258 else
259 colIdx = 1;
260 for (int i = this.dataGridDistance.RowCount - 1; i >= 0; i--)
261 {
262 DataGridViewRow r = this.dataGridDistance.Rows[i];
263 if (r.Cells[colIdx].Value.Equals(dgv.Tag))
264 this.dataGridDistance.Rows.Remove(r);
265 }
266 }
267
268 private void updateResultX()
269 {
270 this.dataGridViewX.Rows.Clear();
271 string selectedPhi = this.dataGridView1.SelectedRows[0].Cells[0].Value.ToString();
272 foreach (Tuple<string, string, double> row in this.resultX[selectedPhi])
273 this.dataGridViewX.Rows.Add(row.Item1, row.Item2, row.Item3.ToString("0.00"));
274 }
275
276 private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
277 {
278 this.updateResultX();
279 }
280
281
282 static String GetModelText()
283 {
284 String model = @"
285 Sets
286 i canning plants
287 j markets;
288
289 Parameters
290
291 a(i) capacity of plant i in cases
292
293 b(j) demand at market j in cases
294
295 d(i,j) distance in thousands of miles;
296
297$gdxin data
298$load i j a b d
299
300
301 Scalar f freight in dollars per case per thousand miles /90/ ;
302 Scalar phi demand and cost elasticity factor /1/;
303
304 Parameter c(i,j) transport cost in thousands of dollars per case ;
305
306 c(i,j) = f * d(i,j) / 1000 ;
307
308 Variables
309 x(i,j) shipment quantities in cases
310 z total transportation costs in thousands of dollars ;
311
312 Positive Variable x ;
313
314 Equations
315 cost define objective function
316 supply(i) observe supply limit at plant i
317 demand(j) satisfy demand at market j ;
318
319 cost .. z =e= sum((i,j), c(i,j)*x(i,j)**phi) ;
320
321 supply(i) .. sum(j, x(i,j)) =l= a(i) ;
322
323 demand(j) .. sum(i, x(i,j)) =g= sqr(1-phi)*b(j) ;
324
325 Model transport /all/ ;
326";
327
328 return model;
329 }
330 }
331}
GAMSModelInstance AddModelInstance(string modelInstanceName=null)
GAMSParameter AddParameter(string identifier, int dimension, string explanatoryText="")
void Run(GAMSOptions gamsOptions=null, GAMSCheckpoint checkpoint=null, TextWriter output=null, Boolean createOutDB=true)
void Instantiate(string modelDefinition, params GAMSModifier[] modifiers)
new GAMSParameterRecord AddRecord(params string[] keys)
new GAMSSetRecord AddRecord(params string[] keys)
string Key(int index)
In this example a series of transportation problems is solved using GAMSModelInstance....
Definition: Form1.cs:25