예제 #1
0
    def _do(self):

        # initial a figure with a single plot
        self.init_figure()

        # if no normalization of each axis the bounds are based on the overall min and max
        if not self.normalize_each_axis and self.bounds is None:
            _F = np.row_stack([e[0] for e in self.to_plot])
            self.bounds = [_F.min(), _F.max()]

        # normalize the input
        bounds = parse_bounds(self.bounds, self.n_dim)
        to_plot_norm, bounds = normalize(self.to_plot,
                                         bounds,
                                         return_bounds=True)

        # plot for each set the lines
        for k, (F, kwargs) in enumerate(to_plot_norm):

            _kwargs = kwargs.copy()
            set_if_none(_kwargs, "color", self.colors[k])

            for i in range(len(F)):
                plt.plot(np.arange(F.shape[1]), F[i, :], **_kwargs)

        # Plot the parallel coordinate axes
        for i in range(self.n_dim):
            self.ax.axvline(i, **self.axis_style)

            bottom, top = -0.1, 1.075
            margin_left = 0.08

            if self.show_bounds:
                self.ax.text(i - margin_left, bottom,
                             self.func_number_to_text(bounds[0][i]))
                self.ax.text(i - margin_left, top,
                             self.func_number_to_text(bounds[1][i]))

            if self.n_ticks is not None:
                n_length = 0.03
                for y in np.linspace(0, 1, self.n_ticks):
                    self.ax.hlines(y, i - n_length, i + n_length,
                                   **self.axis_style)

        # if bounds are shown, then move them to the bottom
        if self.show_bounds:
            self.ax.tick_params(axis='x', which='major', pad=25)

        self.ax.spines['right'].set_visible(False)
        self.ax.spines['left'].set_visible(False)

        self.ax.set_yticklabels([])
        self.ax.set_yticks([])
        self.ax.set_ylim((-0.05, 1.05))

        self.ax.set_xticks(np.arange(self.n_dim))
        self.ax.set_xticklabels(self.get_labels())

        return self
예제 #2
0
    def __init__(self, bounds=None, **kwargs):
        """

        Petal Diagram


        Parameters
        ----------------
        bounds : tuple
            The boundaries for each objective. Necessary to be provided for this plot!
        axis_style : {axis_style}
        reverse : bool
            Default false. Otherwise, larger area means smaller value.

        Other Parameters
        ----------------

        figsize : {figsize}
        title : {title}
        legend : {legend}
        tight_layout : {tight_layout}
        cmap : {cmap}

        """

        super().__init__(bounds=bounds, **kwargs)

        if bounds is None:
            raise Exception(
                "Boundaries must be provided for Petal Width. Otherwise, no trade-offs can be calculated."
            )

        set_if_none(self.axis_style, "color", "black")
        set_if_none(self.axis_style, "linewidth", 2)
        set_if_none(self.axis_style, "alpha", 0.5)
예제 #3
0
    def __init__(self,
                 ref_dirs,
                 n_neighbors=20,
                 decomposition='auto',
                 prob_neighbor_mating=0.9,
                 display=MultiObjectiveDisplay(),
                 **kwargs):
        """

        Parameters
        ----------
        ref_dirs : {ref_dirs}

        decomposition : {{ 'auto', 'tchebi', 'pbi' }}
            The decomposition approach that should be used. If set to `auto` for two objectives `tchebi` and for more than
            two `pbi` will be used.

        n_neighbors : int
            Number of neighboring reference lines to be used for selection.

        prob_neighbor_mating : float
            Probability of selecting the parents in the neighborhood.


        """

        self.n_neighbors = n_neighbors
        self.prob_neighbor_mating = prob_neighbor_mating
        self.decomposition = decomposition

        set_if_none(kwargs, 'pop_size', len(ref_dirs))
        set_if_none(kwargs, 'sampling', FloatRandomSampling())
        set_if_none(kwargs, 'crossover',
                    SimulatedBinaryCrossover(prob=1.0, eta=20))
        set_if_none(kwargs, 'mutation', PolynomialMutation(prob=None, eta=20))
        set_if_none(kwargs, 'survival', None)
        set_if_none(kwargs, 'selection', None)

        super().__init__(display=display, **kwargs)

        # initialized when problem is known
        self.ref_dirs = ref_dirs

        if self.ref_dirs.shape[0] < self.n_neighbors:
            print("Setting number of neighbours to population size: %s" %
                  self.ref_dirs.shape[0])
            self.n_neighbors = self.ref_dirs.shape[0]

        # neighbours includes the entry by itself intentionally for the survival method
        self.neighbors = np.argsort(cdist(self.ref_dirs, self.ref_dirs),
                                    axis=1,
                                    kind='quicksort')[:, :self.n_neighbors]
