251 lines
8.4 KiB
C#
251 lines
8.4 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Diagnostics;
|
||
using System.IO;
|
||
using System.Linq;
|
||
|
||
namespace TMI_practicum
|
||
{
|
||
internal static class Program
|
||
{
|
||
public static void Main(string[] args)
|
||
{
|
||
if (args.Length == 0 && !File.Exists("input.txt"))
|
||
{
|
||
Console.WriteLine("Please enter a file.");
|
||
Environment.Exit(1);
|
||
}
|
||
|
||
var inputFile = "input.txt";
|
||
if (args.Length != 0) inputFile = args[0];
|
||
|
||
if (!File.Exists(inputFile))
|
||
{
|
||
Console.WriteLine("File {0} not found.", inputFile);
|
||
Environment.Exit(1);
|
||
}
|
||
|
||
|
||
(byte algorithm, _, IList<Circle> circles) = ParseFile(inputFile);
|
||
|
||
|
||
var stopwatch = new Stopwatch();
|
||
IEnumerable<Intersection> solved;
|
||
|
||
stopwatch.Start();
|
||
|
||
switch (algorithm)
|
||
{
|
||
case 1:
|
||
solved = SimpleAlgorithm.Solve(circles);
|
||
break;
|
||
case 2:
|
||
solved = SweepLineAlgorithm.Solve(circles);
|
||
break;
|
||
case 3:
|
||
solved = SweepLineEffAlgorithm.Solve(circles);
|
||
break;
|
||
default:
|
||
if (File.Exists(OutputFile))
|
||
{
|
||
File.Delete(OutputFile);
|
||
}
|
||
|
||
using (StreamWriter sw = File.CreateText(OutputFile))
|
||
{
|
||
sw.WriteLine("Dit algoritme is niet ge ̈ımplementeerd.");
|
||
}
|
||
|
||
throw new ArgumentException("Algorithm with id: " + algorithm + " is not defined!");
|
||
}
|
||
|
||
stopwatch.Stop();
|
||
WriteOutput(solved, stopwatch.ElapsedMilliseconds);
|
||
}
|
||
|
||
|
||
private static void CheckAlgo()
|
||
{
|
||
bool failed = false;
|
||
|
||
int i = 0;
|
||
while (!failed)
|
||
{
|
||
Console.WriteLine("start check {0}", i++);
|
||
var circles = CreateRandomCircles(5);
|
||
|
||
var correctSol = SweepLineAlgorithm.Solve(circles);
|
||
var solved = SweepLineEffAlgorithm.Solve(circles);
|
||
|
||
foreach (var intersection in correctSol)
|
||
{
|
||
if (solved.Contains(intersection)) continue;
|
||
|
||
if (solved.Contains(new Intersection(intersection.X + 1e-15, intersection.Y)) ||
|
||
solved.Contains(new Intersection(intersection.X - 1e-15, intersection.Y)) ||
|
||
solved.Contains(new Intersection(intersection.X + 1e-15, intersection.Y + 1e-15)) ||
|
||
solved.Contains(new Intersection(intersection.X + 1e-15, intersection.Y - 1e-15)) ||
|
||
solved.Contains(new Intersection(intersection.X - 1e-15, intersection.Y + 1e-15)) ||
|
||
solved.Contains(new Intersection(intersection.X - 1e-15, intersection.Y - 1e-15)) ||
|
||
solved.Contains(new Intersection(intersection.X, intersection.Y + 1e-15)) ||
|
||
solved.Contains(new Intersection(intersection.X, intersection.Y - 1e-15))
|
||
) continue;
|
||
|
||
bool found = solved.Any(ints =>
|
||
Math.Abs(ints.X - intersection.X) < 1e-12 && Math.Abs(ints.Y - intersection.Y) < 1e-12);
|
||
|
||
if (found) continue;
|
||
|
||
Console.WriteLine(InCircles(circles));
|
||
|
||
failed = true;
|
||
Console.WriteLine("Not found: {0}\t{1}", intersection.X, intersection.Y);
|
||
Console.WriteLine("correct");
|
||
foreach (var intersection1 in correctSol)
|
||
{
|
||
Console.WriteLine("{0}\t{1}", intersection1.X, intersection1.Y);
|
||
}
|
||
|
||
Console.WriteLine("wrong");
|
||
foreach (var intersection1 in solved)
|
||
{
|
||
Console.WriteLine("{0}\t{1}", intersection1.X, intersection1.Y);
|
||
}
|
||
|
||
Console.WriteLine("Cirkels");
|
||
foreach (var circle in circles)
|
||
{
|
||
Console.WriteLine("(x-{0})^2 + (y-{1})^2 = {2}^2", circle.X, circle.Y, circle.R);
|
||
}
|
||
|
||
foreach (var circle in circles)
|
||
{
|
||
Console.WriteLine("{0} {1} {2}", circle.X, circle.Y, circle.R);
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
private static List<Circle> CreateRandomCircles(double amount)
|
||
{
|
||
var circles = new List<Circle>();
|
||
Random rnd = new Random();
|
||
|
||
for (int i = 0; i < amount; i++)
|
||
{
|
||
circles.Add(new Circle(Math.Round(rnd.NextDouble() * 1.0, 15), Math.Round(rnd.NextDouble() * 1.0, 15),
|
||
Math.Round(rnd.NextDouble() * (1.0 / amount), 15)));
|
||
}
|
||
|
||
return circles;
|
||
}
|
||
|
||
private static void GetChartData()
|
||
{
|
||
var stopwatch = new Stopwatch();
|
||
|
||
//warmup
|
||
var circles = CreateRandomCircles(20);
|
||
IEnumerable<Intersection> solved = SweepLineEffAlgorithm.Solve(circles);
|
||
var times = new List<long>();
|
||
|
||
Console.WriteLine("size, time");
|
||
|
||
for (int s = 10; s < 100000; s *= 2)
|
||
{
|
||
for (int i = 0; i < 100; i++)
|
||
{
|
||
circles = CreateRandomCircles(s);
|
||
|
||
stopwatch.Restart();
|
||
solved = SweepLineEffAlgorithm.Solve(circles);
|
||
stopwatch.Stop();
|
||
times.Add(stopwatch.ElapsedMilliseconds);
|
||
}
|
||
|
||
Console.WriteLine("{0}, {1}", s, times.Average());
|
||
times.Clear();
|
||
}
|
||
|
||
stopwatch.Stop();
|
||
}
|
||
|
||
private static (byte Algorithm, int NbCircles, IList<Circle> Circles) ParseFile(string path)
|
||
{
|
||
byte algorithm = 0;
|
||
int nbCircles = 0;
|
||
Circle[] circles = null;
|
||
|
||
using (StreamReader file = new StreamReader(path))
|
||
{
|
||
try
|
||
{
|
||
algorithm = byte.Parse(file.ReadLine());
|
||
nbCircles = int.Parse(file.ReadLine());
|
||
circles = new Circle[nbCircles];
|
||
string line;
|
||
int i = 0;
|
||
while ((line = file.ReadLine()) != null)
|
||
{
|
||
double[] parts = line.Split(' ').Where(x => x.Length != 0).Select(double.Parse).ToArray();
|
||
if (parts.Length == 0) continue;
|
||
|
||
circles[i++] = new Circle(parts[0], parts[1], parts[2]);
|
||
}
|
||
}
|
||
catch (Exception)
|
||
{
|
||
Console.WriteLine("An error occured parsing the input file.\r\n" +
|
||
"Make sure the file has all required values and consists only of numbers.");
|
||
Environment.Exit(1);
|
||
}
|
||
}
|
||
|
||
return (algorithm, nbCircles, circles);
|
||
}
|
||
|
||
private const string OutputFile = "output.txt";
|
||
|
||
private static void WriteOutput(IEnumerable<Intersection> intersections, double time)
|
||
{
|
||
if (File.Exists(OutputFile))
|
||
{
|
||
File.Delete(OutputFile);
|
||
}
|
||
|
||
using (StreamWriter sw = File.CreateText(OutputFile))
|
||
{
|
||
foreach (Intersection intersection in intersections)
|
||
{
|
||
sw.WriteLine("{0:0.000000000000000}\t{1:0.000000000000000}", intersection.X, intersection.Y);
|
||
}
|
||
|
||
sw.WriteLine("\r\n{0}", time);
|
||
}
|
||
}
|
||
|
||
|
||
private static int InCircles(IList<Circle> circles)
|
||
{
|
||
int count = 0;
|
||
|
||
foreach (var toCheck in circles)
|
||
{
|
||
foreach (var circle in circles)
|
||
{
|
||
if (circle == toCheck) continue;
|
||
|
||
if (circle.R > toCheck.R && circle.Distance(toCheck) < circle.R &&
|
||
circle.FindIntersections(toCheck) == null)
|
||
{
|
||
count++;
|
||
}
|
||
}
|
||
}
|
||
|
||
return count;
|
||
}
|
||
}
|
||
} |