Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

100 x 100 matrix evaluation #9

Open
pnovoa opened this issue Jun 29, 2023 · 4 comments
Open

100 x 100 matrix evaluation #9

pnovoa opened this issue Jun 29, 2023 · 4 comments

Comments

@pnovoa
Copy link

pnovoa commented Jun 29, 2023

Hello, great project. However, I have a question, why at the beginning of the NSGA-II execution, it calls the fitness function with a 100 x 100 matrix? This evaluation causes me problems, because in the implementation of my fitness function I expect a vector of 1xn (n number of dimension) or maybe a matrix of mxn. But no, a 100x100 matrix.

@benitezfj
Copy link
Collaborator

Hello, could you share the call you made to the NSGA-II function? rmoo is designed to generate an initial population M with a size equal to the value established in the popSize argument, and the number of decision variables N is equal to the length of the upper argument, which represents the upper bounds vector of the decision variables.

@pnovoa
Copy link
Author

pnovoa commented Jul 3, 2023

Hi, here is the code, from the example you provide in the repository. Following your explanation above, DTLZ1 should be called by passing it an array of dimension m x n, where n is the size of the upper parameter (in this case n=3). However, as you will see when printing x on the first call, rmoo is passing DTLZ1 a 100 x 100 matrix. I have found that this happens (apparently) when the fitness function is first called.


first_call <<- TRUE

DTLZ1 <- function (x, nobj = 3, ...)
{
 if (is.null(dim(x))) {
   x <- matrix(x, 1)
 }

 if(first_call){
   print(dim(x))
   first_call <<- FALSE
 }

 n <- ncol(x)
 y <- matrix(x[, 1:(nobj - 1)], nrow(x))
 z <- matrix(x[, nobj:n], nrow(x))
 g <- 100 * (n - nobj + 1 + rowSums((z - 0.5)^2 - cos(20 *
                                                        pi * (z - 0.5))))
 tmp <- t(apply(y, 1, cumprod))
 tmp <- cbind(t(apply(tmp, 1, rev)), 1)
 tmp2 <- cbind(1, t(apply(1 - y, 1, rev)))
 f <- tmp * tmp2 * 0.5 * (1 + g)
 return(f)
}

result <- rmoo(fitness = DTLZ1,
              type = "real-valued",
              strategy = "NSGA-III",
              lower = c(0,0,0),
              upper = c(1,1,1),
              monitor = FALSE,
              summary = FALSE,
              popSize = 92,
              n_partitions = 12,
              maxiter = 300)

@benitezfj
Copy link
Collaborator

I've tested the code and I was unable to reproduce the error. I've made a small modification to the objective function code to include printing the candidate solution along with its dimension in the first evaluation:

DTLZ1 <- function (x, nobj = 3, ...) {
 if (is.null(dim(x))) {
   x <- matrix(x, 1)
 }

 if(first_call_to_objetive_func){
   cat("Dimension:", dim(x), "\n")
   # I printed the evaluated candidate solution for testing
   cat("Solution:", x, "\n")
   first_call_to_objetive_func <<- FALSE
 }

 n <- ncol(x)
 y <- matrix(x[, 1:(nobj - 1)], nrow(x))
 z <- matrix(x[, nobj:n], nrow(x))
 g <- 100 * (n - nobj + 1 + rowSums((z - 0.5)^2 - cos(20 *
                                                        pi * (z - 0.5))))
 tmp <- t(apply(y, 1, cumprod))
 tmp <- cbind(t(apply(tmp, 1, rev)), 1)
 tmp2 <- cbind(1, t(apply(1 - y, 1, rev)))
 f <- tmp * tmp2 * 0.5 * (1 + g)
 return(f)
}

I've also attempted to verify it using the monitor argument (This will print the solution at the end of each generation), and the results consistently match the print statement within the objective function and the parameters specified in the function call.

The monitor function that will be called at the end of each generation:

monitortest <- function(object, number_objectives, ...) {
  iter <- object@iter
  cat("\n", "Iter:", object@iter, "\n")
  if(first_call_to_monitor){
    cat("Pop Size:", nrow(object@population), " ", "Number of Decision Variables:", ncol(object@population))
    first_call_to_monitor <<- FALSE
  }
}
first_call_to_objetive_func <<- TRUE
first_call_to_monitor <<- TRUE
result <- rmoo(fitness = DTLZ1,
              type = "real-valued",
              strategy = "NSGA-III",
              lower = c(0,0,0),
              upper = c(1,1,1),
              monitor = monitortest,
              summary = FALSE,
              nObj=3,
              seed=45,
              popSize = 92,
              n_partitions = 12,
              maxiter = 5)

The candidate solution printed by the objective function in the first evaluation:

Dimension: 1 3
Solution: 0.6333728 0.8823254 0.05823419

And the printing of the monitor function:

Iter: 1
Pop Size: 92   Number of Decision Variables: 3                                                                                                                           Iter: 2

Does this error occur exclusively when using the sample code, or does it also occur with other specific problems?

@pnovoa
Copy link
Author

pnovoa commented Oct 12, 2023

Hi, I have already discovered the cause. I was not passing the "nObj" parameter. Without it, the algorithm assumes that the number of objective function is 100?

When I debugged it, I get to this part in your code:

{ if (is.null(nObj)) {
nObj <- ncol(fitness(matrix(10000, ncol = 100, nrow = 100)))
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants