- fix lands count
- fix memory leak on big jumps count - fix remove order from route - add path adding
This commit is contained in:
@@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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){
|
||||||
path.setContent(new RouteNode(route).getNode());
|
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());
|
||||||
|
else
|
||||||
|
path.setContent(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
55
core/src/main/java/ru/trader/graph/RouteGraph.java
Normal file
55
core/src/main/java/ru/trader/graph/RouteGraph.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user