Lets gooooo

This commit is contained in:
Zastian Pretorius
2022-08-02 12:42:49 +01:00
parent 782f31810c
commit eb9f7c6c67
88 changed files with 3246 additions and 2066 deletions

180
Presentation/MainMenu.cs Normal file
View File

@@ -0,0 +1,180 @@
using BusinessLogic;
using BusinessLogic.Algorithms;
using Common;
using DataAccess;
using Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Presentation
{
public class MainMenu
{
public static void Run()
{
Model model = new Model();
try
{
Console.Clear();
Console.WriteLine("Welcome to the solver");
Console.WriteLine("=========================================================================================================");
Console.WriteLine("To get started, choose a premade text file that contains the model you would like to solve:");
Console.WriteLine("\nlimpopo.txt\nsanta.txt\nkorean.txt\nfarmer.txt\nbranch.txt\ncut.txt\nacme.txt\n");
string modelPath = Console.ReadLine();
Console.WriteLine("=========================================================================================================");
model = ModelReader.ReadModelFromFile(modelPath);
SolveModelUsingAlgorithm(model);
}
catch (CustomException ex)
{
Console.WriteLine($"There was an error. Details: {ex.Message}.");
Console.WriteLine("\nHere are the tables that were calculated before we ran into that error:");
SolvedModelPrinter.Print(model);
Console.WriteLine("\n\nPress any key to continue. . .");
Console.ReadKey();
Run();
}
catch (InfeasibleException ex)
{
Console.WriteLine($"There was an error. Details: {ex.Message}.");
Console.WriteLine("\nHere are the tables that were calculated before we ran into that error:");
SolvedModelPrinter.Print(model);
Console.WriteLine("\n\nPress any key to continue. . .");
Console.ReadKey();
Run();
}
catch (Exception ex)
{
Console.WriteLine($"There was an error. Details: {ex.Message}.");
Console.WriteLine("\nHere are the tables that were calculated before we ran into that error:");
SolvedModelPrinter.Print(model);
Console.WriteLine("\n\nPress any key to continue. . .");
Console.ReadKey();
Run();
}
}
private static void SolveModelUsingAlgorithm(Model model)
{
Console.Clear();
Console.WriteLine("Great! Now that we have your model, the next step is to choose an algorithm to solve it with.");
Console.WriteLine("Based on factors in your model, these are the available algorithms you can use:");
Console.WriteLine("=========================================================================================================");
string userInput;
Algorithm algorithm;
if (model.SignRestrictions.Contains(SignRestriction.Binary) || model.SignRestrictions.Contains(SignRestriction.Integer))
{
Console.WriteLine("BNB - Branch and Bound Simplex Algorithm");
Console.WriteLine("CP - Cutting Plane Algorithm");
userInput = Console.ReadLine();
switch (userInput.ToUpper())
{
case "BNB":
{
algorithm = new BranchAndBoundSimplex();
}
break;
case "CP":
{
algorithm = new CuttingPlane();
}
break;
default:
{
throw new CustomException("Invalid selection made");
}
}
}
else if (model.ProblemType == ProblemType.Minimization)
{
Console.WriteLine("DS - Dual Simplex Algorithm");
Console.WriteLine("TPS - Two Phase Simplex Algorithm");
userInput = Console.ReadLine();
switch (userInput.ToUpper())
{
case "DS":
{
algorithm = new DualSimplex();
}
break;
case "TPS":
{
algorithm = new TwoPhaseSimplex();
}
break;
default:
{
throw new CustomException("Invalid selection made");
}
}
}
else
{
if (!(model.Constraints.Any(c => c.InequalitySign == InequalitySign.EqualTo) ||
model.Constraints.Any(c => c.InequalitySign == InequalitySign.GreaterThanOrEqualTo)))
{
Console.WriteLine("PS - Primal Simplex");
userInput = Console.ReadLine();
switch (userInput.ToUpper())
{
case "PS":
{
algorithm = new PrimalSimplex();
}
break;
default:
{
throw new CustomException("Invalid selection made");
}
}
}
else
{
Console.WriteLine("DS - Dual Simplex Algorithm");
Console.WriteLine("TPS - Two Phase Simplex Algorithm");
userInput = Console.ReadLine();
switch (userInput.ToUpper())
{
case "DS":
{
algorithm = new DualSimplex();
}
break;
case "TPS":
{
algorithm = new TwoPhaseSimplex();
}
break;
default:
{
throw new CustomException("Invalid selection made");
}
}
}
}
ModelSolver.Solve(model, algorithm);
if (algorithm.GetType() == typeof(BranchAndBoundSimplex))
{
SolvedModelPrinter.Print((BranchAndBoundSimplex)algorithm);
ModelWriter.WriteResultsToFile((BranchAndBoundSimplex)algorithm);
}
else
{
SolvedModelPrinter.Print(model);
ModelWriter.WriteResultsToFile(model);
}
}
}
}

