1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 | using System.Linq;
|
---|
4 | using HeuristicLab.Core;
|
---|
5 | using HeuristicLab.Data;
|
---|
6 | using HeuristicLab.Encodings.IntegerVectorEncoding;
|
---|
7 | using HeuristicLab.Optimization;
|
---|
8 | using HeuristicLab.Problems.Scheduling.MRCPSP;
|
---|
9 | using Microsoft.VisualStudio.TestTools.UnitTesting;
|
---|
10 | using SimSharp;
|
---|
11 | using Environment = SimSharp.Environment;
|
---|
12 |
|
---|
13 | namespace UnitTestProject {
|
---|
14 | [TestClass]
|
---|
15 | public class UnitTest {
|
---|
16 |
|
---|
17 | [TestMethod]
|
---|
18 | public void Import() {
|
---|
19 | var problem = MultiModeFileImporter.Import(@"C:\Users\P41826\FH OÖ FileBox\MRCPSP\MRCPSP_BenchmarkData\mmlib 50\mmlib50.mm\J501_1.mm");
|
---|
20 | }
|
---|
21 |
|
---|
22 | [TestMethod]
|
---|
23 | public void TestMethod1() {
|
---|
24 | Console.Write(Evaluate());
|
---|
25 | }
|
---|
26 |
|
---|
27 | public ItemList<Activity> Activities { get; set; } = new ItemList<Activity>();
|
---|
28 | public ItemList<ResourceCapacity> ResourceCapacities { get; set; } = new ItemList<ResourceCapacity>();
|
---|
29 |
|
---|
30 | public UnitTest() {
|
---|
31 |
|
---|
32 | var RR = new ResourceCapacity { Number = 1, Capacity = 7, IsRenewable = true };
|
---|
33 | var RN = new ResourceCapacity { Number = 2, Capacity = 23, IsRenewable = false };
|
---|
34 |
|
---|
35 | ResourceCapacities.Add(RR);
|
---|
36 | ResourceCapacities.Add(RN);
|
---|
37 |
|
---|
38 |
|
---|
39 | var A = new List<Tuple<int, int, int, int, int>>
|
---|
40 | {
|
---|
41 | Tuple.Create(1, 1, 4, 3, 3),
|
---|
42 | Tuple.Create(1, 2, 5, 2, 4),
|
---|
43 | Tuple.Create(2, 1, 1, 3, 4),
|
---|
44 | Tuple.Create(2, 2, 2, 2, 3),
|
---|
45 | Tuple.Create(3, 1, 1, 2, 3),
|
---|
46 | Tuple.Create(3, 2, 2, 1, 1),
|
---|
47 | Tuple.Create(4, 1, 2, 5, 4),
|
---|
48 | Tuple.Create(4, 2, 3, 4, 3),
|
---|
49 | Tuple.Create(5, 1, 2, 4, 6),
|
---|
50 | Tuple.Create(5, 2, 5, 3, 2),
|
---|
51 | Tuple.Create(6, 1, 1, 1, 4),
|
---|
52 | Tuple.Create(6, 2, 3, 1, 3),
|
---|
53 | Tuple.Create(7, 1, 1, 3, 3),
|
---|
54 | Tuple.Create(7, 2, 3, 2, 2),
|
---|
55 | Tuple.Create(8, 1, 2, 3, 4),
|
---|
56 | Tuple.Create(8, 2, 2, 3, 3)
|
---|
57 | };
|
---|
58 | var S = new Dictionary<int, List<int>>
|
---|
59 | {
|
---|
60 | {0, new List<int> {1, 2, 3}},
|
---|
61 | {1, new List<int> {7}},
|
---|
62 | {2, new List<int> {4, 5}},
|
---|
63 | {3, new List<int> {9}},
|
---|
64 | {4, new List<int> {6}},
|
---|
65 | {5, new List<int> {9}},
|
---|
66 | {6, new List<int> {7, 8}},
|
---|
67 | {7, new List<int> {9}},
|
---|
68 | {8, new List<int> {9}},
|
---|
69 | {9, new List<int>()}
|
---|
70 | };
|
---|
71 |
|
---|
72 | Activities = new ItemList<Activity>(Enumerable.Range(0, 10).Select(i => new Activity { Number = i }).ToList());
|
---|
73 | Activities[0].Modes.Add(new Mode { Number = 1 });
|
---|
74 | foreach (var a in A) {
|
---|
75 | Activities[a.Item1].Modes.Add(new Mode {
|
---|
76 | Number = a.Item2,
|
---|
77 | Duration = a.Item3,
|
---|
78 | ResourceDemands = new ItemList<ResourceDemand>
|
---|
79 | {
|
---|
80 | new ResourceDemand {Number = 1, Demand = a.Item4},
|
---|
81 | new ResourceDemand {Number = 2, Demand = a.Item5}
|
---|
82 | }
|
---|
83 | });
|
---|
84 | }
|
---|
85 |
|
---|
86 | Activities[9].Modes.Add(new Mode { Number = 1 });
|
---|
87 | foreach (var s in S) {
|
---|
88 | Activities[s.Key].Successors = new ItemList<IntValue>(s.Value.Select(x => new IntValue(x)));
|
---|
89 | }
|
---|
90 | }
|
---|
91 |
|
---|
92 | public MultiEncoding Encoding { get; set; }
|
---|
93 |
|
---|
94 | public double Evaluate() {
|
---|
95 | var randomKey = new IntegerVector(new[] { 1, 2, 3, 4, 5, 6, 7, 8 });
|
---|
96 | var modeList = new IntegerVector(new[] { 1, 1, 2, 2, 2, 1, 1, 2 });
|
---|
97 |
|
---|
98 | var activities = new List<Tuple<Activity, int, int>>(Activities.Count);
|
---|
99 | var dependencies = new Dictionary<int, List<int>>(Activities.Count);
|
---|
100 | activities.Add( /*[Activities[0].Number] =*/ Tuple.Create(Activities[0], int.MinValue, 1));
|
---|
101 | dependencies[Activities[0].Number] = new List<int>();
|
---|
102 | for (var i = 1; i < Activities.Count - 1; i++) {
|
---|
103 | activities.Add( /*[Activities[i].Number] =*/ Tuple.Create(Activities[i], randomKey[i - 1], modeList[i - 1]));
|
---|
104 | dependencies[Activities[i].Number] = new List<int>();
|
---|
105 | }
|
---|
106 |
|
---|
107 | activities.Add( /*[Activities[Activities.Count - 1].Number] =*/
|
---|
108 | Tuple.Create(Activities[Activities[Activities.Count - 1].Number], int.MaxValue, 1));
|
---|
109 | dependencies[Activities[Activities.Count - 1].Number] = new List<int>();
|
---|
110 |
|
---|
111 | foreach (var activity in Activities) {
|
---|
112 | foreach (var successor in activity.Successors) {
|
---|
113 | dependencies[successor.Value].Add(activity.Number);
|
---|
114 | }
|
---|
115 | }
|
---|
116 |
|
---|
117 | activities = activities.OrderBy(a => a.Item2).ToList();
|
---|
118 |
|
---|
119 | var env = new Environment();
|
---|
120 | var procActivities = new Dictionary<int, Process>();
|
---|
121 |
|
---|
122 | var resources = new Dictionary<int, Container>();
|
---|
123 | foreach (var resource in ResourceCapacities.Where(r => r.IsRenewable)) {
|
---|
124 | resources.Add(resource.Number, new Container(env, resource.Capacity, resource.Capacity));
|
---|
125 | }
|
---|
126 |
|
---|
127 | var nonrenRes = new Dictionary<int, Container>();
|
---|
128 | foreach (var resource in ResourceCapacities.Where(r => !r.IsRenewable)) {
|
---|
129 | nonrenRes.Add(resource.Number, new Container(env, resource.Capacity, resource.Capacity));
|
---|
130 | }
|
---|
131 |
|
---|
132 | foreach (var act in activities) {
|
---|
133 | procActivities[act.Item1.Number] = env.Process(Job(env, procActivities, act, resources, nonrenRes,
|
---|
134 | dependencies[act.Item1.Number]));
|
---|
135 | }
|
---|
136 |
|
---|
137 | // fitness function by Hartmann (2001)
|
---|
138 | try {
|
---|
139 | env.Run();
|
---|
140 | } catch (InvalidOperationException) {
|
---|
141 | var T = Activities.Sum(a => a.Modes.Max(m =>
|
---|
142 | m.ResourceDemands.Where(d => ResourceCapacities.Single(c => c.Number == d.Number).IsRenewable)
|
---|
143 | .Sum(d => d.Demand)));
|
---|
144 | var ERR = activities.Sum(a => a.Item1.Modes[a.Item3 - 1].ResourceDemands
|
---|
145 | .Where(d => !ResourceCapacities.Single(c => c.Number == d.Number).IsRenewable).Sum(r => r.Demand));
|
---|
146 |
|
---|
147 | return T + ERR;
|
---|
148 | }
|
---|
149 |
|
---|
150 | return env.NowD;
|
---|
151 | }
|
---|
152 |
|
---|
153 | private bool IsRenewable(int resourceNumber) => ResourceCapacities.Single(r => r.Number == resourceNumber).IsRenewable;
|
---|
154 |
|
---|
155 | private IEnumerable<Event> Job(Environment env, Dictionary<int, Process> procActivities, Tuple<Activity, int, int> act,
|
---|
156 | Dictionary<int, Container> resources, Dictionary<int, Container> nonrenRes, IEnumerable<int> deps) {
|
---|
157 | var mode = act.Item1.Modes[act.Item3 - 1];
|
---|
158 | var timeout = mode.Duration;
|
---|
159 | var demands = mode.ResourceDemands.Where(r => r.Demand > 0);
|
---|
160 | var res = demands.Where(r => IsRenewable(r.Number)).Select(r => Tuple.Create(resources[r.Number], r.Demand, r.Number));
|
---|
161 | var nres = demands.Where(r => !IsRenewable(r.Number)).Select(r => Tuple.Create(nonrenRes[r.Number], r.Demand, r.Number));
|
---|
162 |
|
---|
163 | yield return new AllOf(env, deps.Select(d => procActivities[d]));
|
---|
164 | //Console.WriteLine(act.Item1.Number + " B " + env.NowD);
|
---|
165 |
|
---|
166 | foreach (var nr in nres) {
|
---|
167 | if (nr.Item2 > nonrenRes[nr.Item3].Level)
|
---|
168 | throw new InvalidOperationException();
|
---|
169 | yield return nonrenRes[nr.Item3].Get(nr.Item2);
|
---|
170 | }
|
---|
171 |
|
---|
172 | foreach (var r in res) {
|
---|
173 | yield return r.Item1.Get(r.Item2);
|
---|
174 | yield return env.TimeoutD(timeout);
|
---|
175 | yield return r.Item1.Put(r.Item2);
|
---|
176 | //for (var t = 0; t < r.Item2; t++) {
|
---|
177 | // using (var req = r.Item1.Request()) {
|
---|
178 | // yield return req;
|
---|
179 | // yield return env.TimeoutD(timeout);
|
---|
180 | // }
|
---|
181 | //}
|
---|
182 | //Console.WriteLine(act.Item1.Number + " E " + env.NowD);
|
---|
183 | }
|
---|
184 | }
|
---|
185 | }
|
---|
186 | }
|
---|
187 |
|
---|