._.
This commit is contained in:
parent
a5d5460203
commit
c8338ba142
@ -4,12 +4,12 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.entities.city import CityEntity
|
||||
from app.infrastructure.database.models.cities import City
|
||||
from app.infrastructure.database.repository.city_repository import CitiesRepository
|
||||
from app.infrastructure.database.repository.city_repository import CityRepository
|
||||
|
||||
|
||||
class CitiesService:
|
||||
def __init__(self, db: Session):
|
||||
self.repository = CitiesRepository(db)
|
||||
self.repository = CityRepository(db)
|
||||
|
||||
def get_all_cities(self) -> List[CityEntity]:
|
||||
cities = self.repository.get_all_with_federal_district()
|
||||
|
||||
112
app/core/usecases/new_total_order_service.py
Normal file
112
app/core/usecases/new_total_order_service.py
Normal file
@ -0,0 +1,112 @@
|
||||
from itertools import permutations
|
||||
from math import ceil
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.infrastructure.database.repository.accessory_repository import AccessoriesRepository
|
||||
from app.infrastructure.database.repository.city_repository import CityRepository
|
||||
from app.infrastructure.database.repository.delivery_accessory_repository import DeliveryAccessoriesRepository
|
||||
from app.infrastructure.database.repository.delivery_order_repository import DeliveryOrdersRepository
|
||||
from app.infrastructure.database.repository.total_order_repository import TotalOrdersRepository
|
||||
|
||||
|
||||
class NewTotalOrderService:
|
||||
def __init__(self, db: Session):
|
||||
self.total_order_repository = TotalOrdersRepository(db)
|
||||
self.delivery_order_repository = DeliveryOrdersRepository(db)
|
||||
self.delivery_accessory_repository = DeliveryAccessoriesRepository(db)
|
||||
self.city_repository = CityRepository(db)
|
||||
self.accessory_repository = AccessoriesRepository(db)
|
||||
|
||||
def total_calculate(self):
|
||||
grouped_by_period = self.group_accessories_by_period(accessories)
|
||||
routes_by_period = self.find_routes_by_period(grouped_by_period, distances, cities)
|
||||
|
||||
for period, routes in routes_by_period.items():
|
||||
for route in routes:
|
||||
vehicle_count, selected_track = self.calculate_vehicle_requirements(
|
||||
[a for a in accessories if a.period == period], tracks)
|
||||
cost = self.calculate_route_cost(route, accessories, distances)
|
||||
|
||||
print(f"Период: {period}")
|
||||
print(f"Маршрут: {' -> '.join([city.name for city in route])}")
|
||||
selected_vehicle_name = next((track.name for track in tracks if track.id == selected_track),
|
||||
"Нет доступного автомобиля")
|
||||
print(f"Тип автомобиля: {selected_vehicle_name}")
|
||||
print(f"Количество автомобилей: {vehicle_count}")
|
||||
print(f"Стоимость перевозки: {cost}\n")
|
||||
|
||||
def find_routes_by_period(self, grouped_by_period, distances, cities):
|
||||
routes_by_period = {}
|
||||
|
||||
for period, accessories in grouped_by_period.items():
|
||||
cities_in_period = [next(city for city in cities if city.id == accessory.cityId) for accessory in
|
||||
accessories]
|
||||
all_routes = self.generate_routes(cities_in_period, next(city for city in cities if city.id == 9))
|
||||
|
||||
routes_with_details = []
|
||||
for route in all_routes:
|
||||
distance = self.calculate_route_distance(route, distances)
|
||||
total_weight = sum(
|
||||
sum(accessory.weight for accessory in accessories if accessory.cityId == city.id) for city in route)
|
||||
cost = self.calculate_route_cost(route, accessories, distances)
|
||||
routes_with_details.append((route, (distance, total_weight, cost)))
|
||||
|
||||
sorted_routes = sorted(routes_with_details, key=lambda x: (x[1][2], x[1][0]))
|
||||
routes_by_period[period] = [sorted_routes[0][0]]
|
||||
|
||||
return routes_by_period
|
||||
|
||||
@staticmethod
|
||||
def group_accessories_by_period(accessories):
|
||||
grouped = {}
|
||||
for accessory in accessories:
|
||||
if accessory.period not in grouped:
|
||||
grouped[accessory.period] = []
|
||||
grouped[accessory.period].append(accessory)
|
||||
return grouped
|
||||
|
||||
@staticmethod
|
||||
def generate_routes(cities, start_city):
|
||||
routes = []
|
||||
cities_without_start = [city for city in cities if city.id != start_city.id]
|
||||
all_routes = list(permutations(cities_without_start))
|
||||
|
||||
for route in all_routes:
|
||||
routes.append([start_city] + list(route) + [start_city])
|
||||
|
||||
return routes
|
||||
|
||||
@staticmethod
|
||||
def calculate_route_distance(route, distances):
|
||||
total_distance = 0
|
||||
for i in range(len(route) - 1):
|
||||
total_distance += distances[route[i].id - 1][route[i + 1].id - 1]
|
||||
return total_distance
|
||||
|
||||
@staticmethod
|
||||
def calculate_route_cost(route, accessories, distances):
|
||||
total_weight = 0.0
|
||||
total_cost = 0.0
|
||||
|
||||
for i in range(len(route) - 1):
|
||||
if route[i].id != 9:
|
||||
city_accessories = [accessory for accessory in accessories if accessory.cityId == route[i].id]
|
||||
total_weight += sum(accessory.weight for accessory in city_accessories) * 20.0
|
||||
total_cost += distances[route[i].id - 1][route[i + 1].id - 1] * (total_weight / 1000.0) * 8
|
||||
|
||||
return total_cost
|
||||
|
||||
@staticmethod
|
||||
def calculate_vehicle_requirements(accessories, tracks):
|
||||
total_weight = sum(accessory.weight for accessory in accessories) * 20
|
||||
total_vehicles = float('inf')
|
||||
selected_track = 0
|
||||
|
||||
for track in tracks:
|
||||
weight_vehicles = ceil(total_weight / track.weight)
|
||||
if weight_vehicles < total_vehicles:
|
||||
total_vehicles = weight_vehicles
|
||||
selected_track = track.id
|
||||
|
||||
return total_vehicles, selected_track
|
||||
@ -2,7 +2,7 @@ from sqlalchemy.orm import Session, joinedload
|
||||
from app.infrastructure.database.models.cities import City
|
||||
|
||||
|
||||
class CitiesRepository:
|
||||
class CityRepository:
|
||||
def __init__(self, db: Session):
|
||||
self.db = db
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user