This commit is contained in:
Joel 2020-05-24 13:24:15 +02:00
commit 700979aded
11 changed files with 1048729 additions and 75 deletions

Binary file not shown.

1048576
Game1/Content/ML/Rainfall.csv Normal file

File diff suppressed because it is too large Load Diff

View File

@ -74,6 +74,7 @@ namespace Game1
cropTypesNames[11] = "Wheat";
Engine.init();
//Sources.ML_Joel.Engine.CreateModel();

View File

@ -90,6 +90,10 @@
<Compile Include="Sources\Crops\PerlinNoise.cs" />
<Compile Include="Sources\Crops\SoilProperties.cs" />
<Compile Include="Sources\ML\Engine.cs" />
<Compile Include="Sources\ML_Joel\DataModel\Input.cs" />
<Compile Include="Sources\ML_Joel\DataModel\Output.cs" />
<Compile Include="Sources\ML_Joel\Engine.cs" />
<Compile Include="Sources\ML_Joel\Model.cs" />
<Compile Include="Sources\Objects\DayNightCycle.cs" />
<Compile Include="Sources\Objects\Fertilizer.cs" />
<Compile Include="Sources\Objects\FertilizerHolder.cs" />

View File

@ -9,7 +9,12 @@ namespace Game1.Sources.ML_Joel
{
class Output
{
[ColumnName("PredictedLabel")]
//[ColumnName("PredictedLabel")]
public float Prediction { get; set; }
public float Score { get; set; }
//[ColumnName("Score")]
// public float[] Score { get; set; }
}
}

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.ML;
namespace Game1.Sources.ML_Joel
{
static class Engine
{
private static MLContext mlContext = new MLContext(seed: 1);
private static PredictionEngine<ModelInput, ModelOutput> PredictionEngine;
public static void CreateModel()
{
Model.CreateModel();
}
public static void init()
{
PredictionEngine = MLModel.CreateEngine();
}
public static string PredictFertilizer(Crops crop, CropTypes cropTypes)
{
ModelInput modelInput = new ModelInput
{
Temperature = crop.getSoilProperties().Temperature,
Humidity = crop.getSoilProperties().Humidity,
Moisture = crop.getSoilProperties().Moisture,
Soil_Type = crop.getSoilProperties().soilType,
Crop_Type = cropTypes.CropName,
Nitrogen = crop.getSoilProperties().Nitrogen,
Potassium = crop.getSoilProperties().Potassium,
Phosporous = crop.getSoilProperties().Phosphorous
};
return PredictionEngine.Predict(modelInput).Prediction;
}
}
}

View File

