lepszy best first jeszcze
This commit is contained in:
parent
80902cc628
commit
1215d9549e
@ -11,6 +11,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using System.Threading;
|
||||
using CzokoŚmieciarka.MonoGameView.DataModels.GeneralModels.Models;
|
||||
|
||||
namespace MonoGameView.Algorithms
|
||||
{
|
||||
@ -93,7 +94,9 @@ namespace MonoGameView.Algorithms
|
||||
|
||||
}
|
||||
}
|
||||
if (!(itemdupa is House && collector.TrashContainers.All(i=>i.FillPercent==0)))
|
||||
if (!(grid[collector.Coords.X, collector.Coords.Y] is Dump && collector.TrashContainers.Any(x => x.FillPercent > 0 && (grid[collector.Coords.X, collector.Coords.Y] as Dump).TypeOfGarbage.GarbageType == x.TypeOfGarbage.GarbageType))
|
||||
&& !(grid[collector.Coords.X, collector.Coords.Y] is House
|
||||
&& (grid[collector.Coords.X, collector.Coords.Y] as House).TrashCans.Any(j => j.FillPercent > 0 && collector.TrashContainers.Any(i => i.FillPercent < 1 && i.Garbage.TypeOfGarbage.GarbageType == j.TypeOfGarbage.GarbageType))))
|
||||
{
|
||||
var moveSteps = new List<IStep>()
|
||||
{
|
||||
@ -142,7 +145,7 @@ namespace MonoGameView.Algorithms
|
||||
while (true)
|
||||
{
|
||||
var item = nodes.Dequeue();
|
||||
//Thread.Sleep(10);
|
||||
//Thread.Sleep(100);
|
||||
this.Collector.Coords = item.Item2.Coords;
|
||||
this.Collector.TrashContainers = item.Item2.TrashContainers;
|
||||
for (int x = 0; x < item.Item3.GetLength(0); x++)
|
||||
|
290
Trunk/MonoGameView/Algorithms/BestFirstSearch.cs
Normal file
290
Trunk/MonoGameView/Algorithms/BestFirstSearch.cs
Normal file
@ -0,0 +1,290 @@
|
||||
using CzokoŚmieciarka.MonoGameView.DataModels.Enums;
|
||||
using CzokoŚmieciarka.MonoGameView.DataModels.Interfaces;
|
||||
using CzokoŚmieciarka.MonoGameView.DataModels.Interfaces.GarbageCollector;
|
||||
using CzokoŚmieciarka.MonoGameView.DataModels.Interfaces.TrashCans;
|
||||
using CzokoŚmieciarka.MonoGameView.DataModels.Models;
|
||||
using CzokoŚmieciarka.MonoGameView.DataModels.Models.Steps;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using System.Threading;
|
||||
using CzokoŚmieciarka.MonoGameView.DataModels.GeneralModels.Models;
|
||||
|
||||
namespace MonoGameView.Algorithms
|
||||
{
|
||||
public class BestFirstSearch
|
||||
{
|
||||
public GarbageCollector Collector { get; set; }
|
||||
public ICloneable[,] Grid { get; set; }
|
||||
public BestFirstSearch(GarbageCollector collector, ICloneable[,] grid)
|
||||
{
|
||||
this.Collector = collector;
|
||||
this.Grid = grid;
|
||||
}
|
||||
int count = 0;
|
||||
public List<Coords> Houses { get; set; }
|
||||
public List<Coords> Dumps { get; set; }
|
||||
public List<IStep> BestPath(ContentManager content, GarbageCollector collector, ICloneable[,] grid)
|
||||
{
|
||||
Houses = new List<Coords>();
|
||||
Dumps = new List<Coords>();
|
||||
for (int x = 0; x < grid.GetLength(0); x++)
|
||||
{
|
||||
for (int y = 0; y < grid.GetLength(1); y++)
|
||||
{
|
||||
if (grid[x, y] is House)
|
||||
{
|
||||
Houses.Add(new Coords(x, y));
|
||||
|
||||
} else if (grid[x,y] is Dump)
|
||||
{
|
||||
Dumps.Add(new Coords(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
var r = SearchBfs(content, collector, grid, 0).Key;
|
||||
Console.WriteLine($"Counts : {count}");
|
||||
if (r == null) return new List<IStep>();
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
List<IStep> PossibleSteps(AGarbageCollector collector, ICloneable[,] grid)
|
||||
{
|
||||
|
||||
|
||||
var result = new List<IStep>();
|
||||
var itemdupa = grid[collector.Coords.X, collector.Coords.Y];
|
||||
|
||||
if (grid[collector.Coords.X, collector.Coords.Y] is House)
|
||||
{
|
||||
var collectSteps = new List<IStep>()
|
||||
{
|
||||
new CollectStep(GarbageType.Glass),
|
||||
new CollectStep(GarbageType.Organic),
|
||||
new CollectStep(GarbageType.Paper),
|
||||
new CollectStep(GarbageType.PlasticMetal)
|
||||
};
|
||||
foreach (var item in collectSteps)
|
||||
{
|
||||
var copyCollector = (AGarbageCollector)collector.Clone();
|
||||
var copyGrid = CopyGrid(grid);
|
||||
if (item.Invoke(copyCollector, copyGrid))
|
||||
result.Add(item);
|
||||
}
|
||||
}
|
||||
if (grid[collector.Coords.X, collector.Coords.Y] is ADump)
|
||||
{
|
||||
var collectSteps = new List<IStep>()
|
||||
{
|
||||
new SpillStep(GarbageType.Glass),
|
||||
new SpillStep(GarbageType.Organic),
|
||||
new SpillStep(GarbageType.Paper),
|
||||
new SpillStep(GarbageType.PlasticMetal)
|
||||
};
|
||||
foreach (var item in collectSteps)
|
||||
{
|
||||
var copyCollector = (AGarbageCollector)collector.Clone();
|
||||
var copyGrid = CopyGrid(grid);
|
||||
if (item.Invoke(copyCollector, copyGrid))
|
||||
result.Add(item);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
if (!(grid[collector.Coords.X, collector.Coords.Y] is Dump && collector.TrashContainers.Any(x => x.FillPercent > 0 && (grid[collector.Coords.X, collector.Coords.Y] as Dump).TypeOfGarbage.GarbageType == x.TypeOfGarbage.GarbageType))
|
||||
&& !(grid[collector.Coords.X, collector.Coords.Y] is House
|
||||
&& (grid[collector.Coords.X, collector.Coords.Y] as House).TrashCans.Any(j => j.FillPercent > 0 && collector.TrashContainers.Any(i => i.FillPercent < 1 && i.Garbage.TypeOfGarbage.GarbageType == j.TypeOfGarbage.GarbageType))))
|
||||
{
|
||||
var moveSteps = new List<IStep>()
|
||||
{
|
||||
new MoveStep(Direction.Up),
|
||||
new MoveStep(Direction.Down),
|
||||
new MoveStep(Direction.Left),
|
||||
new MoveStep(Direction.Right)
|
||||
};
|
||||
var filteredMoveSteps = new List<IStep>();
|
||||
foreach (var item in moveSteps)
|
||||
{
|
||||
var copyCollector = (AGarbageCollector)collector.Clone();
|
||||
if (item.Invoke(copyCollector, grid))
|
||||
{
|
||||
var gcx = copyCollector.Coords.X;
|
||||
var gcy = copyCollector.Coords.Y;
|
||||
if (grid[gcx, gcy] is Road1 || grid[gcx, gcy] is House || (grid[gcx, gcy] is ADump && copyCollector.TrashContainers.Any(x => x.FillPercent > 0)))
|
||||
{
|
||||
result.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int Priority (Tuple<List<IStep>,GarbageCollector,ICloneable[,]> t)
|
||||
{
|
||||
var inHouses = Houses
|
||||
.Aggregate(0.0, (a, b) => a + (t.Item3[b.X, b.Y] as IGarbageLocalization)
|
||||
.TrashCans
|
||||
.Aggregate(0.0, (i, j) => i + j.Garbage.Weight));
|
||||
var inDumps = Dumps
|
||||
.Aggregate(0.0, (a, b) => a + (t.Item3[b.X, b.Y] as ATrashCan).Garbage.Weight);
|
||||
var inCollector = t.Item2.TrashContainers.Aggregate(0.0, (a, b) => a + b.Garbage.Weight);
|
||||
double p1 = inCollector + 2*inHouses - 3*inDumps;
|
||||
|
||||
|
||||
var houses2 = Houses.Select(x => t.Item3[x.X, x.Y]).Where(x => x is House).Select(x => x as House).ToList();
|
||||
|
||||
var notFullCans = t.Item2.TrashContainers.Where(x => x.FillPercent != 1
|
||||
&& houses2.Any(i=> i.TrashCans.Any(j => j.TypeOfGarbage.GarbageType == x.TypeOfGarbage.GarbageType
|
||||
&& j.FillPercent > 0)) );
|
||||
if (!notFullCans.Any())
|
||||
{
|
||||
var fullCans = t.Item2.TrashContainers.Where(x => x.FillPercent > 0);
|
||||
if (!fullCans.Any()) return 0;
|
||||
//var fullCan=fullCans.First();
|
||||
var closestDump = Dumps
|
||||
.Select(x => t.Item3[x.X, x.Y])
|
||||
.Select(i => i as Dump)
|
||||
.Where(i => fullCans.Any(j=>i.TypeOfGarbage.GarbageType == j.TypeOfGarbage.GarbageType))
|
||||
.Min(b => Math.Pow(t.Item2.Coords.X - b.Coords.X, 2) + Math.Pow(t.Item2.Coords.Y - b.Coords.Y, 2));
|
||||
return (int) (p1 * 1000 + closestDump);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
//var notFullCan = notFullCans.First();
|
||||
var closestHouses = Houses
|
||||
.Select(x => t.Item3[x.X, x.Y])
|
||||
.Where(i => i is House)
|
||||
.Select(i => i as House)
|
||||
.Where(i => i.TrashCans.Any(x => notFullCans.Any(j=>x.TypeOfGarbage.GarbageType ==j.TypeOfGarbage.GarbageType && x.FillPercent > 0)));
|
||||
var closestHouse = (closestHouses.Any()) ? closestHouses.Min(b => Math.Pow(t.Item2.Coords.X - b.Coords.X, 2) + Math.Pow(t.Item2.Coords.Y - b.Coords.Y, 2)): 0.0;
|
||||
|
||||
var closestDumps = Dumps
|
||||
.Select(x => t.Item3[x.X, x.Y])
|
||||
.Select(i => i as Dump)
|
||||
.Where(i => notFullCans.Any(j=>i.TypeOfGarbage.GarbageType == j.TypeOfGarbage.GarbageType));
|
||||
var closestDump = (closestDumps.Any()) ? closestDumps.Min(b => Math.Pow(t.Item2.Coords.X - b.Coords.X, 2) + Math.Pow(t.Item2.Coords.Y - b.Coords.Y, 2)) : 0.0;
|
||||
|
||||
|
||||
return (int) (p1 * 1000 + 10*closestHouse + closestDump);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
KeyValuePair<List<IStep>, int> SearchBfs(ContentManager content, GarbageCollector collector, ICloneable[,] grid, int length)
|
||||
{
|
||||
|
||||
//Thread.Sleep(1);
|
||||
int count = 0;
|
||||
|
||||
var nodes = new PriorityQueue<Tuple<List<IStep>, GarbageCollector, ICloneable[,]>>();
|
||||
|
||||
var f = new Tuple<List<IStep>, GarbageCollector, ICloneable[,]>(new List<IStep>(), collector, grid);
|
||||
|
||||
nodes.Enqueue(f,Priority(f));
|
||||
while (true)
|
||||
{
|
||||
var p = nodes.Dequeue();
|
||||
var item = p.Key;
|
||||
var priority = p.Value;
|
||||
|
||||
Thread.Sleep(100);
|
||||
this.Collector.Coords = item.Item2.Coords;
|
||||
this.Collector.TrashContainers = item.Item2.TrashContainers;
|
||||
for (int x = 0; x < item.Item3.GetLength(0); x++)
|
||||
{
|
||||
for (int y = 0; y < item.Item3.GetLength(1); y++)
|
||||
{
|
||||
this.Grid[x, y] = item.Item3[x, y];
|
||||
}
|
||||
}
|
||||
|
||||
if (Houses.All(c => (item.Item3[c.X, c.Y] as IGarbageLocalization).TrashCans.All(j => j.FillPercent == 0.0))
|
||||
&&
|
||||
item.Item2.TrashContainers.All(i => i.FillPercent == 0.0)
|
||||
)
|
||||
{
|
||||
return new KeyValuePair<List<IStep>, int>(item.Item1, length);
|
||||
}
|
||||
if (true)//item.Item2.Counter <= 12)
|
||||
{
|
||||
|
||||
|
||||
foreach (var step in PossibleSteps(item.Item2, item.Item3))
|
||||
{
|
||||
if (step is SpillStep)
|
||||
{
|
||||
Console.WriteLine();
|
||||
}
|
||||
var collectorClone = (GarbageCollector)item.Item2.Clone();
|
||||
var gridClone = CopyGrid(item.Item3);
|
||||
step.Invoke(collectorClone, gridClone);
|
||||
|
||||
|
||||
var steps = new List<IStep>();
|
||||
steps.AddRange(item.Item1);
|
||||
steps.Add(step);
|
||||
var f2 = new Tuple<List<IStep>, GarbageCollector, ICloneable[,]>(steps, collectorClone, gridClone);
|
||||
var f2P = Priority(f2);
|
||||
|
||||
nodes.Enqueue(f2,Priority(f2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private ICloneable[,] CopyGrid(ICloneable[,] grid)
|
||||
{
|
||||
ICloneable[,] result = new ICloneable[grid.GetLength(0), grid.GetLength(1)];
|
||||
for (int x = 0; x < grid.GetLength(0); x++)
|
||||
{
|
||||
for (int y = 0; y < grid.GetLength(1); y++)
|
||||
{
|
||||
result[x, y] = (ICloneable)grid[x, y].Clone();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ using System.Threading.Tasks;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using System.Threading;
|
||||
using MonoGameView.DataModels.Models;
|
||||
using CzokoŚmieciarka.MonoGameView.DataModels.GeneralModels.Models;
|
||||
|
||||
namespace CzokoŚmieciarka.MonoGameView.Algorithms
|
||||
{
|
||||
@ -93,7 +94,9 @@ namespace CzokoŚmieciarka.MonoGameView.Algorithms
|
||||
|
||||
}
|
||||
}
|
||||
if (!(collector.TrashContainers.Any(x => x.FillPercent > 0) && grid[collector.Coords.X,collector.Coords.Y] is ADump))
|
||||
if (!(grid[collector.Coords.X,collector.Coords.Y] is Dump && collector.TrashContainers.Any(x => x.FillPercent > 0 && (grid[collector.Coords.X, collector.Coords.Y] as Dump).TypeOfGarbage.GarbageType == x.TypeOfGarbage.GarbageType ))
|
||||
&& !(grid[collector.Coords.X,collector.Coords.Y] is House
|
||||
&& (grid[collector.Coords.X, collector.Coords.Y] as House).TrashCans.Any(j => j.FillPercent > 0 && collector.TrashContainers.Any(i => i.FillPercent < 1 && i.Garbage.TypeOfGarbage.GarbageType == j.TypeOfGarbage.GarbageType))))
|
||||
{
|
||||
var moveSteps = new List<IStep>()
|
||||
{
|
||||
@ -127,7 +130,7 @@ namespace CzokoŚmieciarka.MonoGameView.Algorithms
|
||||
KeyValuePair<List<IStep>, int> Search(ContentManager content, GarbageCollector collector, ICloneable[,] grid, int length)
|
||||
{
|
||||
|
||||
//Thread.Sleep(10);
|
||||
Thread.Sleep(100);
|
||||
this.Collector.Coords = collector.Coords;
|
||||
this.Collector.TrashContainers = collector.TrashContainers;
|
||||
|
||||
|
52
Trunk/MonoGameView/Algorithms/PriorityQueue.cs
Normal file
52
Trunk/MonoGameView/Algorithms/PriorityQueue.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class PriorityQueue<T>
|
||||
{
|
||||
// The items and priorities.
|
||||
List<T> Values = new List<T>();
|
||||
List<int> Priorities = new List<int>();
|
||||
|
||||
// Return the number of items in the queue.
|
||||
public int NumItems
|
||||
{
|
||||
get
|
||||
{
|
||||
return Values.Count;
|
||||
}
|
||||
}
|
||||
|
||||
// Add an item to the queue.
|
||||
|
||||
public void AddAt(int index,T new_value, int new_priority)
|
||||
{
|
||||
Values.Insert(index, new_value);
|
||||
Priorities.Insert(index, new_priority);
|
||||
}
|
||||
|
||||
public void Enqueue(T new_value, int new_priority)
|
||||
{
|
||||
var index = 0;
|
||||
foreach (var item in Priorities)
|
||||
{
|
||||
if (item < new_priority) index++;
|
||||
else break;
|
||||
}
|
||||
Values.Insert(index,new_value);
|
||||
Priorities.Insert(index,new_priority);
|
||||
}
|
||||
|
||||
// Remove the item with the largest priority from the queue.
|
||||
public KeyValuePair<T,int> Dequeue()
|
||||
{
|
||||
// Find the hightest priority.
|
||||
var best_index = 0;
|
||||
|
||||
// Return the corresponding item.
|
||||
var top_value = Values[best_index];
|
||||
var top_priotiy = Priorities[best_index];
|
||||
// Remove the item from the lists.
|
||||
Values.RemoveAt(best_index);
|
||||
Priorities.RemoveAt(best_index);
|
||||
return new KeyValuePair<T,int>(top_value,top_priotiy);
|
||||
}
|
||||
}
|
@ -64,36 +64,36 @@ namespace CzokoŚmieciarka.MonoGameView
|
||||
// TODO: Add your initialization logic here
|
||||
timer = 0f;
|
||||
|
||||
mapLoader.Load(out size,out grid,"map12.xml");
|
||||
mapLoader.Load(out size,out grid,"mapa2.xml");
|
||||
var containers = new List<GarbageCollectorContainer>()
|
||||
{
|
||||
new GarbageCollectorContainer(
|
||||
new TypeOfGarbage(GarbageType.Glass,1),
|
||||
100000,
|
||||
10000,
|
||||
new BasicGarbage(new TypeOfGarbage(GarbageType.Glass,1),0)
|
||||
),
|
||||
new GarbageCollectorContainer(
|
||||
new TypeOfGarbage(GarbageType.Paper,1),
|
||||
100000,
|
||||
10000,
|
||||
new BasicGarbage(new TypeOfGarbage(GarbageType.Paper,1),0)
|
||||
),
|
||||
new GarbageCollectorContainer(
|
||||
new TypeOfGarbage(GarbageType.Organic,1),
|
||||
100000,
|
||||
10000,
|
||||
new BasicGarbage(new TypeOfGarbage(GarbageType.Organic,1),0)
|
||||
),
|
||||
new GarbageCollectorContainer(
|
||||
new TypeOfGarbage(GarbageType.PlasticMetal,1),
|
||||
100000,
|
||||
10000,
|
||||
new BasicGarbage(new TypeOfGarbage(GarbageType.PlasticMetal,1),0)
|
||||
),
|
||||
|
||||
};
|
||||
collector = new GarbageCollector(new Coords(2,1), containers, size, size,0);
|
||||
collector = new GarbageCollector(new Coords(1,1), containers, size, size,0);
|
||||
|
||||
|
||||
stepN = 0;
|
||||
var dfs = new BestFirstSearch(collector,grid);
|
||||
var dfs = new DFS(collector,grid);
|
||||
//steps = dfs.BestPath(Content, collector, grid);
|
||||
new Thread(delegate() {
|
||||
var x = dfs.BestPath(Content, collector, grid);
|
||||
|
Loading…
Reference in New Issue
Block a user