ads2_2022/code/python/src/models/random_walk/landscape.py

91 lines
3.0 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from __future__ import annotations;
from src.thirdparty.maths import *;
from src.thirdparty.misc import *;
from src.thirdparty.types import *;
from models.generated.commands import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'Landscape',
];
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# METHOD fitness function -> Array
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class Landscape():
_fct: np.ndarray;
_metric: EnumLandscapeMetric;
_radius: float;
def __init__(
self,
values: DataTypeLandscapeValues,
metric: EnumLandscapeMetric = EnumLandscapeMetric.maximum,
):
self._fct = convert_to_nparray(values);
self._metric = metric;
return;
@property
def shape(self) -> tuple:
return self._fct.shape;
@property
def dim(self) -> int:
return len(self._fct.shape);
def fitness(self, *x: int) -> float:
return self._fct[x];
def neighbourhood(self, *x: int, r: float, strict: bool = False) -> List[tuple]:
sides = [
[ xx - j for j in range(1,r+1) if xx - j in range(s) ]
+ ([ xx ] if xx in range(s) else [])
+ [ xx + j for j in range(1,r+1) if xx + j in range(s) ]
for xx, s in zip(x, self.shape)
];
match self._metric:
case EnumLandscapeMetric.maximum:
umg = list(itertools_product(*sides));
case EnumLandscapeMetric.manhattan:
umg = [
(*x[:i], xx, *x[(i+1):])
for i, side in enumerate(sides)
for xx in side
];
case _:
umg = [ x ];
if strict:
umg = [ p for p in umg if p != x ];
return umg;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# AUXILIARY METHODS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def convert_to_array(values: DataTypeLandscapeValues) -> list:
return [
x if isinstance(x, float) else convert_to_array(x)
for x in values.__root__
];
def convert_to_nparray(values: DataTypeLandscapeValues) -> np.ndarray:
try:
list_of_lists = convert_to_array(values);
return np.asarray(list_of_lists, dtype=float);
except:
raise ValueError('Could not convert to a d-dimensional array! Ensure that the dimensions are consistent.');