@ -13,56 +13,75 @@ namespace Game1.Sources.ML_Joel
class Model
{
private static MLContext mlContext = new MLContext(seed: 1);
/*
private static string path = "C:/Users/Joel/source/repos/Oskars Repo/Game1/Content/ML/Rainfall.csv";
private static string modelpath = "C:/Users/Joel/source/repos/Oskars Repo/Game1/Content/ML/MLmodel_Joel";
private static string report = "C:/Users/Joel/source/repos/Oskars Repo/Game1/Content/ML/report_Joel";
*/
private static string path = "C:/Users/Oskar/source/repos/PotatoPlanFinal/Game1/Content/ML/Rainfall.csv";
private static string modelpath = "C:/Users/Oskar/source/repos/PotatoPlanFinal/Game1/Content/ML/MLmodel_Joel";
private static string report = "C:/Users/Oskar/source/repos/PotatoPlanFinal/Game1/Content/ML/report_Joel";
// Loading data, creatin and saving ML model for smaller dataset (100)
public static void CreateModel()
{
IDataView trainingDataView = mlContext.Data.LoadFromTextFile<ModelInput>(
IDataView trainingDataView = mlContext.Data.LoadFromTextFile<Input>(
path: path,
hasHeader: true,
separatorChar: ',',
allowQuoting: true,
allowSparse: false);
ModelInput sample = mlContext.Data.CreateEnumerable<ModelInput>(trainingDataView, false).ElementAt(0);
ITransformer MLModel = BuildAndTrain(mlContext, trainingDataView, sample, report);
var splitData = mlContext.Data.TrainTestSplit(trainingDataView, testFraction: 0.2);
trainingDataView = splitData.TrainSet;
IDataView testDataView = splitData.TestSet;
Input sample = mlContext.Data.CreateEnumerable<Input>(trainingDataView, false).ElementAt(0);
ITransformer MLModel = BuildAndTrain(mlContext, trainingDataView, testDataView, sample, report);
SaveModel(mlContext, MLModel, modelpath, trainingDataView.Schema);
}
// Building and training ML model, very small dataset (100 entries)
public static ITransformer BuildAndTrain(MLContext mLContext, IDataView trainingDataView, ModelInput sample, string reportPath)
// Building and training ML model
public static ITransformer BuildAndTrain(MLContext mLContext, IDataView trainingDataView, IDataView testDataView, Input sample, string reportPath)
{
var options = new LightGbmMulticlassTrainer.Options
var options = new LightGbmRegressionTrainer.Options
{
MaximumBinCountPerFeature = 8,
LearningRate = 0.00025,
NumberOfIterations = 40000,
NumberOfLeaves = 10,
LabelColumnName = "Fertilizer_NameF",
MaximumBinCountPerFeature = 40,
LearningRate = 0.00020,
NumberOfIterations = 50000,
NumberOfLeaves = 55,
LabelColumnName = "Production",
FeatureColumnName = "Features",
//EarlyStoppingRound = 20,
//UseCategoricalSplit = true,
//L2CategoricalRegularization = 1,
//CategoricalSmoothing = 1,
Booster = new DartBooster.Options()
{
MaximumTreeDepth = 10
MaximumTreeDepth = 20
}
};
var pipeline = mlContext.Transforms
.Text.FeaturizeText("Soil_TypeF", "Soil_Type")
.Append(mlContext.Transforms.Text.FeaturizeText("Crop_TypeF", "Crop_Type"))
.Append(mlContext.Transforms.Concatenate("Features", "Temperature", "Humidity", "Moisture", "Soil_TypeF", "Crop_TypeF", "Nitrogen", "Potassium", "Phosphorous"))
.Append(mlContext.Transforms.Conversion.MapValueToKey("Fertilizer_NameF", "Fertilizer_Name"), TransformerScope.TrainTest)
.AppendCacheCheckpoint(mLContext)
.Append(mLContext.MulticlassClassification.Trainers.LightGbm(options))
.Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel", "PredictedLabel"));
.Text.FeaturizeText("SeasonF", "Season")
.Append(mlContext.Transforms.Text.FeaturizeText("CropF", "Crop"))
.Append(mlContext.Transforms.Concatenate("Features", "SeasonF", "CropF", "Rainfall"))
//.Append(mlContext.Transforms.Conversion.MapValueToKey("ProductionF", "Production"), TransformerScope.TrainTest)
//.AppendCacheCheckpoint(mLContext)
.Append(mLContext.Regression.Trainers.LightGbm(options));
//.Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel", "PredictedLabel"));
//Evaluate(mlContext, trainingDataView, pipeline, 10, reportPath, "ProductionF");
//var Evaluate = mlContext.Regression.CrossValidate(trainingDataView, pipeline, numberOfFolds: 100, labelColumnName: "Production");
//var Evaluate = mlContext.Regression.Evaluate(testDataView, labelColumnName: "Production", scoreColumnName: "Score");
//var metricsInMultipleFolds = Evaluate.Select(r => r.Metrics);
Evaluate(mlContext, trainingDataView, pipeline, 10, reportPath, "Fertilizer_NameF");
ITransformer MLModel = pipeline.Fit(trainingDataView);
var testEval = MLModel.Transform(testDataView);
var Evaluate = mlContext.Regression.Evaluate(testEval, labelColumnName: "Production");
return MLModel;
}
@ -104,10 +123,10 @@ namespace Game1.Sources.ML_Joel
return mlContext.Model.Load(modelpath, out DataViewSchema inputSchema);
}
public static Microsoft.ML.PredictionEngine<ModelInput, ModelOutput> CreateEngine()
public static Microsoft.ML.PredictionEngine<Input, Output> CreateEngine()
{
ITransformer mlModel = LoadModel(false);
return mlContext.Model.CreatePredictionEngine<ModelInput, ModelOutput>(mlModel);
return mlContext.Model.CreatePredictionEngine<Input, Output>(mlModel);
}
}