예제 #4
0
파일: moead.py 프로젝트: zyhuster1/pymoo
    def __init__(self,
                 ref_dirs,
                 n_neighbors=20,
                 decomposition='auto',
                 prob_neighbor_mating=0.9,
                 display=MultiObjectiveDisplay(),
                 **kwargs):
        """

        Parameters
        ----------
        ref_dirs
        n_neighbors
        decomposition
        prob_neighbor_mating
        display
        kwargs
        """

        self.n_neighbors = n_neighbors
        self.prob_neighbor_mating = prob_neighbor_mating
        self.decomposition = decomposition

        set_if_none(kwargs, 'pop_size', len(ref_dirs))
        set_if_none(kwargs, 'sampling', FloatRandomSampling())
        set_if_none(kwargs, 'crossover',
                    SimulatedBinaryCrossover(prob=1.0, eta=20))
        set_if_none(kwargs, 'mutation', PolynomialMutation(prob=None, eta=20))
        set_if_none(kwargs, 'survival', None)
        set_if_none(kwargs, 'selection', None)

        super().__init__(display=display, **kwargs)

        # initialized when problem is known
        self.ref_dirs = ref_dirs

        if self.ref_dirs.shape[0] < self.n_neighbors:
            print("Setting number of neighbours to population size: %s" %
                  self.ref_dirs.shape[0])
            self.n_neighbors = self.ref_dirs.shape[0]

        # neighbours includes the entry by itself intentionally for the survival method
        self.neighbors = np.argsort(cdist(self.ref_dirs, self.ref_dirs),
                                    axis=1,
                                    kind='quicksort')[:, :self.n_neighbors]
예제 #5
0
 def save(self, fname, **kwargs):
     self.plot_if_not_done_yet()
     set_if_none(kwargs, "bbox_inches", "tight")
     self.fig.savefig(fname, **kwargs)
     return self
예제 #6
0
    def _do(self):

        is_1d = (self.n_dim == 1)
        is_2d = (self.n_dim == 2)
        is_3d = (self.n_dim == 3)
        more_than_3d = (self.n_dim > 3)

        # create the figure and axis objects
        if is_1d or is_2d:
            self.init_figure()
        elif is_3d:
            self.init_figure(plot_3D=True)
        elif more_than_3d:
            self.init_figure(n_rows=self.n_dim, n_cols=self.n_dim)

        # now plot data points for each entry
        for k, (F, kwargs) in enumerate(self.to_plot):

            # copy the arguments and set the default color
            _kwargs = kwargs.copy()
            set_if_none(_kwargs, "color", self.colors[k % len(self.colors)])

            # determine the plotting type - scatter or line
            _type = _kwargs.get("plot_type")
            if "plot_type" in _kwargs:
                del _kwargs["plot_type"]

            if is_1d:
                F = np.column_stack([F, np.zeros(len(F))])
                labels = self.get_labels() + [""]

                self.plot(self.ax, _type, F, **_kwargs)
                self.set_labels(self.ax, labels, False)

            elif is_2d:
                self.plot(self.ax, _type, F, **_kwargs)
                self.set_labels(self.ax, self.get_labels(), False)

            elif is_3d:
                set_if_none(_kwargs, "alpha", 1.0)

                self.plot(self.ax, _type, F, **_kwargs)
                self.ax.xaxis.pane.fill = False
                self.ax.yaxis.pane.fill = False
                self.ax.zaxis.pane.fill = False

                self.set_labels(self.ax, self.get_labels(), True)

                if self.angle is not None:
                    self.ax.view_init(*self.angle)

            else:
                labels = self.get_labels()

                for i in range(self.n_dim):
                    for j in range(self.n_dim):

                        ax = self.ax[i, j]

                        if i != j:
                            self.plot(ax, _type, F[:, [i, j]], **_kwargs)
                            self.set_labels(ax, [labels[i], labels[j]], is_3d)
                        else:
                            ax.set_xticks([])
                            ax.set_yticks([])
                            ax.scatter(0, 0, s=1, color="white")
                            ax.text(0, 0, labels[i], ha='center', va='center', fontsize=20)

        return self
예제 #7
0
    def __init__(self,
                 ref_dirs,
                 n_neighbors=20,
                 decomposition=Tchebicheff(),
                 prob_neighbor_mating=0.9,
                 rate_update_weight=0.05,
                 rate_evol=0.8,
                 wag=20,
                 archive_size_multiplier=1.5,
                 use_new_ref_dirs_initialization=True,
                 display=MultiObjectiveDisplay(),
                 **kwargs):
        """

        MOEAD-AWA Algorithm.

        Parameters
        ----------
        ref_dirs
        n_neighbors
        decomposition
        prob_neighbor_mating
        rate_update_weight
        rate_evol
        wag
        archive_size_multiplier
        use_new_ref_dirs_initialization
        display
        kwargs
        """

        self.n_neighbors = n_neighbors
        self.prob_neighbor_mating = prob_neighbor_mating
        self.decomp = decomposition

        self.rate_update_weight = rate_update_weight
        self.rate_evol = rate_evol
        self.wag = wag

        self.EP = None
        self.nEP = np.ceil(len(ref_dirs) * archive_size_multiplier)

        set_if_none(kwargs, 'pop_size', len(ref_dirs))
        set_if_none(kwargs, 'sampling', FloatRandomSampling())
        set_if_none(kwargs, 'crossover', SBX(prob=1.0, eta=20))
        set_if_none(kwargs, 'mutation', PM(prob=None, eta=20))
        set_if_none(kwargs, 'survival', None)
        set_if_none(kwargs, 'selection', None)

        super().__init__(display=display, **kwargs)

        # initialized when problem is known
        self.ref_dirs = ref_dirs
        if use_new_ref_dirs_initialization:
            self.ref_dirs = 1.0 / (self.ref_dirs + 1e-6)
            self.ref_dirs = self.ref_dirs / np.sum(self.ref_dirs, axis=1)[:,
                                                                          None]

        if self.ref_dirs.shape[0] < self.n_neighbors:
            print("Setting number of neighbours to population size: %s" %
                  self.ref_dirs.shape[0])
            self.n_neighbors = self.ref_dirs.shape[0]

        self.nds = NonDominatedSorting()

        # compute neighbors of reference directions using euclidean distance
        self._update_neighbors()