fix fuel compute
This commit is contained in:
@@ -6,8 +6,7 @@ import ru.trader.analysis.graph.ConnectibleGraph;
|
|||||||
import ru.trader.analysis.graph.Path;
|
import ru.trader.analysis.graph.Path;
|
||||||
import ru.trader.core.Vendor;
|
import ru.trader.core.Vendor;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class TransitPath {
|
public class TransitPath {
|
||||||
private final List<ConnectibleEdge<Vendor>> entries;
|
private final List<ConnectibleEdge<Vendor>> entries;
|
||||||
@@ -16,82 +15,82 @@ public class TransitPath {
|
|||||||
private int refillCount;
|
private int refillCount;
|
||||||
|
|
||||||
public TransitPath(Path<Vendor> path, double fuel) {
|
public TransitPath(Path<Vendor> path, double fuel) {
|
||||||
List<ConnectibleGraph<Vendor>.BuildEdge> edges = path.getEdges();
|
entries = new ArrayList<>(path.getSize());
|
||||||
entries = new ArrayList<>(edges.size());
|
createEdges(path, fuel);
|
||||||
createEdges(edges, fuel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createEdges(List<ConnectibleGraph<Vendor>.BuildEdge> edges, double fuel) {
|
private void createEdges(Path<Vendor> path, double fuel) {
|
||||||
fuelCost = 0; refillCount = 0;
|
fuelCost = 0;
|
||||||
for (int i = edges.size() - 1; i >= 0; i--) {
|
refillCount = 0;
|
||||||
ConnectibleGraph<Vendor>.BuildEdge edge = edges.get(i);
|
|
||||||
|
for (Iterator<ConnectibleGraph<Vendor>.BuildEdge> iterator = path.listIterator(0); iterator.hasNext(); ) {
|
||||||
|
ConnectibleGraph<Vendor>.BuildEdge edge = iterator.next();
|
||||||
|
double cost = edge.getFuelCost(fuel);
|
||||||
|
|
||||||
ConnectibleEdge<Vendor> cEdge = new ConnectibleEdge<>(edge.getSource(), edge.getTarget());
|
ConnectibleEdge<Vendor> cEdge = new ConnectibleEdge<>(edge.getSource(), edge.getTarget());
|
||||||
double fuelCost = edge.getFuelCost(fuel);
|
cEdge.setFuelCost(cost);
|
||||||
this.fuelCost += fuelCost;
|
fuelCost += cost;
|
||||||
cEdge.setFuelCost(fuelCost);
|
|
||||||
entries.add(cEdge);
|
entries.add(cEdge);
|
||||||
if (fuel < 0 || fuel < edge.getMinFuel()){
|
|
||||||
if (refillCount == 0){
|
if (fuel < 0 || fuel < edge.getMinFuel()) {
|
||||||
fuel = refill(edges, 0);
|
//TODO: improve best refill place search
|
||||||
|
fuel = refill(path, false);
|
||||||
if (fuel < 0){
|
if (fuel < 0){
|
||||||
fuel = refill(edges, entries.size()-1);
|
fuel = refill(path, true);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fuel = refill(edges, entries.size()-1);
|
|
||||||
}
|
}
|
||||||
if (fuel < 0)
|
if (fuel < 0)
|
||||||
throw new IllegalStateException("Is not exists path");
|
throw new IllegalStateException("Is not exists path");
|
||||||
refillCount++;
|
|
||||||
} else {
|
} else {
|
||||||
fuel -= fuelCost;
|
fuel -= cost;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
remain = fuel;
|
remain = fuel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double refill(List<ConnectibleGraph<Vendor>.BuildEdge> edges, int startIndex){
|
private double refill(Path<Vendor> path, boolean includeTransit){
|
||||||
double max = -1;
|
int lastIndex = entries.size() - 1;
|
||||||
for (int i = startIndex; i >= 0; i--) {
|
double max = path.getMaxFuel(true, lastIndex);
|
||||||
ConnectibleGraph<Vendor>.BuildEdge e = edges.get(edges.size()-1-i);
|
|
||||||
if (max != -1){
|
ListIterator<ConnectibleEdge<Vendor>> iterator = entries.listIterator(lastIndex+1);
|
||||||
max += e.getFuelCost(max + e.getMinFuel());
|
int refillIndex = lastIndex;
|
||||||
}
|
ConnectibleEdge<Vendor> refillEdge = null;
|
||||||
Vendor source = e.getSource().getEntry();
|
while (iterator.hasPrevious()){
|
||||||
if (source.canRefill()){
|
refillEdge = iterator.previous();
|
||||||
ConnectibleEdge<Vendor> ce = entries.get(i);
|
if (refillEdge.getSource().getEntry().canRefill()){
|
||||||
if (ce.isRefill()){
|
if (refillEdge.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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (includeTransit || !refillEdge.getSource().getEntry().isTransit()){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
refillIndex--;
|
||||||
|
}
|
||||||
|
|
||||||
private double updateFuelCost(List<ConnectibleGraph<Vendor>.BuildEdge> edges, int startIndex, double fuel){
|
if (refillIndex < 0 || refillEdge == null) return -1;
|
||||||
for (int i = startIndex; i < entries.size(); i++) {
|
|
||||||
ConnectibleGraph<Vendor>.BuildEdge e = edges.get(edges.size()-1-i);
|
ConnectibleGraph<Vendor>.BuildEdge pathEdge = path.get(refillIndex);
|
||||||
if (fuel < 0 || fuel < e.getMinFuel()){
|
double fuel = Math.min(pathEdge.getShip().getRoundFuel(max), pathEdge.getRefill());
|
||||||
return -1;
|
refillEdge.setRefill(fuel);
|
||||||
|
refillCount++;
|
||||||
|
|
||||||
|
ListIterator<ConnectibleGraph<Vendor>.BuildEdge> pathIterator = path.listIterator(refillIndex);
|
||||||
|
while (iterator.hasNext()){
|
||||||
|
ConnectibleEdge<Vendor> edge = iterator.next();
|
||||||
|
pathEdge = pathIterator.next();
|
||||||
|
fuelCost -= edge.getFuelCost();
|
||||||
|
double cost = pathEdge.getFuelCost(fuel);
|
||||||
|
edge.setFuelCost(cost);
|
||||||
|
fuelCost += cost;
|
||||||
|
|
||||||
|
fuel -= cost;
|
||||||
}
|
}
|
||||||
ConnectibleEdge<Vendor> ce = entries.get(i);
|
|
||||||
double fuelCost = e.getFuelCost(fuel);
|
if (fuel < 0){
|
||||||
this.fuelCost += fuelCost - ce.getFuelCost();
|
refillEdge.setRefill(0);
|
||||||
ce.setFuelCost(fuelCost);
|
refillCount--;
|
||||||
fuel -= fuelCost;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fuel;
|
return fuel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ public class VendorsGraph extends ConnectibleGraph<Vendor> {
|
|||||||
Vertex<Vendor> target = lastEdge.getTarget();
|
Vertex<Vendor> target = lastEdge.getTarget();
|
||||||
assert vertex.getEntry().isTransit() && !target.getEntry().isTransit();
|
assert vertex.getEntry().isTransit() && !target.getEntry().isTransit();
|
||||||
VendorsGraphBuilder h = this;
|
VendorsGraphBuilder h = this;
|
||||||
Path<Vendor> path = new Path<>(Collections.singleton(lastEdge));
|
Path<Vendor> path = new Path<>(lastEdge);
|
||||||
while (h != null && h.edge != null){
|
while (h != null && h.edge != null){
|
||||||
if (callback.isCancel()) break;
|
if (callback.isCancel()) break;
|
||||||
BuildEdge cEdge = h.edge;
|
BuildEdge cEdge = h.edge;
|
||||||
@@ -175,7 +175,7 @@ public class VendorsGraph extends ConnectibleGraph<Vendor> {
|
|||||||
LOG.trace("Found loop, break");
|
LOG.trace("Found loop, break");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
path = path.add(cEdge);
|
path = path.addFirst(cEdge);
|
||||||
if (path.getMinFuel() > path.getMaxFuel()){
|
if (path.getMinFuel() > path.getMaxFuel()){
|
||||||
LOG.trace("Path inaccessible");
|
LOG.trace("Path inaccessible");
|
||||||
break;
|
break;
|
||||||
@@ -217,7 +217,7 @@ public class VendorsGraph extends ConnectibleGraph<Vendor> {
|
|||||||
assert vertex.getEntry().isTransit() && !target.getEntry().isTransit();
|
assert vertex.getEntry().isTransit() && !target.getEntry().isTransit();
|
||||||
List<Path<Vendor>> paths = lastEdge.paths;
|
List<Path<Vendor>> paths = lastEdge.paths;
|
||||||
int i = 1;
|
int i = 1;
|
||||||
Path<Vendor> path = paths != null ? paths.get(0) : new Path<>(Collections.singleton((BuildEdge)lastEdge));
|
Path<Vendor> path = paths != null ? paths.get(0) : new Path<>(lastEdge);
|
||||||
while (path != null){
|
while (path != null){
|
||||||
if (callback.isCancel()) break;
|
if (callback.isCancel()) break;
|
||||||
VendorsGraphBuilder h = this;
|
VendorsGraphBuilder h = this;
|
||||||
@@ -230,7 +230,7 @@ public class VendorsGraph extends ConnectibleGraph<Vendor> {
|
|||||||
LOG.trace("Found loop, break");
|
LOG.trace("Found loop, break");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
path = path.add(cEdge);
|
path = path.addFirst(cEdge);
|
||||||
if (path.getMinFuel() > path.getMaxFuel()){
|
if (path.getMinFuel() > path.getMaxFuel()){
|
||||||
LOG.trace("Path inaccessible");
|
LOG.trace("Path inaccessible");
|
||||||
break;
|
break;
|
||||||
@@ -286,7 +286,7 @@ public class VendorsGraph extends ConnectibleGraph<Vendor> {
|
|||||||
|
|
||||||
protected VendorsBuildEdge(BuildEdge edge) {
|
protected VendorsBuildEdge(BuildEdge edge) {
|
||||||
super(edge.getSource(), edge.getTarget());
|
super(edge.getSource(), edge.getTarget());
|
||||||
Path<Vendor> path = new Path<>(Collections.singleton(edge));
|
Path<Vendor> path = new Path<>(edge);
|
||||||
paths.add(path);
|
paths.add(path);
|
||||||
setFuel(path.getMinFuel(), path.getMaxFuel());
|
setFuel(path.getMinFuel(), path.getMaxFuel());
|
||||||
}
|
}
|
||||||
@@ -319,7 +319,7 @@ public class VendorsGraph extends ConnectibleGraph<Vendor> {
|
|||||||
public Path<Vendor> getPath(double fuel){
|
public Path<Vendor> getPath(double fuel){
|
||||||
Path<Vendor> res = null;
|
Path<Vendor> res = null;
|
||||||
for (Path<Vendor> p : paths) {
|
for (Path<Vendor> 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 (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)) {
|
if (res == null || (p.getSize() < res.getSize() || p.getSize() == res.getSize() && p.getFuelCost() < res.getFuelCost()) && p.getRefillCount(fuel) <= res.getRefillCount(fuel)) {
|
||||||
res = p;
|
res = p;
|
||||||
@@ -336,6 +336,7 @@ public class VendorsGraph extends ConnectibleGraph<Vendor> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isRemove(Path<Vendor> path, Path<Vendor> best){
|
private boolean isRemove(Path<Vendor> path, Path<Vendor> best){
|
||||||
|
if (path.getMinFuel() > path.getMaxFuel()) return true;
|
||||||
if (profile.getPathPriority() == Profile.PATH_PRIORITY.FAST){
|
if (profile.getPathPriority() == Profile.PATH_PRIORITY.FAST){
|
||||||
return (path.getSize() > best.getSize() || (path.getSize() == best.getSize() && path.getFuelCost() >= best.getFuelCost()))
|
return (path.getSize() > best.getSize() || (path.getSize() == best.getSize() && path.getFuelCost() >= best.getFuelCost()))
|
||||||
&& (path.getSource().canRefill() || path.getMinFuel() >= best.getMinFuel() && path.getRefillCount() >= best.getRefillCount())
|
&& (path.getSource().canRefill() || path.getMinFuel() >= best.getMinFuel() && path.getRefillCount() >= best.getRefillCount())
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class ConnectibleGraph<T extends Connectable<T>> extends AbstractGraph<T>
|
|||||||
double distance = vertex.getEntry().getDistance(entry);
|
double distance = vertex.getEntry().getDistance(entry);
|
||||||
if (distance > getShip().getMaxJumpRange()){
|
if (distance > getShip().getMaxJumpRange()){
|
||||||
LOG.trace("Vertex {} is far away, {}", entry, distance);
|
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 maxFuel = getShip().getMaxFuel(distance);
|
||||||
double minFuel = getShip().getMinFuel(distance);
|
double minFuel = getShip().getMinFuel(distance);
|
||||||
|
|||||||
@@ -2,60 +2,108 @@ package ru.trader.analysis.graph;
|
|||||||
|
|
||||||
import ru.trader.core.Ship;
|
import ru.trader.core.Ship;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Path<T extends Connectable<T>> {
|
public class Path<T extends Connectable<T>> {
|
||||||
private final List<ConnectibleGraph<T>.BuildEdge> entries;
|
private final LinkedList<ConnectibleGraph<T>.BuildEdge> entries;
|
||||||
private double minFuel;
|
private double minFuel;
|
||||||
private double maxFuel;
|
private double maxFuel;
|
||||||
private double fuelCost;
|
private double fuelCost;
|
||||||
private int refillCount;
|
private int refillCount;
|
||||||
|
|
||||||
|
public Path(ConnectibleGraph<T>.BuildEdge edge) {
|
||||||
|
this(edge, true);
|
||||||
|
}
|
||||||
|
|
||||||
public Path(Collection<ConnectibleGraph<T>.BuildEdge> edges) {
|
public Path(Collection<ConnectibleGraph<T>.BuildEdge> edges) {
|
||||||
entries = new ArrayList<>(edges);
|
this(edges, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path(Collection<ConnectibleGraph<T>.BuildEdge> edges, boolean update) {
|
||||||
|
entries = new LinkedList<>(edges);
|
||||||
|
if (update){
|
||||||
updateStat();
|
updateStat();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path(ConnectibleGraph<T>.BuildEdge edge, boolean update) {
|
||||||
|
entries = new LinkedList<>();
|
||||||
|
entries.add(edge);
|
||||||
|
if (update){
|
||||||
|
updateStat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateStat(){
|
private void updateStat(){
|
||||||
Ship ship = entries.get(0).getShip();
|
Ship ship = entries.get(0).getShip();
|
||||||
double fuel = ship.getTank();
|
double fuel = ship.getTank();
|
||||||
minFuel = 0; maxFuel = 0; fuelCost = 0; refillCount = 0;
|
minFuel = 0; maxFuel = 0; fuelCost = 0; refillCount = 0;
|
||||||
int minTo = 0;
|
boolean refillFound = false;
|
||||||
for (int i = entries.size() - 1; i >= 0; i--) {
|
int index = -1; double f = ship.getTank();
|
||||||
ConnectibleGraph<T>.BuildEdge edge = entries.get(i);
|
ConnectibleGraph<T>.BuildEdge prevEdge = null;
|
||||||
if (i < entries.size() - 1 && edge.getSource().getEntry().canRefill()){
|
for (ConnectibleGraph<T>.BuildEdge edge : entries) {
|
||||||
if (minTo == 0) minTo = i+1;
|
index++;
|
||||||
fuel = edge.getMaxFuel();
|
|
||||||
|
if (index > 0 && edge.getSource().getEntry().canRefill()){
|
||||||
|
refillFound = true;
|
||||||
|
f = edge.getMaxFuel();
|
||||||
}
|
}
|
||||||
if (fuel < 0 || fuel < edge.getMinFuel()){
|
|
||||||
minFuel = ship.getTank()+1;
|
if (!refillFound){
|
||||||
minTo = -1;
|
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);
|
double cost = edge.getFuelCost(fuel);
|
||||||
fuelCost += cost;
|
|
||||||
fuel -= cost;
|
fuel -= cost;
|
||||||
|
if (fuel < 0){
|
||||||
|
refillCount++;
|
||||||
|
fuel = f;
|
||||||
|
cost = c;
|
||||||
}
|
}
|
||||||
maxFuel = -1;
|
fuelCost += cost;
|
||||||
for (int i = 0; i < entries.size(); i++) {
|
|
||||||
ConnectibleGraph<T>.BuildEdge edge = entries.get(i);
|
if (f < 0){
|
||||||
if (maxFuel != -1) {
|
minFuel = ship.getTank()+1;
|
||||||
maxFuel += edge.getFuelCost(maxFuel + edge.getMinFuel());
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
prevEdge = edge;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxFuel = getMaxFuel(false, entries.size()-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMaxFuel(boolean fromRefill, int endIndex){
|
||||||
|
double maxFuel = -1;
|
||||||
|
for (ListIterator<ConnectibleGraph<T>.BuildEdge> iterator = entries.listIterator(endIndex+1); iterator.hasPrevious(); ) {
|
||||||
|
ConnectibleGraph<T>.BuildEdge edge = iterator.previous();
|
||||||
|
if (maxFuel > -1) {
|
||||||
|
maxFuel += edge.getFuelCost(edge.getMinFuel());
|
||||||
}
|
}
|
||||||
if (maxFuel == -1 || edge.getMaxFuel() < maxFuel) {
|
if (maxFuel == -1 || edge.getMaxFuel() < maxFuel) {
|
||||||
maxFuel = edge.getMaxFuel();
|
maxFuel = edge.getMaxFuel();
|
||||||
}
|
}
|
||||||
if (minTo != -1 && i >= minTo) {
|
if (fromRefill && edge.getSource().getEntry().canRefill()){
|
||||||
minFuel += edge.getFuelCost(minFuel + edge.getMinFuel());
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
refillCount = getRefillCount(ship.getTank());
|
return maxFuel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ConnectibleGraph<T>.BuildEdge> getEdges() {
|
public ConnectibleGraph<T>.BuildEdge get(int index){
|
||||||
return entries;
|
return entries.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListIterator<ConnectibleGraph<T>.BuildEdge> listIterator(int startIndex){
|
||||||
|
return entries.listIterator(startIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getFuelCost() {
|
public double getFuelCost() {
|
||||||
@@ -80,8 +128,7 @@ public class Path<T extends Connectable<T>> {
|
|||||||
|
|
||||||
public int getRefillCount(double fuel){
|
public int getRefillCount(double fuel){
|
||||||
int res = 0;
|
int res = 0;
|
||||||
for (int i = entries.size() - 1; i >= 0; i--) {
|
for (ConnectibleGraph<T>.BuildEdge edge : entries) {
|
||||||
ConnectibleGraph<T>.BuildEdge edge = entries.get(i);
|
|
||||||
fuel -= edge.getFuelCost(fuel);
|
fuel -= edge.getFuelCost(fuel);
|
||||||
if (fuel < 0) {
|
if (fuel < 0) {
|
||||||
res++;
|
res++;
|
||||||
@@ -91,26 +138,35 @@ public class Path<T extends Connectable<T>> {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Path<T> add(ConnectibleGraph<T>.BuildEdge edge){
|
public Path<T> addFirst(ConnectibleGraph<T>.BuildEdge edge){
|
||||||
Path<T> res = new Path<>(entries);
|
Path<T> res = new Path<>(entries, false);
|
||||||
res.entries.add(edge);
|
res.entries.addFirst(edge);
|
||||||
|
res.updateStat();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Path<T> addLast(ConnectibleGraph<T>.BuildEdge edge){
|
||||||
|
Path<T> res = new Path<>(entries, false);
|
||||||
|
res.entries.addLast(edge);
|
||||||
res.updateStat();
|
res.updateStat();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T getSource(){
|
public T getSource(){
|
||||||
return entries.get(entries.size()-1).getSource().getEntry();
|
return entries.getFirst().getSource().getEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final StringBuilder sb = new StringBuilder("{");
|
final StringBuilder sb = new StringBuilder("{");
|
||||||
for (int i = entries.size() - 1; i >= 0; i--) {
|
int i = -1;
|
||||||
ConnectibleGraph<T>.BuildEdge entry = entries.get(i);
|
for (ConnectibleGraph<T>.BuildEdge entry : entries) {
|
||||||
|
i++;
|
||||||
sb.append(entry);
|
sb.append(entry);
|
||||||
if (i>0)
|
if (i < entries.size()-1){
|
||||||
sb.append(", ");
|
sb.append(", ");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
sb.append('}');
|
sb.append('}');
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
231
core/src/test/java/ru/trader/analysis/graph/PathTest.java
Normal file
231
core/src/test/java/ru/trader/analysis/graph/PathTest.java
Normal file
@@ -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<Point> graph = new TestGraph<>(profile, new AnalysisCallBack());
|
||||||
|
LOG.info("Ship = {}", profile.getShip());
|
||||||
|
|
||||||
|
Collection<ConnectibleGraph<Point>.BuildEdge> edges = new ArrayList<>();
|
||||||
|
ConnectibleGraph<Point>.BuildEdge edge1 = graph.createEdge(x1,x2);
|
||||||
|
|
||||||
|
edges.add(edge1);
|
||||||
|
Path<Point> 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<Point>.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<Point>.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<ConnectibleGraph<Vendor>.BuildEdge> edges, double fuel, double tank, int refill){
|
||||||
|
boolean isFirst = true;
|
||||||
|
for (ConnectibleGraph<Vendor>.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<Vendor> 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<ConnectibleGraph<Vendor>.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<Vendor> 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"
|
||||||
|
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
27
core/src/test/java/ru/trader/analysis/graph/TestGraph.java
Normal file
27
core/src/test/java/ru/trader/analysis/graph/TestGraph.java
Normal file
@@ -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<T extends Connectable<T>> extends ConnectibleGraph<T> {
|
||||||
|
public TestGraph(Profile profile, AnalysisCallBack callback) {
|
||||||
|
super(profile, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vertex<T> createVertex(T entry){
|
||||||
|
Vertex<T> 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<T> helper = builder.createHelper(x2);
|
||||||
|
return builder.createEdge(helper, createVertex(x2));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user