View File

@ -16,72 +16,72 @@ class FertilizerHolder
{
ID = 999,
Name = "None",
Nitrogen = 0.0f / 5,
Phosphorus = 0 * 0.436f / 5,
Potassium = 0 * 0.83f / 5
Nitrogen = 0.0f / 2,
Phosphorus = 0 * 0.436f / 2,
Potassium = 0 * 0.83f / 2
};
FertilizerType[1] = new Fertilizer
{
ID = 0,
Name = "10-26-26",
Nitrogen = 10.0f / 5,
Phosphorus = 26 * 0.436f / 5,
Potassium = 26 * 0.83f / 5
Nitrogen = 10.0f / 2,
Phosphorus = 26 * 0.436f / 2,
Potassium = 26 * 0.83f / 2
};
FertilizerType[2] = new Fertilizer
{
ID = 1,
Name = "14-35-14",
Nitrogen = 14.0f / 5,
Phosphorus = 35 * 0.436f / 5,
Potassium = 14 * 0.83f / 5
Nitrogen = 14.0f / 2,
Phosphorus = 35 * 0.436f / 2,
Potassium = 14 * 0.83f / 2
};
FertilizerType[3] = new Fertilizer
{
ID = 2,
Name = "17-17-17",
Nitrogen = 17.0f / 5,
Phosphorus = 17 * 0.436f / 5,
Potassium = 17 * 0.83f / 5
Nitrogen = 17.0f / 2,
Phosphorus = 17 * 0.436f / 2,
Potassium = 17 * 0.83f / 2
};
FertilizerType[4] = new Fertilizer
{
ID = 3,
Name = "20-20",
Nitrogen = 20.0f / 5,
Phosphorus = 20 * 0.436f / 5,
Potassium = 0 * 0.83f / 5
Nitrogen = 20.0f / 2,
Phosphorus = 20 * 0.436f / 2,
Potassium = 0 * 0.83f / 2
};
FertilizerType[5] = new Fertilizer
{
ID = 4,
Name = "28-28",
Nitrogen = 28.0f / 5,
Phosphorus = 28 * 0.436f / 5,
Potassium = 0 * 0.83f / 5
Nitrogen = 28.0f / 2,
Phosphorus = 28 * 0.436f / 2,
Potassium = 0 * 0.83f / 2
};
FertilizerType[6] = new Fertilizer
{
ID = 5,
Name = "DAP",
Nitrogen = 18.0f / 5,
Phosphorus = 46 * 0.436f / 5,
Potassium = 0 * 0.83f / 5
Nitrogen = 18.0f / 2,
Phosphorus = 46 * 0.436f / 2,
Potassium = 0 * 0.83f / 2
};
FertilizerType[7] = new Fertilizer
{
ID = 6,
Name = "Urea",
Nitrogen = 46.0f / 5,
Phosphorus = 0 * 0.436f / 5,
Potassium = 0 * 0.83f / 5
Nitrogen = 46.0f / 2,
Phosphorus = 0 * 0.436f / 2,
Potassium = 0 * 0.83f / 2
};
}
*/
@ -89,72 +89,72 @@ class FertilizerHolder
{
ID = 999,
Name = "None",
Nitrogen = 0.0f / 5,
Phosphorus = 0 * 0.436f / 5,
Potassium = 0 * 0.83f / 5
Nitrogen = 0.0f / 2,
Phosphorus = 0 * 0.436f / 2,
Potassium = 0 * 0.83f / 2
};
FertilizerType[1] = new Fertilizer
{
ID = 0,
Name = "10-26-26",
Nitrogen = 17.21f / 5,
Phosphorus = 12.14f / 5,
Potassium = 0.64f / 5
Nitrogen = 17.21f / 2,
Phosphorus = 12.14f / 2,
Potassium = 0.64f / 2
};
FertilizerType[2] = new Fertilizer
{
ID = 1,
Name = "14-35-14",
Nitrogen = 16.89f / 5,
Phosphorus = 6.21f / 5,
Potassium = 5.21f / 5
Nitrogen = 16.89f / 2,
Phosphorus = 6.21f / 2,
Potassium = 5.21f / 2
};
FertilizerType[3] = new Fertilizer
{
ID = 2,
Name = "17-17-17",
Nitrogen = 14.92f / 5,
Phosphorus = 14.42f / 5,
Potassium = 3.0f / 5
Nitrogen = 14.92f / 2,
Phosphorus = 14.42f / 2,
Potassium = 3.0f / 2
};
FertilizerType[4] = new Fertilizer
{
ID = 3,
Name = "20-20",
Nitrogen = 15.39f / 5,
Phosphorus = 15.21f / 5,
Potassium = 9.5f / 5
Nitrogen = 15.39f / 2,
Phosphorus = 15.21f / 2,
Potassium = 9.5f / 2
};
FertilizerType[5] = new Fertilizer
{
ID = 4,
Name = "28-28",
Nitrogen = 9.67f / 5,
Phosphorus = 10.47f / 5,
Potassium = 9.5f / 5
Nitrogen = 9.67f / 2,
Phosphorus = 10.47f / 2,
Potassium = 9.5f / 2
};
FertilizerType[6] = new Fertilizer
{
ID = 5,
Name = "DAP",
Nitrogen = 14.52f / 5,
Phosphorus = 1.77f / 5,
Potassium = 9.5f / 5
Nitrogen = 14.52f / 2,
Phosphorus = 1.77f / 2,
Potassium = 9.5f / 2
};
FertilizerType[7] = new Fertilizer
{
ID = 6,
Name = "Urea",
Nitrogen = 1.81f / 5,
Phosphorus = 21.0f / 5,
Potassium = 9.5f / 5
Nitrogen = 1.81f / 2,
Phosphorus = 21.0f / 2,
Potassium = 9.5f / 2
};
}

