From ee83ebf73af0f260259adc2ab6cf5a50a0d04999 Mon Sep 17 00:00:00 2001 From: iMoHax Date: Fri, 9 Dec 2016 16:41:09 +0300 Subject: [PATCH] fix fuel compute --- .../java/ru/trader/analysis/TransitPath.java | 123 +++++----- .../java/ru/trader/analysis/VendorsGraph.java | 13 +- .../analysis/graph/ConnectibleGraph.java | 2 +- .../java/ru/trader/analysis/graph/Path.java | 126 +++++++--- .../ru/trader/analysis/graph/PathTest.java | 231 ++++++++++++++++++ .../ru/trader/analysis/graph/TestGraph.java | 27 ++ 6 files changed, 418 insertions(+), 104 deletions(-) create mode 100644 core/src/test/java/ru/trader/analysis/graph/PathTest.java create mode 100644 core/src/test/java/ru/trader/analysis/graph/TestGraph.java diff --git a/core/src/main/java/ru/trader/analysis/TransitPath.java b/core/src/main/java/ru/trader/analysis/TransitPath.java index 81e1e14..2d10377 100644 --- a/core/src/main/java/ru/trader/analysis/TransitPath.java +++ b/core/src/main/java/ru/trader/analysis/TransitPath.java @@ -6,8 +6,7 @@ import ru.trader.analysis.graph.ConnectibleGraph; import ru.trader.analysis.graph.Path; import ru.trader.core.Vendor; -import java.util.ArrayList; -import java.util.List; +import java.util.*; public class TransitPath { private final List> entries; @@ -16,82 +15,82 @@ public class TransitPath { private int refillCount; public TransitPath(Path path, double fuel) { - List.BuildEdge> edges = path.getEdges(); - entries = new ArrayList<>(edges.size()); - createEdges(edges, fuel); + entries = new ArrayList<>(path.getSize()); + createEdges(path, fuel); } - private void createEdges(List.BuildEdge> edges, double fuel) { - fuelCost = 0; refillCount = 0; - for (int i = edges.size() - 1; i >= 0; i--) { - ConnectibleGraph.BuildEdge edge = edges.get(i); + private void createEdges(Path path, double fuel) { + fuelCost = 0; + refillCount = 0; + + for (Iterator.BuildEdge> iterator = path.listIterator(0); iterator.hasNext(); ) { + ConnectibleGraph.BuildEdge edge = iterator.next(); + double cost = edge.getFuelCost(fuel); + ConnectibleEdge cEdge = new ConnectibleEdge<>(edge.getSource(), edge.getTarget()); - double fuelCost = edge.getFuelCost(fuel); - this.fuelCost += fuelCost; - cEdge.setFuelCost(fuelCost); + cEdge.setFuelCost(cost); + fuelCost += cost; entries.add(cEdge); - if (fuel < 0 || fuel < edge.getMinFuel()){ - if (refillCount == 0){ - fuel = refill(edges, 0); - if (fuel < 0){ - fuel = refill(edges, entries.size()-1); - } - } else { - fuel = refill(edges, entries.size()-1); + + if (fuel < 0 || fuel < edge.getMinFuel()) { + //TODO: improve best refill place search + fuel = refill(path, false); + if (fuel < 0){ + fuel = refill(path, true); } if (fuel < 0) throw new IllegalStateException("Is not exists path"); - refillCount++; } else { - fuel -= fuelCost; + fuel -= cost; } } remain = fuel; } - private double refill(List.BuildEdge> edges, int startIndex){ - double max = -1; - for (int i = startIndex; i >= 0; i--) { - ConnectibleGraph.BuildEdge e = edges.get(edges.size()-1-i); - if (max != -1){ - max += e.getFuelCost(max + e.getMinFuel()); - } - Vendor source = e.getSource().getEntry(); - if (source.canRefill()){ - ConnectibleEdge ce = entries.get(i); - if (ce.isRefill()){ - throw new IllegalStateException("Is not exists path"); - } - double remain = max != -1 ? Math.min(max, e.getRefill()) : e.getRefill(); - double fuelCost = e.getFuelCost(remain); - double fuel = updateFuelCost(edges, i+1, remain-fuelCost); - if (fuel < 0){ - continue; - } - this.fuelCost += fuelCost - ce.getFuelCost(); - ce.setFuelCost(fuelCost); - ce.setRefill(remain); - return fuel; - } - if (max == -1 || e.getMaxFuel() < max){ - max = e.getMaxFuel(); - } - } - return -1; - } + private double refill(Path path, boolean includeTransit){ + int lastIndex = entries.size() - 1; + double max = path.getMaxFuel(true, lastIndex); - private double updateFuelCost(List.BuildEdge> edges, int startIndex, double fuel){ - for (int i = startIndex; i < entries.size(); i++) { - ConnectibleGraph.BuildEdge e = edges.get(edges.size()-1-i); - if (fuel < 0 || fuel < e.getMinFuel()){ - return -1; + ListIterator> iterator = entries.listIterator(lastIndex+1); + int refillIndex = lastIndex; + ConnectibleEdge refillEdge = null; + while (iterator.hasPrevious()){ + refillEdge = iterator.previous(); + if (refillEdge.getSource().getEntry().canRefill()){ + if (refillEdge.isRefill()){ + return -1; + } + if (includeTransit || !refillEdge.getSource().getEntry().isTransit()){ + break; + } } - ConnectibleEdge ce = entries.get(i); - double fuelCost = e.getFuelCost(fuel); - this.fuelCost += fuelCost - ce.getFuelCost(); - ce.setFuelCost(fuelCost); - fuel -= fuelCost; + refillIndex--; } + + if (refillIndex < 0 || refillEdge == null) return -1; + + ConnectibleGraph.BuildEdge pathEdge = path.get(refillIndex); + double fuel = Math.min(pathEdge.getShip().getRoundFuel(max), pathEdge.getRefill()); + refillEdge.setRefill(fuel); + refillCount++; + + ListIterator.BuildEdge> pathIterator = path.listIterator(refillIndex); + while (iterator.hasNext()){ + ConnectibleEdge edge = iterator.next(); + pathEdge = pathIterator.next(); + fuelCost -= edge.getFuelCost(); + double cost = pathEdge.getFuelCost(fuel); + edge.setFuelCost(cost); + fuelCost += cost; + + fuel -= cost; + } + + if (fuel < 0){ + refillEdge.setRefill(0); + refillCount--; + } + return fuel; } diff --git a/core/src/main/java/ru/trader/analysis/VendorsGraph.java b/core/src/main/java/ru/trader/analysis/VendorsGraph.java index 5847550..535f332 100644 --- a/core/src/main/java/ru/trader/analysis/VendorsGraph.java +++ b/core/src/main/java/ru/trader/analysis/VendorsGraph.java @@ -166,7 +166,7 @@ public class VendorsGraph extends ConnectibleGraph { Vertex target = lastEdge.getTarget(); assert vertex.getEntry().isTransit() && !target.getEntry().isTransit(); VendorsGraphBuilder h = this; - Path path = new Path<>(Collections.singleton(lastEdge)); + Path path = new Path<>(lastEdge); while (h != null && h.edge != null){ if (callback.isCancel()) break; BuildEdge cEdge = h.edge; @@ -175,7 +175,7 @@ public class VendorsGraph extends ConnectibleGraph { LOG.trace("Found loop, break"); break; } - path = path.add(cEdge); + path = path.addFirst(cEdge); if (path.getMinFuel() > path.getMaxFuel()){ LOG.trace("Path inaccessible"); break; @@ -217,7 +217,7 @@ public class VendorsGraph extends ConnectibleGraph { assert vertex.getEntry().isTransit() && !target.getEntry().isTransit(); List> paths = lastEdge.paths; int i = 1; - Path path = paths != null ? paths.get(0) : new Path<>(Collections.singleton((BuildEdge)lastEdge)); + Path path = paths != null ? paths.get(0) : new Path<>(lastEdge); while (path != null){ if (callback.isCancel()) break; VendorsGraphBuilder h = this; @@ -230,7 +230,7 @@ public class VendorsGraph extends ConnectibleGraph { LOG.trace("Found loop, break"); break; } - path = path.add(cEdge); + path = path.addFirst(cEdge); if (path.getMinFuel() > path.getMaxFuel()){ LOG.trace("Path inaccessible"); break; @@ -286,7 +286,7 @@ public class VendorsGraph extends ConnectibleGraph { protected VendorsBuildEdge(BuildEdge edge) { super(edge.getSource(), edge.getTarget()); - Path path = new Path<>(Collections.singleton(edge)); + Path path = new Path<>(edge); paths.add(path); setFuel(path.getMinFuel(), path.getMaxFuel()); } @@ -319,7 +319,7 @@ public class VendorsGraph extends ConnectibleGraph { public Path getPath(double fuel){ Path res = null; for (Path p : paths) { - if (((fuel - p.getMinFuel() > 0.05) || getSource().getEntry().canRefill()) && fuel <= p.getMaxFuel()) { + if ((fuel > p.getMinFuel() || getSource().getEntry().canRefill()) && fuel <= p.getMaxFuel()) { if (getProfile().getPathPriority().equals(Profile.PATH_PRIORITY.FAST)) { if (res == null || (p.getSize() < res.getSize() || p.getSize() == res.getSize() && p.getFuelCost() < res.getFuelCost()) && p.getRefillCount(fuel) <= res.getRefillCount(fuel)) { res = p; @@ -336,6 +336,7 @@ public class VendorsGraph extends ConnectibleGraph { } private boolean isRemove(Path path, Path best){ + if (path.getMinFuel() > path.getMaxFuel()) return true; if (profile.getPathPriority() == Profile.PATH_PRIORITY.FAST){ return (path.getSize() > best.getSize() || (path.getSize() == best.getSize() && path.getFuelCost() >= best.getFuelCost())) && (path.getSource().canRefill() || path.getMinFuel() >= best.getMinFuel() && path.getRefillCount() >= best.getRefillCount()) diff --git a/core/src/main/java/ru/trader/analysis/graph/ConnectibleGraph.java b/core/src/main/java/ru/trader/analysis/graph/ConnectibleGraph.java index 3110308..a85a312 100644 --- a/core/src/main/java/ru/trader/analysis/graph/ConnectibleGraph.java +++ b/core/src/main/java/ru/trader/analysis/graph/ConnectibleGraph.java @@ -53,7 +53,7 @@ public class ConnectibleGraph> extends AbstractGraph double distance = vertex.getEntry().getDistance(entry); if (distance > getShip().getMaxJumpRange()){ LOG.trace("Vertex {} is far away, {}", entry, distance); - return new BuildHelper<>(entry,-1); + return new CBuildHelper<>(entry,-1,0,0,distance); } double maxFuel = getShip().getMaxFuel(distance); double minFuel = getShip().getMinFuel(distance); diff --git a/core/src/main/java/ru/trader/analysis/graph/Path.java b/core/src/main/java/ru/trader/analysis/graph/Path.java index ec7c632..14b58ed 100644 --- a/core/src/main/java/ru/trader/analysis/graph/Path.java +++ b/core/src/main/java/ru/trader/analysis/graph/Path.java @@ -2,60 +2,108 @@ package ru.trader.analysis.graph; import ru.trader.core.Ship; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import java.util.*; public class Path> { - private final List.BuildEdge> entries; + private final LinkedList.BuildEdge> entries; private double minFuel; private double maxFuel; private double fuelCost; private int refillCount; + public Path(ConnectibleGraph.BuildEdge edge) { + this(edge, true); + } public Path(Collection.BuildEdge> edges) { - entries = new ArrayList<>(edges); - updateStat(); + this(edges, true); + } + + private Path(Collection.BuildEdge> edges, boolean update) { + entries = new LinkedList<>(edges); + if (update){ + updateStat(); + } + } + + private Path(ConnectibleGraph.BuildEdge edge, boolean update) { + entries = new LinkedList<>(); + entries.add(edge); + if (update){ + updateStat(); + } } private void updateStat(){ Ship ship = entries.get(0).getShip(); double fuel = ship.getTank(); minFuel = 0; maxFuel = 0; fuelCost = 0; refillCount = 0; - int minTo = 0; - for (int i = entries.size() - 1; i >= 0; i--) { - ConnectibleGraph.BuildEdge edge = entries.get(i); - if (i < entries.size() - 1 && edge.getSource().getEntry().canRefill()){ - if (minTo == 0) minTo = i+1; - fuel = edge.getMaxFuel(); + boolean refillFound = false; + int index = -1; double f = ship.getTank(); + ConnectibleGraph.BuildEdge prevEdge = null; + for (ConnectibleGraph.BuildEdge edge : entries) { + index++; + + if (index > 0 && edge.getSource().getEntry().canRefill()){ + refillFound = true; + f = edge.getMaxFuel(); } - if (fuel < 0 || fuel < edge.getMinFuel()){ - minFuel = ship.getTank()+1; - minTo = -1; + + if (!refillFound){ + if (prevEdge != null){ + minFuel = Math.max(minFuel, edge.getMinFuel()) + prevEdge.getFuelCost(prevEdge.getMaxFuel()); + } else { + minFuel = edge.getMinFuel(); + } } + + double c = edge.getFuelCost(f); + f -= c; + + double cost = edge.getFuelCost(fuel); - fuelCost += cost; fuel -= cost; + if (fuel < 0){ + refillCount++; + fuel = f; + cost = c; + } + fuelCost += cost; + + if (f < 0){ + minFuel = ship.getTank()+1; + break; + } + + prevEdge = edge; } - maxFuel = -1; - for (int i = 0; i < entries.size(); i++) { - ConnectibleGraph.BuildEdge edge = entries.get(i); - if (maxFuel != -1) { - maxFuel += edge.getFuelCost(maxFuel + edge.getMinFuel()); + + maxFuel = getMaxFuel(false, entries.size()-1); + } + + public double getMaxFuel(boolean fromRefill, int endIndex){ + double maxFuel = -1; + for (ListIterator.BuildEdge> iterator = entries.listIterator(endIndex+1); iterator.hasPrevious(); ) { + ConnectibleGraph.BuildEdge edge = iterator.previous(); + if (maxFuel > -1) { + maxFuel += edge.getFuelCost(edge.getMinFuel()); } if (maxFuel == -1 || edge.getMaxFuel() < maxFuel) { maxFuel = edge.getMaxFuel(); } - if (minTo != -1 && i >= minTo) { - minFuel += edge.getFuelCost(minFuel + edge.getMinFuel()); + if (fromRefill && edge.getSource().getEntry().canRefill()){ + break; } } - refillCount = getRefillCount(ship.getTank()); + return maxFuel; } - public List.BuildEdge> getEdges() { - return entries; + public ConnectibleGraph.BuildEdge get(int index){ + return entries.get(index); + } + + public ListIterator.BuildEdge> listIterator(int startIndex){ + return entries.listIterator(startIndex); } public double getFuelCost() { @@ -80,8 +128,7 @@ public class Path> { public int getRefillCount(double fuel){ int res = 0; - for (int i = entries.size() - 1; i >= 0; i--) { - ConnectibleGraph.BuildEdge edge = entries.get(i); + for (ConnectibleGraph.BuildEdge edge : entries) { fuel -= edge.getFuelCost(fuel); if (fuel < 0) { res++; @@ -91,25 +138,34 @@ public class Path> { return res; } - public Path add(ConnectibleGraph.BuildEdge edge){ - Path res = new Path<>(entries); - res.entries.add(edge); + public Path addFirst(ConnectibleGraph.BuildEdge edge){ + Path res = new Path<>(entries, false); + res.entries.addFirst(edge); + res.updateStat(); + return res; + } + + public Path addLast(ConnectibleGraph.BuildEdge edge){ + Path res = new Path<>(entries, false); + res.entries.addLast(edge); res.updateStat(); return res; } public T getSource(){ - return entries.get(entries.size()-1).getSource().getEntry(); + return entries.getFirst().getSource().getEntry(); } @Override public String toString() { final StringBuilder sb = new StringBuilder("{"); - for (int i = entries.size() - 1; i >= 0; i--) { - ConnectibleGraph.BuildEdge entry = entries.get(i); + int i = -1; + for (ConnectibleGraph.BuildEdge entry : entries) { + i++; sb.append(entry); - if (i>0) + if (i < entries.size()-1){ sb.append(", "); + } } sb.append('}'); return sb.toString(); diff --git a/core/src/test/java/ru/trader/analysis/graph/PathTest.java b/core/src/test/java/ru/trader/analysis/graph/PathTest.java new file mode 100644 index 0000000..acda268 --- /dev/null +++ b/core/src/test/java/ru/trader/analysis/graph/PathTest.java @@ -0,0 +1,231 @@ +package ru.trader.analysis.graph; + +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; +import ru.trader.analysis.AnalysisCallBack; +import ru.trader.analysis.TransitPath; +import ru.trader.core.*; +import ru.trader.store.simple.Store; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; + +public class PathTest extends Assert { + private final static Logger LOG = LoggerFactory.getLogger(PathTest.class); + + private final static Point x1 = new Point("x1",0); + private final static Point x2 = new Point("x2",3); + private final static Point x3 = new Point("x3",7); + private final static Point x4 = new Point("x4",8); + private final static Point x5 = new Point("x5",10); + private final static Point x6 = new Point("x6",12); + private final static Point x7 = new Point("x7",27); + + @Test + public void testCreatePath1() throws Exception { + LOG.info("Start create path test1"); + //max distance 5.167, 1 jump tank + Ship ship = new Ship(); + ship.setMass(64);ship.setTank(0.6); + + Profile profile = new Profile(ship); + TestGraph graph = new TestGraph<>(profile, new AnalysisCallBack()); + LOG.info("Ship = {}", profile.getShip()); + + Collection.BuildEdge> edges = new ArrayList<>(); + ConnectibleGraph.BuildEdge edge1 = graph.createEdge(x1,x2); + + edges.add(edge1); + Path path = new Path<>(edges); + double lastAfterMin1 = path.getMinFuel() - ship.getFuelCost(path.getMinFuel(), edge1.getDistance()); + double lastAfterMax1 = path.getMaxFuel() - ship.getFuelCost(path.getMaxFuel(), edge1.getDistance()); + + assertEquals(0.2, path.getMinFuel(),0.01); + assertEquals(0.6, path.getMaxFuel(),0.01); + assertEquals(0.2, path.getFuelCost(),0.01); + assertEquals(0, path.getRefillCount()); + assertEquals(1, path.getSize()); + assertTrue(lastAfterMin1 >= 0); + assertTrue(lastAfterMax1 >= 0); + + ConnectibleGraph.BuildEdge edge2 = graph.createEdge(x2,x3); + + edges.add(edge2); + path = new Path<>(edges); + + lastAfterMin1 = path.getMinFuel() - ship.getFuelCost(path.getMinFuel(), edge1.getDistance()); + lastAfterMax1 = path.getMaxFuel() - ship.getFuelCost(path.getMaxFuel(), edge1.getDistance()); + double lastAfterMin2 = lastAfterMin1 - ship.getFuelCost(lastAfterMin1, edge2.getDistance()); + double lastAfterMax2 = lastAfterMax1 - ship.getFuelCost(lastAfterMax1, edge2.getDistance()); + + assertTrue(edge1.getMinFuel() + edge2.getMinFuel() <= path.getMinFuel()); + assertEquals(0.6, path.getMaxFuel(),0.01); + assertEquals(0.56, path.getFuelCost(),0.01); + assertEquals(0, path.getRefillCount()); + assertEquals(2, path.getSize()); + assertTrue(lastAfterMin2 >= 0); + assertTrue(lastAfterMax2 >= 0); + + ConnectibleGraph.BuildEdge edge3 = graph.createEdge(x3,x4); + edges.add(edge3); + path = new Path<>(edges); + + lastAfterMin1 = path.getMinFuel() - ship.getFuelCost(path.getMinFuel(), edge1.getDistance()); + lastAfterMax1 = path.getMaxFuel() - ship.getFuelCost(path.getMaxFuel(), edge1.getDistance()); + lastAfterMin2 = lastAfterMin1 - ship.getFuelCost(lastAfterMin1, edge2.getDistance()); + lastAfterMax2 = lastAfterMax1 - ship.getFuelCost(lastAfterMax1, edge2.getDistance()); + double lastAfterMin3 = lastAfterMin2 - ship.getFuelCost(lastAfterMin2, edge3.getDistance()); + double lastAfterMax3 = lastAfterMax2 - ship.getFuelCost(lastAfterMax2, edge3.getDistance()); + + assertTrue(edge1.getMinFuel() + edge2.getMinFuel() + edge3.getMinFuel() <= path.getMinFuel()); + assertEquals(0.6, path.getMaxFuel(),0.01); + assertEquals(0.58, path.getFuelCost(),0.01); + assertEquals(0, path.getRefillCount()); + assertEquals(3, path.getSize()); + assertTrue(lastAfterMin3 >= 0); + assertTrue(lastAfterMax3 >= 0); + + } + + private double getRemain(Collection.BuildEdge> edges, double fuel, double tank, int refill){ + boolean isFirst = true; + for (ConnectibleGraph.BuildEdge edge : edges) { + fuel -= edge.getFuelCost(fuel); + if (refill == 1 && fuel <= 0 || refill == 2){ + if (!isFirst && edge.getSource().getEntry().canRefill()){ + fuel = tank - edge.getFuelCost(tank); + } else { + if (fuel <= 0) return fuel; + } + } + isFirst = false; + } + return fuel; + } + + @Test + public void testTransitPath() throws IOException, SAXException, ParserConfigurationException { + LOG.info("Start transit path test1"); + + Ship ship = new Ship(); + ship.setCargo(24); ship.setEngine(2,'A'); + Profile profile = new Profile(ship); + profile.setBalance(100000); profile.setJumps(6); + LOG.info("Ship = {}", profile.getShip()); + TestGraph graph = new TestGraph<>(profile, new AnalysisCallBack()); + + InputStream is = getClass().getResourceAsStream("/test3.xml"); + Market world = Store.loadFromFile(is); + Vendor hallerPort = world.get("LHS 1541").get("Haller Port"); + Vendor transitWolf1325= world.get("Wolf 1325").asTransit(); + Vendor transitBhadaba = world.get("Bhadaba").asTransit(); + Vendor transitLHS21 = world.get("LHS 21").asTransit(); + Vendor transitD99 = world.get("Tascheter Sector CL-Y D99").asTransit(); + Vendor morganTerminal = world.get("Sui Xing").get("Morgan Terminal"); + + Collection.BuildEdge> edges = new ArrayList<>(); + edges.add(graph.createEdge(hallerPort, transitWolf1325)); + edges.add(graph.createEdge(transitWolf1325, transitBhadaba)); + edges.add(graph.createEdge(transitBhadaba, transitLHS21)); + edges.add(graph.createEdge(transitLHS21, transitD99)); + edges.add(graph.createEdge(transitD99, morganTerminal)); + + LOG.info("Test path with refill"); + + double fuel = getRemain(edges, ship.getTank(), ship.getTank(), 0); + double fuel2 = getRemain(edges, ship.getTank(), ship.getTank(), 2); + double fuel3 = getRemain(edges, 0.64, ship.getTank(), 1); + double fuel4 = getRemain(edges, 0.63, ship.getTank(), 1); + + assertTrue(fuel < 0); + assertTrue(fuel2 > 0); + assertTrue(fuel3 > 0); + assertTrue(fuel4 < 0); + + Path path = new Path<>(edges); + + assertEquals(0.64, path.getMinFuel(),0.01); + assertEquals(2, path.getMaxFuel(),0.01); + assertEquals(2.03, path.getFuelCost(),0.01); + assertEquals(1, path.getRefillCount()); + assertEquals(5, path.getSize()); + + TransitPath transitPath = new TransitPath(path, ship.getTank()); + assertEquals(1, transitPath.getRefillCount()); + assertEquals(2.03, transitPath.getFuelCost(), 0.01); + assertEquals(fuel2, transitPath.getRemain(), 0.01); + + transitPath = new TransitPath(path, 0.64); + assertEquals(2, transitPath.getRefillCount()); + assertEquals(2.03, transitPath.getFuelCost(), 0.01); + assertEquals(fuel2, transitPath.getRemain(), 0.01); + + +/* + transitPath = new TransitPath(path, 0.64); + assertEquals(1, transitPath.getRefillCount()); + assertEquals(2.01, transitPath.getFuelCost(), 0.01); + assertEquals(fuel3, transitPath.getRemain(), 0.01); + transitPath = new TransitPath(path, 0.62); + assertEquals(2, transitPath.getRefillCount()); +*/ + + LOG.info("Test wrong path"); + + Vendor quimperPort = world.get("LHS 21").get("Quimper Ring"); + Vendor transitWolf1278= world.get("Wolf 1278").asTransit(); + Vendor sarichPort = world.get("Lowne 1").get("Sarich Port"); + + edges = new ArrayList<>(); + edges.add(graph.createEdge(quimperPort, transitBhadaba)); + edges.add(graph.createEdge(transitBhadaba, transitWolf1278)); + edges.add(graph.createEdge(transitWolf1278, sarichPort)); + + fuel = getRemain(edges, ship.getTank(), ship.getTank(), 0); + fuel2 = getRemain(edges, ship.getTank(), ship.getTank(), 2); + fuel3 = getRemain(edges, 0.55, ship.getTank(), 1); + fuel4 = getRemain(edges, 0.54, ship.getTank(), 1); + + assertTrue(fuel > 0); + assertTrue(fuel2 > 0); + assertTrue(fuel3 > 0); + assertTrue(fuel4 < 0); + + path = new Path<>(edges); + + assertEquals(0.55, path.getMinFuel(),0.01); + assertEquals(2, path.getMaxFuel(),0.01); + assertEquals(1.85, path.getFuelCost(),0.01); + assertEquals(0, path.getRefillCount()); + assertEquals(3, path.getSize()); + + transitPath = new TransitPath(path, ship.getTank()); + assertEquals(0, transitPath.getRefillCount()); + assertEquals(1.85, transitPath.getFuelCost(), 0.01); + assertEquals(fuel, transitPath.getRemain(), 0.01); + + transitPath = new TransitPath(path, 0.54); + assertEquals(1, transitPath.getRefillCount()); + assertEquals(1.85, transitPath.getFuelCost(), 0.01); + assertEquals(0.15, transitPath.getRemain(), 0.01); + + transitPath = new TransitPath(path, 0.55); + assertEquals(1, transitPath.getRefillCount()); + assertEquals(1.85, transitPath.getFuelCost(), 0.01); + assertEquals(0.15, transitPath.getRemain(), 0.01); + + /* + "Transit Wolf 1278 - null(0.5300000082701445 - 2.0) -> Sarich Port" + "Transit Bhadaba - null(0.7500000033527613 - 2.0) -> Transit Wolf 1278" + "Quimper Ring - null(0.5500000078231096 - 2.0) -> Transit Bhadaba" + + */ + } + +} diff --git a/core/src/test/java/ru/trader/analysis/graph/TestGraph.java b/core/src/test/java/ru/trader/analysis/graph/TestGraph.java new file mode 100644 index 0000000..98aa530 --- /dev/null +++ b/core/src/test/java/ru/trader/analysis/graph/TestGraph.java @@ -0,0 +1,27 @@ +package ru.trader.analysis.graph; + +import ru.trader.analysis.AnalysisCallBack; +import ru.trader.core.Profile; + +import java.util.Collections; + +public class TestGraph> extends ConnectibleGraph { + public TestGraph(Profile profile, AnalysisCallBack callback) { + super(profile, callback); + } + + private Vertex createVertex(T entry){ + Vertex vertex = getVertex(entry).orElse(null); + if (vertex == null){ + vertex = newInstance(entry, vertexes.size()); + vertexes.add(vertex); + } + return vertex; + } + + public BuildEdge createEdge(T x1, T x2){ + ConnectibleGraphBuilder builder = new ConnectibleGraphBuilder(createVertex(x1), Collections.emptySet(), 0,0); + BuildHelper helper = builder.createHelper(x2); + return builder.createEdge(helper, createVertex(x2)); + } +}