Skip to content
This repository has been archived by the owner on May 10, 2023. It is now read-only.

Issue 41 #42

Merged
merged 10 commits into from
Aug 31, 2019
8 changes: 8 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
coverage:
status:
project:
default:
threshold: 1
patch:
default:
threshold: 1
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ install:
- 'pip install pipenv'
- 'pipenv sync'
script:
- 'pipenv run coverage run --source=jinete --module unittest discover tests'
- 'pipenv run flake8'
- 'pipenv run mypy'
- 'pipenv run coverage run -m unittest discover tests'
after_success:
- 'pipenv run codecov'

Expand Down
86 changes: 86 additions & 0 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 11 additions & 2 deletions jinete/algorithms/metaheuristics/grasp.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
if TYPE_CHECKING:
from typing import (
Type,
Optional,
)
from ...models import (
Result,
)

logger = logging.getLogger(__name__)
Expand All @@ -37,15 +41,20 @@ def __init__(self, episodes: int = 100, algorithm_cls: Type[Algorithm] = None, s
self.kwargs = kwargs

def build_algorithm(self, *args, **kwargs) -> Algorithm:
return self.algorithm_cls(*self.args, *args, **self.kwargs, **kwargs)
args = (*self.args, *args)
kwargs.update(self.kwargs)
return self.algorithm_cls(*args, **kwargs)

def _optimize(self) -> Planning:
logger.info('Optimizing...')

best = None
best: Optional[Result] = None
for i in range(self.episodes):
seed = self.random.randint(0, MAX_INT)
current = self.build_algorithm(seed=seed).optimize()
best = self.objective.best(best, current)

assert isinstance(best, Result)

logger.info('Optimized!')
return best.planning
14 changes: 13 additions & 1 deletion jinete/algorithms/naive.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
from __future__ import annotations

from typing import TYPE_CHECKING

from ..models import (
Planning,
)
from .abc import (
Algorithm,
)

if TYPE_CHECKING:
from typing import (
Set,
)
from ..models import (
Route
)


class NaiveAlgorithm(Algorithm):

def _optimize(self) -> Planning:
routes = set()
routes: Set[Route] = set()
return Planning(routes)
11 changes: 9 additions & 2 deletions jinete/algorithms/utils/crossers/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@


class Crosser(ABC):
fleet: Fleet
job: Job
criterion_cls: Type[PlannedTripCriterion]
_criterion: Optional[PlannedTripCriterion]

def __init__(self, fleet: Fleet, job: Job, criterion_cls: Type[PlannedTripCriterion] = None):
def __init__(self, fleet: Fleet, job: Job, criterion_cls: Type[PlannedTripCriterion] = None, *args, **kwargs):
if criterion_cls is None:
criterion_cls = ShortestTimePlannedTripCriterion

Expand All @@ -49,10 +53,13 @@ def __init__(self, fleet: Fleet, job: Job, criterion_cls: Type[PlannedTripCriter
self.criterion_cls = criterion_cls
self._criterion = None

self.args = args
self.kwargs = kwargs

@property
def criterion(self) -> PlannedTripCriterion:
if self._criterion is None:
self._criterion = self.criterion_cls()
self._criterion = self.criterion_cls(*self.args, **self.kwargs)
return self._criterion

@property
Expand Down
3 changes: 2 additions & 1 deletion jinete/algorithms/utils/crossers/randomized.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
if TYPE_CHECKING:
from typing import (
Optional,
List,
)
from ....models import (
PlannedTrip,
Expand All @@ -29,7 +30,7 @@ def get_planned_trip(self) -> Optional[PlannedTrip]:
if len(self.ranking) == 0:
return None

candidates = list()
candidates: List[PlannedTrip] = list()
for sub_ranking in self.ranking.values():
if len(sub_ranking) == 0:
continue
Expand Down
2 changes: 1 addition & 1 deletion jinete/dispatchers/static.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from time import time
from __future__ import annotations

from .abc import Dispatcher

Expand Down
18 changes: 16 additions & 2 deletions jinete/loaders/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
)
from typing import (
TYPE_CHECKING,
)
Any)
from ..models import (
Fleet,
Job,
Expand All @@ -18,19 +18,33 @@
if TYPE_CHECKING:
from typing import (
Type,
Optional,
)
from .formatters import (
LoaderFormatter,
)


class Loader(ABC):
formatter_cls: Type[LoaderFormatter]
_formatter: Optional[LoaderFormatter]

def __init__(self, formatter_cls: Type[LoaderFormatter] = None):
if formatter_cls is None:
formatter_cls = CordeauLaporteLoaderFormatter
self.formatter_cls = formatter_cls
self.formatter: LoaderFormatter = None
self._formatter = None

@property
def formatter(self) -> LoaderFormatter:
if self._formatter is None:
self._formatter = self.formatter_cls(self.data)
return self._formatter

@property
@abstractmethod
def data(self) -> Any:
pass

@property
@abstractmethod
Expand Down
19 changes: 10 additions & 9 deletions jinete/loaders/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from pathlib import (
Path,
)
from typing import TYPE_CHECKING

from ..models import (
Job,
Expand All @@ -14,10 +15,18 @@
Loader,
)

if TYPE_CHECKING:
from typing import (
Optional,
)

logger = logging.getLogger(__name__)


class FileLoader(Loader):
_fleet: Optional[Fleet]
_job: Optional[Job]
_surface: Optional[Surface]

def __init__(self, file_path: Path, *args, **kwargs):
super().__init__(*args, **kwargs)
Expand All @@ -31,34 +40,26 @@ def __init__(self, file_path: Path, *args, **kwargs):
self._job = None
self._surface = None

def _build_formatter(self, force: bool = True):
if self.formatter is not None and force is False:
return
self.formatter = self.formatter_cls(self.data)

@property
def data(self):
with self.file_path.open() as file:
data = tuple(tuple(float(v) for v in line.split()) for line in file.readlines())
data = list(list(float(v) for v in line.split()) for line in file.readlines())
return data

@property
def fleet(self) -> Fleet:
if self._fleet is None:
self._build_formatter()
self._fleet = self.formatter.fleet(surface=self.surface)
return self._fleet

@property
def job(self) -> Job:
if self._job is None:
self._build_formatter()
self._job = self.formatter.job(surface=self.surface)
return self._job

@property
def surface(self) -> Surface:
if self._surface is None:
self._build_formatter()
self._surface = self.formatter.surface()
return self._surface
4 changes: 2 additions & 2 deletions jinete/loaders/formatters/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ def __init__(self, data: Any):
self.data = data

@abstractmethod
def fleet(self, *args, **kwargs) -> Fleet:
def fleet(self, surface: Surface, *args, **kwargs) -> Fleet:
pass

@abstractmethod
def job(self, *args, **kwargs) -> Job:
def job(self, surface: Surface, *args, **kwargs) -> Job:
pass

@abstractmethod
Expand Down
12 changes: 7 additions & 5 deletions jinete/loaders/formatters/hashcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ def job(self, surface: Surface, *args, **kwargs) -> Job:
bonus = self.data[0][4]
rows = self.data[1:]
trips = set(self._build_trip(surface, str(i), bonus, *row) for i, row in enumerate(rows))
objective_cls = HashCodeObjective
job = Job(trips, objective_cls=objective_cls, *args, **kwargs)

kwargs['objective_cls'] = HashCodeObjective
job = Job(trips, *args, **kwargs)

logger.info(f'Created job!')
return job

Expand All @@ -48,9 +50,9 @@ def _build_trip(self, surface: Surface, identifier: str, bonus: float, x1: float
return trip

def surface(self, *args, **kwargs) -> Surface:
row = self.data[0]
rows = row[0]
columns = row[1]
# row = self.data[0]
# rows = row[0]
# columns = row[1]
surface = GeometricSurface(DistanceMetric.MANHATTAN)
logger.info(f'Created surface!')
return surface
Loading