View File

@ -7,7 +7,7 @@ using System.Threading.Tasks;
class Cargo
{
private Items[,] items = new Items[2, 351];
private Items[,] items = new Items[2, 281];
private int[] Count = new int[2];

View File

@ -11,7 +11,7 @@ using Microsoft.Xna.Framework.Input;
class Inventory
{
private int Weight = 0;
private int maxWeight = 350;
private int maxWeight = 280;
private int[] totalHarvested = new int[11];
private int[] totalFertilizerUsed = new int[8];
private Cargo cargo = new Cargo();

View File

@ -54,11 +54,16 @@ class AI
int testsize = 2;
Path newTarget;
Nodes nodes;
Random random = new Random();
if (astar.GetAdjacentNodes(tractorPos).Count == 0)
nodes = new Nodes(housePos);
else
nodes = astar.GetAdjacentNodes(tractorPos)[0];
{
List<Nodes> templist = astar.GetAdjacentNodes(tractorPos);
nodes = templist[random.Next(0, templist.Count())];
templist.Clear();
}
if (tractorPos != housePos)
if (inventory.getWeight() == inventory.getMaxWeight() || inventory.isMissingFertilizer())
@ -168,7 +173,7 @@ class AI
saturationScore = -100;
}
return score + (-aproxDistance * 5) + statusScore + timerScore + saturationScore;
return score + (-aproxDistance * 10) + statusScore + timerScore + saturationScore;
}
private float norm(float min, float max, float val)