/// <summary> /// Parses the input, returning the facilities and customers /// </summary> /// <returns> A tuple containing the facilities and customers</returns> /// <param name="args">The Command-line arguments.</param> public static Tuple<Facility[], Customer[]> ParseInput(string[] args) { string fileName = null; // get the temp file name foreach (var arg in args.Where(arg => arg.StartsWith("-file="))) { fileName = arg.Substring(6); } if (fileName == null) return Tuple.Create(new Facility[0], new Customer[0]); // read the lines out of the file var lines = File.ReadAllLines(fileName); // parse the data in the file var firstLine = lines[0].Split(' '); int facilityCount = int.Parse(firstLine[0]); int customerCount = int.Parse(firstLine[1]); // build up facility and customer arrays var facilities = new Facility[facilityCount]; var customers = new Customer[customerCount]; // populate the facilities for (int i = 1; i < facilityCount + 1; i++) { var line = lines[i]; var parts = line.Split(' '); var facility = new Facility(i - 1) { SetupCost = double.Parse(parts[0], CultureInfo.InvariantCulture), Capacity = int.Parse(parts[1]), X = double.Parse(parts[2], CultureInfo.InvariantCulture), Y = double.Parse(parts[3], CultureInfo.InvariantCulture) }; facilities[i - 1] = facility; } var offset = 1 + facilityCount; // populate the customers for (int i = offset; i < offset + customerCount; i++) { var line = lines[i]; var parts = line.Split(' '); var customer = new Customer(i - offset) { Demand = int.Parse(parts[0]), X = double.Parse(parts[1], CultureInfo.InvariantCulture), Y = double.Parse(parts[2], CultureInfo.InvariantCulture) }; customers[i - offset] = customer; } return Tuple.Create(facilities, customers); }
public void FixIt(Facility[] facilities, Customer[] customers) { var sortedByAssignedCount = facilities.OrderBy(f => f.AssignedFacilityCount); Console.WriteLine(""); Console.WriteLine("***********"); foreach (var facility in sortedByAssignedCount) { Console.WriteLine("{0} {1} {2} {3}", facility.Id, facility.AssignedFacilityCount, facility.Capacity, facility.AvailableCapacity); } }
public void Execute(Facility[] facilities, Customer[] customers) { foreach (var customer in customers) { var first = facilities.FirstOrDefault(f => f.CanAssignCustomer(customer)); if (first == null) throw new Exception("something went wrong"); var actual = facilities.Aggregate(first, (curr, next) => { if (!next.CanAssignCustomer(customer)) return curr; if (next.Location.DistanceFrom(customer.Location) < curr.Location.DistanceFrom(customer.Location)) return next; return curr; }); if (actual == null) throw new Exception("something else went wrong"); if (!actual.CanAssignCustomer(customer)) throw new Exception("couldn't find one..."); actual.AssignCustomer(customer); } }
public SolutionResult Solve(Facility[] facilities, Customer[] customers) { var result = new SolutionResult(customers); var fIndex = 0; var remainingCapacity = facilities[fIndex].Capacity; var facility = facilities[fIndex]; // trivially just add while they fit foreach (var customer in customers) { while (customer.Demand > remainingCapacity) { facility = facilities[++fIndex]; remainingCapacity = facility.Capacity; } result.Map(customer, facility); remainingCapacity -= customer.Demand; } return result; }
/// <summary> /// Map the specified customer and facility. /// </summary> /// <param name="customer">Customer.</param> /// <param name="facility">Facility.</param> public void Map(Customer customer, Facility facility) { Facility oldFacility; // get rid of the old one if (customerToFacility.TryGetValue(customer, out oldFacility)) { facilityToCustomers[oldFacility].Remove(customer); } customerToFacility[customer] = facility; // unmap existing one if it's there facilityToCustomers.Add(facility, customer); // force recalculation value = null; }
/// <summary> /// Initializes a new instance of the <see cref="SolutionResult"/> class. /// </summary> /// <param name="customers">The customers.</param> public SolutionResult(Customer[] customers) { this.customers = customers; }
/// <summary> /// Calculate the distance between a facility and customer /// </summary> /// <param name="f">Facility.</param> /// <param name="c">Customer.</param> public static double Distance(Facility f, Customer c) { var dx = f.X - c.X; var dy = f.Y - c.Y; return Math.Sqrt(dx * dx + dy * dy); }