121
Presentation/ModelWriter.cs Normal file
View File

@@ -0,0 +1,121 @@
using BusinessLogic.Algorithms;
using Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Presentation
{
public class ModelWriter
{
public static void WriteResultsToFile(Model model)
{
var fileName = Guid.NewGuid().ToString() + ".txt";
using (FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
using (StreamWriter writer = new StreamWriter(stream))
{
int iteration = 0;
foreach (var table in model.Result)
{
writer.WriteLine($"\n\nTable {iteration}:");
for (int i = 0; i < table.Count; i++)
{
for (int j = 0; j < table[0].Count; j++)
{
writer.Write($"\t{table[i][j]:0.###}");
}
writer.WriteLine();
}
iteration++;
}
}
}
Console.WriteLine($"\n\nThe results have been written to the file: {fileName}");
}
public static void WriteResultsToFile(BranchAndBoundSimplex branchAndBoundSimplex)
{
var fileName = Guid.NewGuid().ToString() + ".txt";
using (FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
using (StreamWriter writer = new StreamWriter(stream))
{
var tree = branchAndBoundSimplex.Results;
WriteBranchResults(tree.Root, writer);
List<List<double>> bestCandidate = branchAndBoundSimplex.GetBestCandidate();
writer.WriteLine("\n\nThis is the best solution of all the candidates:\n");
for (int i = 0; i < bestCandidate.Count; i++)
{
for (int j = 0; j < bestCandidate[i].Count; j++)
{
writer.Write($"\t{bestCandidate[i][j]:0.###}");
}
writer.WriteLine();
}
}
}
Console.WriteLine($"\n\nThe results have been written to the file: {fileName}");
}
private static void WriteBranchResults(BusinessLogic.BinaryTreeNode root, StreamWriter writer, string previousProblem = "0")
{
if (root == null)
return;
if (previousProblem.Equals("0"))
{
writer.WriteLine("\n\n");
writer.WriteLine("Sub-Problem 0");
for (int i = 0; i < root.Data.Count; i++)
{
for (int j = 0; j < root.Data[i].Count; j++)
{
for (int k = 0; k < root.Data[i][j].Count; k++)
{
writer.Write($"\t{root.Data[i][j][k]:0.###}");
}
writer.WriteLine();
}
writer.WriteLine("\n\n");
}
WriteBranchResults(root.LeftNode, writer, "1");
WriteBranchResults(root.RightNode, writer, "2");
}
else
{
writer.WriteLine("\n\n");
writer.WriteLine($"Sub-Problem {previousProblem}");
for (int i = 0; i < root.Data.Count; i++)
{
for (int j = 0; j < root.Data[i].Count; j++)
{
for (int k = 0; k < root.Data[i][j].Count; k++)
{
writer.Write($"\t{root.Data[i][j][k]:0.###}");
}
writer.WriteLine();
}
writer.WriteLine("\n\n");
}
WriteBranchResults(root.LeftNode, writer, previousProblem + ".1");
WriteBranchResults(root.RightNode, writer, previousProblem + ".2");
}
}
}
}

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{377D38FE-AA9D-4AB0-B743-9E80AA0C82C4}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Presentation</RootNamespace>
<AssemblyName>Presentation</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="ConsoleTables, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ConsoleTables.2.4.2\lib\net40\ConsoleTables.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MainMenu.cs" />
<Compile Include="ModelWriter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SolvedModelPrinter.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BusinessLogic\BusinessLogic.csproj">
<Project>{F904DA9B-8BA5-4803-88C1-24A6471C7FEF}</Project>
<Name>BusinessLogic</Name>
</ProjectReference>
<ProjectReference Include="..\DataAccess\DataAccess.csproj">
<Project>{02E85643-5DA8-4A1E-AF07-10184FC132A0}</Project>
<Name>DataAccess</Name>
</ProjectReference>
<ProjectReference Include="..\Models\Common.csproj">
<Project>{04C11623-F02E-45C6-8C51-82244CFF4780}</Project>
<Name>Common</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Presentation")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Presentation")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("377d38fe-aa9d-4ab0-b743-9e80aa0c82c4")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,112 @@
using BusinessLogic;
using BusinessLogic.Algorithms;
using Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConsoleTables;
namespace Presentation
{
public class SolvedModelPrinter
{
public static void Print(Model model)
{
int iteration = 0;
foreach (var table in model.Result)
{
Console.WriteLine($"\n\nTable {iteration}:");
string[] headers = new string[table[0].Count];
string temp = "";
for (int j = 0; j < table[0].Count; j++)
{
temp = table[0][j].ToString();
headers[j] = temp;
}
table.RemoveAt(0);
var conTable = new ConsoleTable(headers);
foreach (List<double> row in table)
{
object[] rowArray = new object[row.Count];
for (int i = 0; i < row.Count; i++)
{
rowArray[i] = row[i];
}
conTable.AddRow(rowArray);
}
Console.WriteLine();
iteration++;
conTable.Write(Format.Alternative);
}
}
public static void Print(BranchAndBoundSimplex branchAndBoundSimplex)
{
var tree = branchAndBoundSimplex.Results;
PrintBranchResults(tree.Root);
List<List<double>> bestCandidate = branchAndBoundSimplex.GetBestCandidate();
Console.WriteLine("\n\nThis is the best solution of all the candidates:\n");
for (int i = 0; i < bestCandidate.Count; i++)
{
for (int j = 0; j < bestCandidate[i].Count; j++)
{
Console.Write($"\t{bestCandidate[i][j]:0.###}");
}
Console.WriteLine();
}
}
private static void PrintBranchResults(BinaryTreeNode root, string previousProblem = "0")
{
if (root == null)
return;
if (previousProblem.Equals("0"))
{
Console.WriteLine("\n\n");
Console.WriteLine("Sub-Problem 0");
for (int i = 0; i < root.Data.Count; i++)
{
for (int j = 0; j < root.Data[i].Count; j++)
{
for (int k = 0; k < root.Data[i][j].Count; k++)
{
Console.Write($"\t{root.Data[i][j][k]:0.###}");
}
Console.WriteLine();
}
Console.WriteLine("\n\n");
}
PrintBranchResults(root.LeftNode, "1");
PrintBranchResults(root.RightNode, "2");
}
else
{
Console.WriteLine("\n\n");
Console.WriteLine($"Sub-Problem {previousProblem}");
for (int i = 0; i < root.Data.Count; i++)
{
for (int j = 0; j < root.Data[i].Count; j++)
{
for (int k = 0; k < root.Data[i][j].Count; k++)
{
Console.Write($"\t{root.Data[i][j][k]:0.###}");
}
Console.WriteLine();
}
Console.WriteLine("\n\n");
}
PrintBranchResults(root.LeftNode, previousProblem + ".1");
PrintBranchResults(root.RightNode, previousProblem + ".2");
}
}
}
}

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="ConsoleTables" version="2.4.2" targetFramework="net48" />
</packages>