Archived
0

- fix lands count

- fix memory leak on big jumps count
- fix remove order from route
- add path adding
This commit is contained in:
iMoHax
2014-08-21 16:46:13 +04:00
parent 14c2021e0c
commit d70bbb005c
17 changed files with 471 additions and 163 deletions

View File

@@ -19,7 +19,6 @@ import ru.trader.model.OrderModel;
import ru.trader.model.support.BindingsHelper; import ru.trader.model.support.BindingsHelper;
import java.util.Collection; import java.util.Collection;
import java.util.Optional;
public class OrdersController { public class OrdersController {
private final Action OK = new AbstractAction("OK") { private final Action OK = new AbstractAction("OK") {
@@ -84,7 +83,7 @@ public class OrdersController {
} }
private Collection<OrderModel> getOrders() { private Collection<OrderModel> getOrders() {
return tblOrders.getItems().filtered((o) -> o.getCount()>0 && o.getBuyer()!=null); return tblOrders.getItems().filtered((o) -> o.getCount()>0 && o.getBuyOffer()!=null);
} }
private void init(Collection<OfferDescModel> offers, double balance, long max) { private void init(Collection<OfferDescModel> offers, double balance, long max) {
@@ -105,7 +104,7 @@ public class OrdersController {
private void setBuyer(OfferModel offer) { private void setBuyer(OfferModel offer) {
if (order != null && offer!=null) { if (order != null && offer!=null) {
order.setBuyer(offer); order.setBuyOffer(offer);
order.setCount(order.getMax()); order.setCount(order.getMax());
} }
} }

View File

@@ -1,6 +1,7 @@
package ru.trader.controllers; package ru.trader.controllers;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
import javafx.fxml.FXML; import javafx.fxml.FXML;
@@ -13,9 +14,6 @@ import ru.trader.view.support.NumberField;
import ru.trader.view.support.RouteNode; import ru.trader.view.support.RouteNode;
import java.util.Collection;
public class RoutersController { public class RoutersController {
@FXML @FXML
@@ -33,7 +31,10 @@ public class RoutersController {
private ScrollPane path; private ScrollPane path;
@FXML @FXML
private Button add; private Button editBtn;
@FXML
private Button removeBtn;
@FXML @FXML
private ComboBox<VendorModel> source; private ComboBox<VendorModel> source;
@@ -51,22 +52,36 @@ public class RoutersController {
private MarketModel market; private MarketModel market;
private PathRouteModel route;
@FXML @FXML
private void initialize(){ private void initialize(){
init(); init();
balance.numberProperty().addListener((ov, o, n) -> totalBalance.setValue(n)); balance.numberProperty().addListener((ov, o, n) -> totalBalance.setValue(n));
cargo.numberProperty().addListener((ov, o, n) -> market.setCargo(n.longValue())); cargo.numberProperty().addListener((ov, o, n) -> market.setCargo(n.intValue()));
tank.numberProperty().addListener((ov, o, n) -> market.setTank(n.doubleValue())); tank.numberProperty().addListener((ov, o, n) -> market.setTank(n.doubleValue()));
distance.numberProperty().addListener((ov, o, n) -> market.setDistance(n.doubleValue())); distance.numberProperty().addListener((ov, o, n) -> market.setDistance(n.doubleValue()));
jumps.numberProperty().addListener((ov, o, n) -> market.setJumps(n.intValue())); jumps.numberProperty().addListener((ov, o, n) -> market.setJumps(n.intValue()));
balance.setOnAction((v)->cargo.requestFocus());
cargo.setOnAction((v) -> tank.requestFocus());
tank.setOnAction((v) -> distance.requestFocus());
distance.setOnAction((v)->jumps.requestFocus());
jumps.setOnAction((v)->balance.requestFocus());
balance.setValue(1000); balance.setValue(1000);
cargo.setValue(4); cargo.setValue(4);
tank.setValue(20); tank.setValue(20);
distance.setValue(7); distance.setValue(7);
jumps.setValue(3); jumps.setValue(3);
add.disableProperty().bind(this.balance.wrongProperty().or(this.cargo.wrongProperty())); editBtn.disableProperty().bind(tblOrders.getSelectionModel().selectedIndexProperty().isEqualTo(-1));
removeBtn.disableProperty().bind(Bindings.createBooleanBinding(()-> {
int sel = tblOrders.getSelectionModel().getSelectedIndex();
return sel == -1 || sel != tblOrders.getItems().size()-1;
}, tblOrders.getSelectionModel().selectedIndexProperty()));
tblOrders.setItems(FXCollections.observableArrayList()); tblOrders.setItems(FXCollections.observableArrayList());
tblOrders.getItems().addListener((ListChangeListener<OrderModel>) c -> { tblOrders.getItems().addListener((ListChangeListener<OrderModel>) c -> {
while (c.next()) { while (c.next()) {
@@ -96,35 +111,47 @@ public class RoutersController {
totalProfit.setValue(0); totalProfit.setValue(0);
} }
private Collection<OfferDescModel> getOffers(){
VendorModel vendor = source.getSelectionModel().getSelectedItem();
return vendor.getSells(market::asOfferDescModel);
}
private void onAdd(OrderModel order){ private void onAdd(OrderModel order){
totalProfit.add(order.getProfit()); totalProfit.add(order.getProfit());
totalBalance.add(order.getProfit()); totalBalance.add(order.getProfit());
source.getSelectionModel().select(order.getBuyer().getVendor()); source.getSelectionModel().select(order.getBuyOffer().getVendor());
balance.setDisable(true);
source.setDisable(true);
} }
private void onRemove(OrderModel order) { private void onRemove(OrderModel order) {
totalProfit.sub(order.getProfit()); totalProfit.sub(order.getProfit());
totalBalance.sub(order.getProfit()); totalBalance.sub(order.getProfit());
source.getSelectionModel().select(order.getVendor()); source.getSelectionModel().select(order.getVendor());
if (tblOrders.getItems().isEmpty()) {
balance.setDisable(false);
source.setDisable(false);
}
} }
public void addOrders(){ public void editOrders(){
Collection<OrderModel> orders = Screeners.showOrders(getOffers(), totalBalance.getValue().doubleValue(), cargo.getValue().longValue()); OrderModel sel = tblOrders.getSelectionModel().getSelectedItem();
if (orders!=null){ int index = tblOrders.getSelectionModel().getSelectedIndex();
tblOrders.getItems().addAll(orders);
OrderModel order = Screeners.showOrders(market.getOrders(sel.getVendor(), sel.getBuyer(), sel.getBalance()));
if (order!=null){
tblOrders.getItems().set(index, order);
} }
} }
public void removeSelected(){ public void removeSelected(){
TableView.TableViewSelectionModel<OrderModel> select = tblOrders.getSelectionModel(); TableView.TableViewSelectionModel<OrderModel> select = tblOrders.getSelectionModel();
if (!select.isEmpty()){ if (!select.isEmpty()){
int index = select.getSelectedIndex(); int index = select.getSelectedIndex();
if (index > 0){
route = route.remove(select.getSelectedItem());
} else {
route = null;
}
tblOrders.getItems().remove(index); tblOrders.getItems().remove(index);
refreshPath();
} }
} }
@@ -132,14 +159,16 @@ public class RoutersController {
tblOrders.getItems().clear(); tblOrders.getItems().clear();
totalBalance.setValue(balance.getValue()); totalBalance.setValue(balance.getValue());
totalProfit.setValue(0); totalProfit.setValue(0);
path.setContent(null); route = null;
refreshPath();
} }
public void showTopOrders(){ public void showTopOrders(){
OrderModel order = Screeners.showTopOrders(market.getTop(100, totalBalance.getValue().doubleValue())); OrderModel order = Screeners.showOrders(market.getTop(100, totalBalance.getValue().doubleValue()));
if (order!=null){ if (order!=null){
tblOrders.getItems().add(order); tblOrders.getItems().add(order);
addOrderToPath(order);
} }
} }
@@ -148,12 +177,13 @@ public class RoutersController {
VendorModel t = target.getSelectionModel().getSelectedItem(); VendorModel t = target.getSelectionModel().getSelectedItem();
OrderModel order; OrderModel order;
if (t==null){ if (t==null){
order = Screeners.showTopOrders(market.getOrders(s, totalBalance.getValue().doubleValue())); order = Screeners.showOrders(market.getOrders(s, totalBalance.getValue().doubleValue()));
} else { } else {
order = Screeners.showTopOrders(market.getOrders(t, s, totalBalance.getValue().doubleValue())); order = Screeners.showOrders(market.getOrders(t, s, totalBalance.getValue().doubleValue()));
} }
if (order!=null){ if (order!=null){
tblOrders.getItems().add(order); tblOrders.getItems().add(order);
addOrderToPath(order);
} }
} }
@@ -168,7 +198,7 @@ public class RoutersController {
} }
if (path!=null){ if (path!=null){
tblOrders.getItems().addAll(path.getOrders()); tblOrders.getItems().addAll(path.getOrders());
setPath(path); addRouteToPath(path);
} }
} }
@@ -176,12 +206,33 @@ public class RoutersController {
PathRouteModel path = Screeners.showRouters(market.getTopRoutes(totalBalance.getValue().doubleValue())); PathRouteModel path = Screeners.showRouters(market.getTopRoutes(totalBalance.getValue().doubleValue()));
if (path!=null){ if (path!=null){
tblOrders.getItems().addAll(path.getOrders()); tblOrders.getItems().addAll(path.getOrders());
setPath(path); addRouteToPath(path);
} }
} }
private void setPath(PathRouteModel route){ private void addRouteToPath(PathRouteModel route){
if (this.route == null){
this.route = route;
} else {
this.route.add(route.getPath());
}
refreshPath();
}
private void addOrderToPath(OrderModel order){
if (route != null){
route.add(order);
} else {
route = market.getPath(order);
}
refreshPath();
}
private void refreshPath(){
if (route != null)
path.setContent(new RouteNode(route).getNode()); path.setContent(new RouteNode(route).getNode());
else
path.setContent(null);
} }
} }

View File

@@ -156,8 +156,8 @@ public class Screeners {
itemDescController.close(); itemDescController.close();
} }
public static OrderModel showTopOrders(ObservableList<OrderModel> top) { public static OrderModel showOrders(ObservableList<OrderModel> orders) {
return topOrdersController.showDialog(mainScreen, topOrdersScreen, top); return topOrdersController.showDialog(mainScreen, topOrdersScreen, orders);
} }
public static PathRouteModel showRouters(ObservableList<PathRouteModel> routers) { public static PathRouteModel showRouters(ObservableList<PathRouteModel> routers) {

View File

@@ -178,7 +178,7 @@ public class MarketModel {
} }
public void setCargo(long cargo){ public void setCargo(int cargo){
analyzer.setCargo(cargo); analyzer.setCargo(cargo);
} }
@@ -218,4 +218,15 @@ public class MarketModel {
return BindingsHelper.observableList(analyzer.getTopPaths(100, balance), this::asModel); return BindingsHelper.observableList(analyzer.getTopPaths(100, balance), this::asModel);
} }
PathRoute getPath(VendorModel from, VendorModel to) {
return analyzer.getPath(from.getVendor(), to.getVendor());
}
public PathRouteModel getPath(OrderModel order) {
PathRoute p = analyzer.getPath(order.getVendor().getVendor(), order.getBuyer().getVendor());
p.setOrder(new Order(order.getOffer().getOffer(), order.getBuyOffer().getOffer(), order.getCount()));
order.setPath(p);
return asModel(p);
}
} }

View File

@@ -2,6 +2,8 @@ package ru.trader.model;
import javafx.beans.property.*; import javafx.beans.property.*;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import ru.trader.core.Order;
import ru.trader.graph.PathRoute;
import ru.trader.model.support.ModelBindings; import ru.trader.model.support.ModelBindings;
import java.util.List; import java.util.List;
@@ -16,6 +18,7 @@ public class OrderModel {
private DoubleProperty profit; private DoubleProperty profit;
private DoubleProperty distance; private DoubleProperty distance;
private DoubleProperty bestProfit; private DoubleProperty bestProfit;
private PathRoute path;
public OrderModel(OfferDescModel offer) { public OrderModel(OfferDescModel offer) {
this.offer = offer; this.offer = offer;
@@ -34,7 +37,7 @@ public class OrderModel {
public OrderModel(OfferDescModel sellOffer, OfferModel buyOffer, long max) { public OrderModel(OfferDescModel sellOffer, OfferModel buyOffer, long max) {
this(sellOffer); this(sellOffer);
this.max = max; this.max = max;
setBuyer(buyOffer); setBuyOffer(buyOffer);
setCount(max); setCount(max);
} }
@@ -95,16 +98,16 @@ public class OrderModel {
return profitProperty().get(); return profitProperty().get();
} }
public ReadOnlyObjectProperty<OfferModel> buyerProperty() { public ReadOnlyObjectProperty<OfferModel> buyOfferProperty() {
return buyer; return buyer;
} }
public void setBuyer(OfferModel buyer) { public void setBuyOffer(OfferModel buyer) {
this.buyer.set(buyer); this.buyer.set(buyer);
if (distance!=null) distance.set(getVendor().getDistance(buyer.getVendor())); if (distance!=null) distance.set(getVendor().getDistance(buyer.getVendor()));
} }
public OfferModel getBuyer() { public OfferModel getBuyOffer() {
return buyer.get(); return buyer.get();
} }
@@ -112,6 +115,11 @@ public class OrderModel {
return offer.getOffer().getVendor(); return offer.getOffer().getVendor();
} }
public VendorModel getBuyer() {
OfferModel buyOffer = getBuyOffer();
return buyOffer != null ? buyer.get().getVendor() : null;
}
public long getMax() { public long getMax() {
return max; return max;
} }
@@ -126,11 +134,22 @@ public class OrderModel {
public ReadOnlyDoubleProperty distanceProperty() { public ReadOnlyDoubleProperty distanceProperty() {
if (distance == null){ if (distance == null){
OfferModel buyOffer = getBuyer(); VendorModel buyer = getBuyer();
distance = new SimpleDoubleProperty(buyOffer!=null ? getVendor().getDistance(buyOffer.getVendor()) : Double.NaN); distance = new SimpleDoubleProperty(buyer!=null ? getVendor().getDistance(buyer) : Double.NaN);
} }
return distance; return distance;
} }
void setPath(PathRoute path) {
this.path = path;
}
PathRoute getPath() {
return path;
}
public double getBalance(){
return path != null ? path.getBalance() : max * offer.getPrice();
}
} }

View File

@@ -21,15 +21,14 @@ public class PathRouteModel {
this.path = path; this.path = path;
PathRoute p = path.getRoot(); PathRoute p = path.getRoot();
totalProfit = p.getProfit(); totalProfit = p.getProfit();
double d = 0; int j = 0, r = 0, l = 0; lands = p.getLandsCount();
double d = 0; int j = 0, r = 0;
while (p.hasNext()){ while (p.hasNext()){
p = p.getNext(); p = p.getNext();
d += p.getDistance(); d += p.getDistance();
j++; j++;
if (p.isRefill()) r++; if (p.isRefill()) r++;
if (p.getBest() != null || p.isRefill()) l++;
} }
lands = l;
distance = d; distance = d;
jumps = j; jumps = j;
refuels = r; refuels = r;
@@ -71,7 +70,9 @@ public class PathRouteModel {
p = p.getNext(); p = p.getNext();
if (cargo == null && p.getBest()!=null){ if (cargo == null && p.getBest()!=null){
cargo = p.getBest(); cargo = p.getBest();
res.add(market.asModel(cargo)); OrderModel order = market.asModel(cargo);
order.setPath(p);
res.add(order);
} }
if (cargo!=null && cargo.isBuyer(p.get())){ if (cargo!=null && cargo.isBuyer(p.get())){
cargo = null; cargo = null;
@@ -79,4 +80,21 @@ public class PathRouteModel {
} }
return res; return res;
} }
public void add(OrderModel order){
PathRoute p = market.getPath(order.getVendor(), order.getBuyer());
if (p == null) return;
p.getRoot().getNext().setOrder(new Order(order.getOffer().getOffer(), order.getBuyOffer().getOffer(), order.getCount()));
PathRoute head = path.getEnd();
add(p);
order.setPath(head);
}
public void add(PathRoute route){
path.getEnd().add(route, true);
}
public PathRouteModel remove(OrderModel order) {
return new PathRouteModel(path.dropTo(order.getVendor().getVendor()), market);
}
} }

View File

@@ -25,7 +25,7 @@
<cellValueFactory><PropertyValueFactory property="count"/></cellValueFactory> <cellValueFactory><PropertyValueFactory property="count"/></cellValueFactory>
</TableColumn> </TableColumn>
<TableColumn minWidth="160.0" text="Покупатель"> <TableColumn minWidth="160.0" text="Покупатель">
<cellValueFactory><OfferCellValueImpl property="buyer"/></cellValueFactory> <cellValueFactory><OfferCellValueImpl property="buyOffer"/></cellValueFactory>
</TableColumn> </TableColumn>
<TableColumn minWidth="80.0" text="Прибыль"> <TableColumn minWidth="80.0" text="Прибыль">
<cellFactory><DoubleCell/></cellFactory> <cellFactory><DoubleCell/></cellFactory>

View File

@@ -47,8 +47,8 @@
<Separator GridPane.columnSpan="2" GridPane.rowIndex="3" GridPane.margin="$separator_margin"/> <Separator GridPane.columnSpan="2" GridPane.rowIndex="3" GridPane.margin="$separator_margin"/>
<VBox GridPane.columnSpan="2" GridPane.rowIndex="4" spacing="5"> <VBox GridPane.columnSpan="2" GridPane.rowIndex="4" spacing="5">
<HBox alignment="CENTER" spacing="5"> <HBox alignment="CENTER" spacing="5">
<Button fx:id="add" text="Добавить" onAction="#addOrders"/> <Button fx:id="editBtn" text="Изменить" onAction="#editOrders"/>
<Button text="Удалить" onAction="#removeSelected"/> <Button fx:id="removeBtn" text="Удалить" onAction="#removeSelected"/>
<Button text="Очистить" onAction="#removeAll" /> <Button text="Очистить" onAction="#removeAll" />
</HBox> </HBox>
<HBox alignment="CENTER" spacing="5"> <HBox alignment="CENTER" spacing="5">
@@ -93,7 +93,7 @@
<cellValueFactory><PropertyValueFactory property="count"/></cellValueFactory> <cellValueFactory><PropertyValueFactory property="count"/></cellValueFactory>
</TableColumn> </TableColumn>
<TableColumn minWidth="120.0" text="Покупатель"> <TableColumn minWidth="120.0" text="Покупатель">
<cellValueFactory><OfferCellValueImpl property="buyer"/></cellValueFactory> <cellValueFactory><OfferCellValueImpl property="buyOffer"/></cellValueFactory>
</TableColumn> </TableColumn>
<TableColumn minWidth="80.0" text="Дистанция"> <TableColumn minWidth="80.0" text="Дистанция">
<cellFactory><DoubleCell format="\%.2f LY"/></cellFactory> <cellFactory><DoubleCell format="\%.2f LY"/></cellFactory>

View File

@@ -24,7 +24,7 @@
<cellValueFactory><PropertyValueFactory property="count"/></cellValueFactory> <cellValueFactory><PropertyValueFactory property="count"/></cellValueFactory>
</TableColumn> </TableColumn>
<TableColumn minWidth="160.0" text="Покупатель"> <TableColumn minWidth="160.0" text="Покупатель">
<cellValueFactory><OfferCellValueImpl property="buyer"/></cellValueFactory> <cellValueFactory><OfferCellValueImpl property="buyOffer"/></cellValueFactory>
</TableColumn> </TableColumn>
<TableColumn minWidth="80.0" text="Дистанция"> <TableColumn minWidth="80.0" text="Дистанция">
<cellFactory><DoubleCell format="\%.2f LY"/></cellFactory> <cellFactory><DoubleCell format="\%.2f LY"/></cellFactory>

View File

@@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory;
import ru.trader.graph.Graph; import ru.trader.graph.Graph;
import ru.trader.graph.Path; import ru.trader.graph.Path;
import ru.trader.graph.PathRoute; import ru.trader.graph.PathRoute;
import ru.trader.graph.RouteGraph;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@@ -15,11 +16,11 @@ public class MarketAnalyzer {
private final static Logger LOG = LoggerFactory.getLogger(MarketAnalyzer.class); private final static Logger LOG = LoggerFactory.getLogger(MarketAnalyzer.class);
private Market market; private Market market;
private Graph<Vendor> graph; private RouteGraph graph;
private double tank; private double tank;
private double maxDistance; private double maxDistance;
private int jumps; private int jumps;
private long cargo; private int cargo;
public MarketAnalyzer(Market market) { public MarketAnalyzer(Market market) {
@@ -31,6 +32,7 @@ public class MarketAnalyzer {
TreeSet<Order> top = new TreeSet<>(); TreeSet<Order> top = new TreeSet<>();
for (Vendor vendor : market.get()) { for (Vendor vendor : market.get()) {
LOG.trace("Check vendor {}", vendor); LOG.trace("Check vendor {}", vendor);
setSource(vendor);
for (Offer sell : vendor.getAllSellOffers()) { for (Offer sell : vendor.getAllSellOffers()) {
long count = Math.min(cargo, (long) Math.floor(balance / sell.getPrice())); long count = Math.min(cargo, (long) Math.floor(balance / sell.getPrice()));
LOG.trace("Sell offer {}, count = {}", sell, count); LOG.trace("Sell offer {}, count = {}", sell, count);
@@ -38,6 +40,10 @@ public class MarketAnalyzer {
Iterator<Offer> buyers = market.getStatBuy(sell.getItem()).getOffers().descendingIterator(); Iterator<Offer> buyers = market.getStatBuy(sell.getItem()).getOffers().descendingIterator();
while (buyers.hasNext()){ while (buyers.hasNext()){
Offer buy = buyers.next(); Offer buy = buyers.next();
if (!graph.isAccessible(buy.getVendor())){
LOG.trace("Is inaccessible buyer, skip");
continue;
}
Order order = new Order(sell, buy, count); Order order = new Order(sell, buy, count);
LOG.trace("Buy offer {} profit = {}", buy, order.getProfit()); LOG.trace("Buy offer {} profit = {}", buy, order.getProfit());
if (order.getProfit() <= 0 ) break; if (order.getProfit() <= 0 ) break;
@@ -62,6 +68,7 @@ public class MarketAnalyzer {
public Collection<Order> getOrders(Vendor vendor, double balance) { public Collection<Order> getOrders(Vendor vendor, double balance) {
Collection<Order> res = new ArrayList<>(); Collection<Order> res = new ArrayList<>();
setSource(vendor);
for (Offer sell : vendor.getAllSellOffers()) { for (Offer sell : vendor.getAllSellOffers()) {
long count = Math.min(cargo, (long) Math.floor(balance / sell.getPrice())); long count = Math.min(cargo, (long) Math.floor(balance / sell.getPrice()));
LOG.trace("Sell offer {}, count = {}", sell, count); LOG.trace("Sell offer {}, count = {}", sell, count);
@@ -69,6 +76,10 @@ public class MarketAnalyzer {
Iterator<Offer> buyers = market.getStatBuy(sell.getItem()).getOffers().descendingIterator(); Iterator<Offer> buyers = market.getStatBuy(sell.getItem()).getOffers().descendingIterator();
while (buyers.hasNext()){ while (buyers.hasNext()){
Offer buy = buyers.next(); Offer buy = buyers.next();
if (!graph.isAccessible(buy.getVendor())){
LOG.trace("Is inaccessible buyer, skip");
continue;
}
Order order = new Order(sell, buy, count); Order order = new Order(sell, buy, count);
LOG.trace("Buy offer {} profit = {}", buy, order.getProfit()); LOG.trace("Buy offer {} profit = {}", buy, order.getProfit());
res.add(order); res.add(order);
@@ -79,6 +90,11 @@ public class MarketAnalyzer {
public Collection<Order> getOrders(Vendor from, Vendor to, double balance) { public Collection<Order> getOrders(Vendor from, Vendor to, double balance) {
Collection<Order> res = new ArrayList<>(); Collection<Order> res = new ArrayList<>();
setSource(from);
if (!graph.isAccessible(to)){
LOG.trace("Is inaccessible buyer");
return res;
}
for (Offer sell : from.getAllSellOffers()) { for (Offer sell : from.getAllSellOffers()) {
long count = Math.min(cargo, (long) Math.floor(balance / sell.getPrice())); long count = Math.min(cargo, (long) Math.floor(balance / sell.getPrice()));
LOG.trace("Sell offer {}, count = {}", sell, count); LOG.trace("Sell offer {}, count = {}", sell, count);
@@ -97,7 +113,8 @@ public class MarketAnalyzer {
private void rebuild(Vendor source){ private void rebuild(Vendor source){
graph = new Graph<>(source, market.get(), tank, maxDistance, true, jumps, PathRoute::new); graph = new RouteGraph(source, market.get(), tank, maxDistance, true, jumps);
graph.setLimit(cargo);
} }
private void setSource(Vendor source){ private void setSource(Vendor source){
@@ -107,42 +124,46 @@ public class MarketAnalyzer {
public Collection<Path<Vendor>> getPaths(Vendor from, Vendor to){ public Collection<Path<Vendor>> getPaths(Vendor from, Vendor to){
setSource(from); setSource(from);
return graph.getPathsTo(to, true); return graph.getPathsTo(to);
} }
public Path<Vendor> getPath(Vendor from, Vendor to){ public PathRoute getPath(Vendor from, Vendor to){
setSource(from); setSource(from);
return graph.getFastPathTo(to); return (PathRoute) graph.getFastPathTo(to);
} }
public Collection<PathRoute> getPaths(Vendor from, double balance){ public Collection<PathRoute> getPaths(Vendor from, double balance){
setSource(from);
graph.setBalance(balance);
Collection<PathRoute> res = new ArrayList<>(); Collection<PathRoute> res = new ArrayList<>();
for (Vendor vendor : market.get()) { for (Vendor vendor : market.get()) {
PathRoute path = (PathRoute) getPath(from, vendor); Collection<Path<Vendor>> paths = graph.getPathsTo(vendor, 10);
if (path == null) continue; for (Path<Vendor> path : paths) {
path.sort(balance, cargo); res.add((PathRoute) path);
res.add(path); }
} }
return res; return res;
} }
public Collection<PathRoute> getPaths(Vendor from, Vendor to, double balance){ public Collection<PathRoute> getPaths(Vendor from, Vendor to, double balance){
Collection<Path<Vendor>> paths = getPaths(from, to); setSource(from);
graph.setBalance(balance);
Collection<Path<Vendor>> paths = graph.getPathsTo(to);
Collection<PathRoute> res = new ArrayList<>(paths.size()); Collection<PathRoute> res = new ArrayList<>(paths.size());
for (Path<Vendor> path : paths) { for (Path<Vendor> path : paths) {
PathRoute p = (PathRoute) path; res.add((PathRoute) path);
p.sort(balance, cargo);
res.add(p);
} }
return res; return res;
} }
public Collection<PathRoute> getTopPaths(int limit, double balance){ public Collection<PathRoute> getTopPaths(int limit, double balance){
TreeSet<PathRoute> top = new TreeSet<>((p1, p2) -> Double.compare(p2.getProfit(), p1.getProfit())); TreeSet<PathRoute> top = new TreeSet<>((p1, p2) -> Double.compare(p2.getProfit()/p2.getLandsCount(), p1.getProfit()/p1.getLandsCount()));
for (Vendor vendor : market.get()) { for (Vendor vendor : market.get()) {
Collection<PathRoute> paths = getPaths(vendor, vendor, balance); setSource(vendor);
for (PathRoute path : paths) { graph.setBalance(balance);
top.add(path); Collection<Path<Vendor>> paths = graph.getPathsTo(vendor, 10);
for (Path<Vendor> path : paths) {
top.add((PathRoute) path);
if (top.size() > limit) { if (top.size() > limit) {
top.pollLast(); top.pollLast();
} }
@@ -167,12 +188,10 @@ public class MarketAnalyzer {
this.graph = null; this.graph = null;
} }
public void setCargo(long cargo) { public void setCargo(int cargo) {
if (graph != null) graph.setLimit(cargo);
this.cargo = cargo; this.cargo = cargo;
} }
public long getCargo() {
return cargo;
}
} }

View File

@@ -82,6 +82,10 @@ public class Order implements Comparable<Order> {
} }
public boolean equalsIgnoreCount(Order order) {
return buy.equals(order.buy) && sell.equals(order.sell);
}
@Override @Override
public int hashCode() { public int hashCode() {
int result; int result;

View File

@@ -97,29 +97,32 @@ public class Graph<T extends Connectable<T>> {
return vertexes.get(entry); return vertexes.get(entry);
} }
public Collection<Path<T>> getPathsTo(T entry, boolean all){ public Collection<Path<T>> getPathsTo(T entry){
return getPathsTo(entry, 200);
}
public Collection<Path<T>> getPathsTo(T entry, int max){
Vertex<T> target = getVertex(entry); Vertex<T> target = getVertex(entry);
return findPaths(pathFabric.build(root), target, root.getLevel()-1, stock, all); ArrayList<Path<T>> paths = new ArrayList<>(max);
findPaths(paths, max, pathFabric.build(root), target, root.getLevel()-1, stock);
return paths;
} }
private Collection<Path<T>> findPaths(Path<T> head, Vertex<T> target, int deep, double limit, boolean all){ private boolean findPaths(ArrayList<Path<T>> paths, int max, Path<T> head, Vertex<T> target, int deep, double limit){
Collection<Path<T>> paths = new ArrayList<>(); if (target == null) return true;
if (target == null) return paths;
boolean found =false;
Vertex<T> source = head.getTarget(); Vertex<T> source = head.getTarget();
LOG.trace("Find path to deep from {} to {}, deep {}, limit {}, head {}", source, target, deep, limit, head); LOG.trace("Find path to deep from {} to {}, deep {}, limit {}, head {}", source, target, deep, limit, head);
Edge<T> edge = source.getEdge(target); Edge<T> edge = source.getEdge(target);
if (edge != null ){ if (edge != null ){
if (!(withRefill && Math.min(limit, maxDistance) < edge.getLength() && !source.getEntry().canRefill())){ if (!(withRefill && Math.min(limit, maxDistance) < edge.getLength() && !source.getEntry().canRefill())){
found = true;
Path<T> path = head.connectTo(edge.getTarget(), limit < edge.getLength()); Path<T> path = head.connectTo(edge.getTarget(), limit < edge.getLength());
path.finish(); path.finish();
LOG.trace("Last edge find, add path {}", path); LOG.trace("Last edge find, add path {}", path);
paths.add(path); if (onFindPath(paths, max, path)) return true;
} }
} }
if ((all || !found) && deep > 0 ){ if (deep > 0 ){
if (source.getEdgesCount() > 0){ if (source.getEdgesCount() > 0){
LOG.trace("Search around"); LOG.trace("Search around");
for (Edge<T> next : source.getEdges()) { for (Edge<T> next : source.getEdges()) {
@@ -131,12 +134,17 @@ public class Graph<T extends Connectable<T>> {
double nextLimit = withRefill ? limit - next.getLength(): stock; double nextLimit = withRefill ? limit - next.getLength(): stock;
// refill // refill
if (nextLimit < 0 ) nextLimit = maxDistance - next.getLength(); if (nextLimit < 0 ) nextLimit = maxDistance - next.getLength();
paths.addAll(findPaths(path, target, deep - 1, nextLimit, all)); if (findPaths(paths, max, path, target, deep - 1, nextLimit)) return true;
if (!all && !paths.isEmpty()) break;
} }
} }
} }
return paths; return false;
}
// if is true, then break search
protected boolean onFindPath(ArrayList<Path<T>> paths, int max, Path<T> path){
paths.add(path);
return paths.size() >= max;
} }

View File

@@ -94,6 +94,10 @@ public class Path<T extends Connectable<T>> {
return refill; return refill;
} }
public void setRefill(boolean refill) {
this.refill = refill;
}
protected Path<T> getPrevious(){ protected Path<T> getPrevious(){
return head; return head;
} }

View File

@@ -12,34 +12,21 @@ public class PathRoute extends Path<Vendor> {
private final static Logger LOG = LoggerFactory.getLogger(PathRoute.class); private final static Logger LOG = LoggerFactory.getLogger(PathRoute.class);
private final ArrayList<Order> orders = new ArrayList<>(); private final ArrayList<Order> orders = new ArrayList<>();
private final boolean expand;
private final int index;
private double profit = 0; private double profit = 0;
private double balance = 0; private double balance = 0;
private PathRoute tail; private PathRoute tail;
private int ordersCount = 0;
public final static Order TRANSIT = null; public final static Order TRANSIT = null;
public PathRoute(Vertex<Vendor> source, boolean expand) {
super(source);
this.expand = expand;
index = 0;
}
public PathRoute(Vertex<Vendor> source) { public PathRoute(Vertex<Vendor> source) {
super(source); super(source);
expand = false;
index = 0;
} }
private PathRoute(PathRoute head, Vertex<Vendor> vertex, boolean refill) { private PathRoute(PathRoute head, Vertex<Vendor> vertex, boolean refill) {
super(head, vertex, refill); super(head, vertex, refill);
assert head.tail == null; assert head.tail == null;
head.tail = this; head.tail = this;
expand = head.expand;
//transit //transit
orders.add(ordersCount++, TRANSIT); orders.add(TRANSIT);
index = head.index+1;
} }
@Override @Override
@@ -48,56 +35,53 @@ public class PathRoute extends Path<Vendor> {
return new PathRoute(this.getCopy(), vertex, refill); return new PathRoute(this.getCopy(), vertex, refill);
} }
public void add(PathRoute path, boolean withOrders) {
LOG.trace("Add path {} to {}", path, this);
PathRoute res = this;
path = path.getRoot();
if (!path.getTarget().equals(getTarget())){
res = new PathRoute(res, path.getTarget(), true);
}
while (path.hasNext()){
path = path.getNext();
res = new PathRoute(res, path.getTarget(), res == this || path.isRefill());
if (withOrders){
res.orders.clear();
res.orders.addAll(path.getOrders());
}
}
if (withOrders){
update();
} else {
res.finish();
}
}
public PathRoute getCopy(){ public PathRoute getCopy(){
return getCopy(false);
}
public PathRoute getCopy(boolean withOrders){
PathRoute path = getRoot(); PathRoute path = getRoot();
PathRoute res = new PathRoute(path.getTarget()); PathRoute res = new PathRoute(path.getTarget());
if (withOrders) {
res.orders.clear();
res.orders.addAll(path.getOrders());
}
while (path.hasNext()){ while (path.hasNext()){
path = path.getNext(); path = path.getNext();
res = new PathRoute(res, path.getTarget(), path.isRefill()); res = new PathRoute(res, path.getTarget(), path.isRefill());
if (withOrders) {
res.orders.clear();
res.orders.addAll(path.getOrders());
}
} }
return res; return res;
} }
private void addOrder(Order order){ private void addOrder(Order order){
LOG.trace("Add order {} to path {}", order, this); LOG.trace("Add order {} to path {}", order, this);
orders.add(ordersCount++, order); orders.add(order);
if (expand) expand(order);
}
private void expand(Order order){
LOG.trace("Expand orders");
if (hasNext()){
PathRoute next = getNext();
LOG.trace("Add {} clone of order", next.ordersCount - 1);
for (int i = 1; i < next.ordersCount; i++) {
orders.add(ordersCount++, new Order(order.getSell(), order.getBuy()));
addTransitsToHead();
}
cloneTailOrders(next.ordersCount);
}
addTransitsToHead();
}
private void addTransitsToHead(){
PathRoute p = getPrevious();
while (!p.isRoot()) {
LOG.trace("Add transit order to path {}", p);
p.orders.add(p.ordersCount++, TRANSIT);
p = p.getPrevious();
}
}
private void cloneTailOrders(int count){
if (hasNext()) {
PathRoute p = getNext();
LOG.trace("Duplicate {} orders of path {}", count, p);
for (int i = 0; i < count; i++) {
Order o = p.orders.get(i);
if (o == TRANSIT) p.orders.add(TRANSIT);
else p.orders.add(new Order(o.getSell(), o.getBuy()));
}
p.cloneTailOrders(count);
}
} }
@Override @Override
@@ -109,6 +93,8 @@ public class PathRoute extends Path<Vendor> {
} }
private void fillOrders(){ private void fillOrders(){
orders.clear();
orders.add(TRANSIT);
LOG.trace("Fill orders of path {}", this); LOG.trace("Fill orders of path {}", this);
Vendor seller = getPrevious().get(); Vendor seller = getPrevious().get();
for (Offer sell : seller.getAllSellOffers()) { for (Offer sell : seller.getAllSellOffers()) {
@@ -126,7 +112,7 @@ public class PathRoute extends Path<Vendor> {
} }
public boolean isEmpty(){ public boolean isEmpty(){
return ordersCount <= 1; return orders.size() <= 1;
} }
@Override @Override
@@ -142,6 +128,19 @@ public class PathRoute extends Path<Vendor> {
return tail != null; return tail != null;
} }
public void update(){
PathRoute p = this;
p.updateBalance();
while (p.hasNext()){
p = p.getNext();
p.updateBalance();
}
while (p != this){
p.updateProfit();
p = p.getPrevious();
}
}
public void sort(double balance, long limit){ public void sort(double balance, long limit){
// start on root only // start on root only
if (isRoot()){ if (isRoot()){
@@ -250,27 +249,17 @@ public class PathRoute extends Path<Vendor> {
return Double.compare(profit2, profit1); return Double.compare(profit2, profit1);
} }
public PathRoute getPath(int index){
if (this.index == index) return this;
if (this.index > index){
return isRoot() ? null : getPrevious().getPath(index);
} else {
return hasNext() ? getNext().getPath(index) : null;
}
}
@Override @Override
public PathRoute getRoot() { public PathRoute getRoot() {
return (PathRoute) super.getRoot(); return (PathRoute) super.getRoot();
} }
public Order getBest(){ public PathRoute getEnd() {
return orders.get(0); return hasNext()? getNext().getEnd() : this;
} }
public double getMaxProfit(){ public Order getBest(){
Order o = orders.get(0); return orders.get(0);
return o != TRANSIT ? o.getProfit() : 0;
} }
public double getDistance(){ public double getDistance(){
@@ -280,9 +269,7 @@ public class PathRoute extends Path<Vendor> {
@Override @Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
int step = !hasNext() || tail.ordersCount == 0 ? 1 : tail.ordersCount; for (Order order : orders) {
for (int i = 0; i < ordersCount; i += step) {
Order order = orders.get(i);
if (order == TRANSIT) continue; if (order == TRANSIT) continue;
if (sb.length() > 0) sb.append(", "); if (sb.length() > 0) sb.append(", ");
sb.append(order.getBuy().getItem()); sb.append(order.getBuy().getItem());
@@ -302,4 +289,49 @@ public class PathRoute extends Path<Vendor> {
return sb.toString(); return sb.toString();
} }
public void setOrder(Order order) {
orders.set(0, order);
}
public int getLandsCount(){
int res = 0;
PathRoute p = this.isRoot() ? getNext() : this;
Order o = p.getBest();
while (p.hasNext()){
p = p.getNext();
// lands for sell
if (o != null && p.isPathFrom(o.getBuyer())){
LOG.trace("{} is lands for sell by order {}", p, o);
o = p.getBest();
res++;
} else {
if (o == null){
o = p.getBest();
if (o!= null){
LOG.trace("{} is lands for by by order {}", p, o);
res++;
}
} else {
if (p.isRefill()){
LOG.trace("{} is lands for refill", p);
res++;
}
}
}
}
LOG.trace("{} is end, landing", p);
res++;
return res;
}
public PathRoute dropTo(Vendor vendor){
PathRoute p = getCopy(true).getEnd();
while (!p.isRoot() && !p.get().equals(vendor)){
p = p.getPrevious();
}
p.tail = null;
return p;
}
} }

View File

@@ -0,0 +1,55 @@
package ru.trader.graph;
import ru.trader.core.Vendor;
import java.util.*;
public class RouteGraph extends Graph<Vendor> {
private double balance;
private int limit;
private Comparator<Path<Vendor>> comparator = (p1, p2) -> {
PathRoute r1 = (PathRoute) p1.getRoot();
PathRoute r2 = (PathRoute) p2.getRoot();
return Double.compare(r2.getProfit()/r2.getLandsCount(), r1.getProfit()/r1.getLandsCount());
};
public RouteGraph(Vendor start, Collection<Vendor> set, double stock, double maxDistance, boolean withRefill, int maxDeep) {
super(start, set, stock, maxDistance, withRefill, maxDeep, PathRoute::new);
}
public void setBalance(double balance) {
this.balance = balance;
}
public void setLimit(int limit) {
this.limit = limit;
}
@Override
protected boolean onFindPath(ArrayList<Path<Vendor>> paths, int max, Path<Vendor> path) {
PathRoute route = (PathRoute) path;
route.sort(balance, limit);
if (paths.size() == max){
int index = Collections.binarySearch(paths, route, comparator);
if (index == -1) return false;
if (index < -1) index = -1 - index;
paths.add(index, path);
paths.remove(max);
} else {
if (paths.size() < max-1){
paths.add(route);
} else {
paths.add(route);
paths.sort(comparator);
}
}
return false;
}
}

View File

@@ -208,13 +208,13 @@ public class GraphTest extends Assert {
Graph<Point> graph = new Graph<>(x5, entrys, 5.1, 2); Graph<Point> graph = new Graph<>(x5, entrys, 5.1, 2);
// x5 <-> x4, x5 <-> x6 // x5 <-> x4, x5 <-> x6
Collection<Path<Point>> paths = graph.getPathsTo(x4, true); Collection<Path<Point>> paths = graph.getPathsTo(x4);
TestUtil.assertCollectionEquals(paths, Path.toPath(x5, x4)); TestUtil.assertCollectionEquals(paths, Path.toPath(x5, x4));
paths = graph.getPathsTo(x6, true); paths = graph.getPathsTo(x6);
TestUtil.assertCollectionEquals(paths, Path.toPath(x5, x6)); TestUtil.assertCollectionEquals(paths, Path.toPath(x5, x6));
paths = graph.getPathsTo(x7, true); paths = graph.getPathsTo(x7);
assertEquals(paths.size(), 0); assertEquals(paths.size(), 0);
} }
@@ -226,21 +226,21 @@ public class GraphTest extends Assert {
// x5 <-> x4 <-> x3 <-> x2, x5 <-> x6 <-> x7 <-> x8 // x5 <-> x4 <-> x3 <-> x2, x5 <-> x6 <-> x7 <-> x8
// x5 <-> x3, x4 <-> x2, x3 <-> x6, x4 <-> x6 // x5 <-> x3, x4 <-> x2, x3 <-> x6, x4 <-> x6
Collection<Path<Point>> paths = graph.getPathsTo(x8, true); Collection<Path<Point>> paths = graph.getPathsTo(x8);
TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x6, x7, x8)); TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x6, x7, x8));
paths = graph.getPathsTo(x7, true); paths = graph.getPathsTo(x7);
TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x6, x7), Path.toPath(x5, x4, x6, x7), Path.toPath(x5, x3, x6, x7)); TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x6, x7), Path.toPath(x5, x4, x6, x7), Path.toPath(x5, x3, x6, x7));
paths = graph.getPathsTo(x7, false); paths = graph.getPathsTo(x7, 1);
TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x3, x6, x7)); TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x3, x6, x7));
paths = graph.getPathsTo(x4, true); paths = graph.getPathsTo(x4);
TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x4), Path.toPath(x5, x6, x4), Path.toPath(x5, x3, x4), TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x4), Path.toPath(x5, x6, x4), Path.toPath(x5, x3, x4),
Path.toPath(x5, x6, x3, x4), Path.toPath(x5, x3, x2, x4), Path.toPath(x5, x3, x6, x4)); Path.toPath(x5, x6, x3, x4), Path.toPath(x5, x3, x2, x4), Path.toPath(x5, x3, x6, x4));
paths = graph.getPathsTo(x5, true); paths = graph.getPathsTo(x5);
TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x4, x5), Path.toPath(x5, x4, x6, x5), Path.toPath(x5, x4, x3, x5), TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x4, x5), Path.toPath(x5, x4, x6, x5), Path.toPath(x5, x4, x3, x5),
Path.toPath(x5, x6, x5), Path.toPath(x5, x6, x4, x5), Path.toPath(x5, x6, x3, x5), Path.toPath(x5, x3, x5), Path.toPath(x5, x6, x5), Path.toPath(x5, x6, x4, x5), Path.toPath(x5, x6, x3, x5), Path.toPath(x5, x3, x5),
Path.toPath(x5, x3, x4, x5), Path.toPath(x5, x3, x6, x5)); Path.toPath(x5, x3, x4, x5), Path.toPath(x5, x3, x6, x5));
@@ -264,13 +264,13 @@ public class GraphTest extends Assert {
// x5 <-> x4 <- refill -> x3 <- refill -> x2, x5 <-> x6 // x5 <-> x4 <- refill -> x3 <- refill -> x2, x5 <-> x6
// x5 <-> x3 <- refill -> x2, x5 <-> x4 <- refill -> x6 // x5 <-> x3 <- refill -> x2, x5 <-> x4 <- refill -> x6
Collection<Path<Point>> paths = graph.getPathsTo(x1, true); Collection<Path<Point>> paths = graph.getPathsTo(x1);
assertTrue(paths.isEmpty()); assertTrue(paths.isEmpty());
paths = graph.getPathsTo(x2, true); paths = graph.getPathsTo(x2);
TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x4, x3, x2), Path.toPath(x5, x3, x2)); TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x4, x3, x2), Path.toPath(x5, x3, x2));
paths = graph.getPathsTo(x6, true); paths = graph.getPathsTo(x6);
TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x6), Path.toPath(x5, x4, x6), Path.toPath(x5, x3, x4, x6)); TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x6), Path.toPath(x5, x4, x6), Path.toPath(x5, x3, x4, x6));
Path<Point> fast = graph.getFastPathTo(x2); Path<Point> fast = graph.getFastPathTo(x2);
@@ -287,19 +287,19 @@ public class GraphTest extends Assert {
// x5 <-> x3 <- refill -> x2 // x5 <-> x3 <- refill -> x2
// x5 <-> x4 <- refill -> x6 // x5 <-> x4 <- refill -> x6
Collection<Path<Point>> paths = graph.getPathsTo(x1, true); Collection<Path<Point>> paths = graph.getPathsTo(x1);
assertTrue(paths.isEmpty()); assertTrue(paths.isEmpty());
paths = graph.getPathsTo(x2, true); paths = graph.getPathsTo(x2);
TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x3, x4, x2), Path.toPath(x5, x3, x2), TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x3, x4, x2), Path.toPath(x5, x3, x2),
Path.toPath(x5, x4, x3, x2), Path.toPath(x5, x4, x2), Path.toPath(x5, x4, x3, x2), Path.toPath(x5, x4, x2),
Path.toPath(x5, x6, x4, x2), Path.toPath(x5, x6, x4, x3, x2)); Path.toPath(x5, x6, x4, x2), Path.toPath(x5, x6, x4, x3, x2));
paths = graph.getPathsTo(x6, true); paths = graph.getPathsTo(x6);
TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x6), Path.toPath(x5, x4, x6), TestUtil.assertCollectionContainAll(paths, Path.toPath(x5, x6), Path.toPath(x5, x4, x6),
Path.toPath(x5, x3, x4, x6), Path.toPath(x5, x3, x6), Path.toPath(x5, x4, x3, x6)); Path.toPath(x5, x3, x4, x6), Path.toPath(x5, x3, x6), Path.toPath(x5, x4, x3, x6));
paths = graph.getPathsTo(x7, true); paths = graph.getPathsTo(x7);
assertTrue(paths.isEmpty()); assertTrue(paths.isEmpty());
Path<Point> fast = graph.getFastPathTo(x2); Path<Point> fast = graph.getFastPathTo(x2);

View File

@@ -45,7 +45,9 @@ public class PathRouteTest extends Assert {
public void testPathRoute1() throws Exception { public void testPathRoute1() throws Exception {
LOG.info("Start path route test 1"); LOG.info("Start path route test 1");
PathRoute path = initTest1(); PathRoute path = initTest1();
assertEquals(1000, path.getProfit(), 0.0001); assertEquals(1000, path.getProfit(), 0.0001);
assertEquals(1, path.getLandsCount());
path = path.getNext(); path = path.getNext();
Collection<Order> orders = path.getOrders(); Collection<Order> orders = path.getOrders();
@@ -85,6 +87,7 @@ public class PathRouteTest extends Assert {
LOG.info("Start path route test 2"); LOG.info("Start path route test 2");
PathRoute path = initTest2(); PathRoute path = initTest2();
assertEquals(1000, path.getProfit(), 0.0001); assertEquals(1000, path.getProfit(), 0.0001);
assertEquals(1, path.getLandsCount());
path = path.getNext(); path = path.getNext();
Collection<Order> orders = path.getOrders(); Collection<Order> orders = path.getOrders();
@@ -137,6 +140,7 @@ public class PathRouteTest extends Assert {
LOG.info("Start path route test 3"); LOG.info("Start path route test 3");
PathRoute path = initTest3(); PathRoute path = initTest3();
assertEquals(800, path.getProfit(), 0.0001); assertEquals(800, path.getProfit(), 0.0001);
assertEquals(2, path.getLandsCount());
path = path.getNext(); path = path.getNext();
Collection<Order> orders = path.getOrders(); Collection<Order> orders = path.getOrders();
@@ -201,6 +205,7 @@ public class PathRouteTest extends Assert {
LOG.info("Start path route test 4"); LOG.info("Start path route test 4");
PathRoute path = initTest4(); PathRoute path = initTest4();
assertEquals(1000, path.getProfit(), 0.0001); assertEquals(1000, path.getProfit(), 0.0001);
assertEquals(3, path.getLandsCount());
path = path.getNext(); path = path.getNext();
Collection<Order> orders = path.getOrders(); Collection<Order> orders = path.getOrders();
@@ -266,11 +271,13 @@ public class PathRouteTest extends Assert {
return res.getRoot(); return res.getRoot();
} }
@Test @Test
public void testPathRoute5() throws Exception { public void testPathRoute5() throws Exception {
LOG.info("Start path route test 5"); LOG.info("Start path route test 5");
PathRoute path = initTest5(); PathRoute path = initTest5();
assertEquals(620, path.getProfit(), 0.0001); assertEquals(620, path.getProfit(), 0.0001);
assertEquals(2, path.getLandsCount());
path = path.getNext(); path = path.getNext();
Collection<Order> orders = path.getOrders(); Collection<Order> orders = path.getOrders();
@@ -302,5 +309,86 @@ public class PathRouteTest extends Assert {
} }
private PathRoute initTest6A(){
LOG.info("Init test 6A");
v1 = new SimpleVendor("v1");
v2 = new SimpleVendor("v2");
v1.add(new Offer(OFFER_TYPE.SELL, ITEM1, 100));
v1.add(new Offer(OFFER_TYPE.SELL, ITEM2, 200));
v1.add(new Offer(OFFER_TYPE.SELL, ITEM3, 300));
v2.add(new Offer(OFFER_TYPE.SELL, ITEM1, 150));
v2.add(new Offer(OFFER_TYPE.SELL, ITEM3, 320));
v2.add(new Offer(OFFER_TYPE.BUY, ITEM2, 225));
PathRoute res = new PathRoute(new Vertex<>(v1));
res = (PathRoute) res.connectTo(new Vertex<>(v2), false);
res.finish();
res.sort(500, 5);
return res.getRoot();
}
private PathRoute initTest6B(){
LOG.info("Init test 6B");
v3 = new SimpleVendor("v3");
v4 = new SimpleVendor("v4");
v3.add(new Offer(OFFER_TYPE.SELL, ITEM3, 390));
v3.add(new Offer(OFFER_TYPE.BUY, ITEM1, 200));
v4.add(new Offer(OFFER_TYPE.BUY, ITEM3, 450));
PathRoute res = new PathRoute(new Vertex<>(v2));
res = (PathRoute) res.connectTo(new Vertex<>(v3), false);
res = (PathRoute) res.connectTo(new Vertex<>(v4), false);
res.finish();
res.sort(500, 5);
return res.getRoot();
}
@Test
public void testAddPathRoute() throws Exception {
LOG.info("Start add path route test");
PathRoute path = initTest6A();
PathRoute pathB = initTest6B();
path.getEnd().add(pathB, false);
path.sort(500, 5);
path = path.getRoot();
assertEquals(620, path.getProfit(), 0.0001);
assertEquals(2, path.getLandsCount());
path = path.getNext();
Collection<Order> orders = path.getOrders();
Order order1 = new Order(v1.getSell(ITEM1), v3.getBuy(ITEM1), 5);
Order order2 = new Order(v1.getSell(ITEM2), v2.getBuy(ITEM2), 2);
Order order3 = new Order(v1.getSell(ITEM3), v4.getBuy(ITEM3), 1);
Order order4 = new Order(v2.getSell(ITEM1), v3.getBuy(ITEM1), 3);
Order order5 = new Order(v2.getSell(ITEM3), v4.getBuy(ITEM3), 1);
Order order7 = new Order(v3.getSell(ITEM3), v4.getBuy(ITEM3), 2);
assertEquals(500, path.getBalance(), 0.0001);
assertEquals(620, path.getProfit(), 0.0001);
TestUtil.assertCollectionEquals(orders, order1, order2, PathRoute.TRANSIT, order3);
path = path.getNext();
orders = path.getOrders();
assertEquals(550, path.getBalance(), 0.0001);
assertEquals(270, path.getProfit(), 0.0001);
TestUtil.assertCollectionEquals(orders, order4, order5, PathRoute.TRANSIT);
path = path.getNext();
orders = path.getOrders();
assertEquals(1000, path.getBalance(), 0.0001);
assertEquals(120, path.getProfit(), 0.0001);
TestUtil.assertCollectionEquals(orders, order7, PathRoute.TRANSIT);
}
} }