Import Library

suppressWarnings(suppressMessages({
  library(stats)
  library(fields)
  library(matrixStats)
  library(dplyr)
  library(proxy)
  library(usdm)
  library(factoextra)
  library(fmsb)
  library(reshape2)
  library(ggplot2)
  library(scales)
}))

Import Data

data_raw <- read.csv("Data.csv", row.names = 1)
data <- data_raw
pop <- read.csv("populasi.csv", header = FALSE)
pop <- as.numeric(pop[[1]])
dist_df <- read.csv("jarak_jabar.csv", header = TRUE, check.names = FALSE)
rownames(dist_df) <- colnames(dist_df)
dist <- as.matrix(dist_df)
head(data)

Analisis Deskriptif

summary_table <- data.frame(
  Variabel = colnames(data),
  Min = round(sapply(data, min, na.rm = TRUE), 2),
  Q1 = round(sapply(data, quantile, probs = 0.25, na.rm = TRUE), 2),
  Median = round(sapply(data, median, na.rm = TRUE), 2),
  Q3 = round(sapply(data, quantile, probs = 0.75, na.rm = TRUE), 2),
  Maks = round(sapply(data, max, na.rm = TRUE), 2),
  `Rata - rata` = round(sapply(data, mean, na.rm = TRUE), 2)
)
print(summary_table)
##          Variabel     Min       Q1   Median       Q3     Maks Rata...rata
## TPT           TPT    1.58     6.20     6.73     7.59     8.97        6.52
## Minum       Minum   85.37    92.71    96.76    98.08    99.85       95.10
## Stunting Stunting    1.60     2.41     3.58     8.09    17.08        5.44
## IPLM         IPLM   44.59    60.47    69.95    79.02    95.37       70.14
## NDVI         NDVI    0.26     0.38     0.52     0.62     0.66        0.50
## SO2           SO2    0.00     0.00     0.00     0.00     0.00        0.00
## RLS           RLS    6.95     7.88     8.24    10.07    11.79        8.91
## Gini         Gini    0.29     0.34     0.37     0.40     0.48        0.37
## PPP           PPP 8965.00 10251.50 11563.00 12905.50 18795.00    11928.85
## TPAK         TPAK   62.58    66.37    67.93    69.25    80.12       68.06
## UHH           UHH   70.39    72.22    73.16    74.53    76.12       73.26
## CO             CO    0.03     0.03     0.03     0.03     0.04        0.03
vars_official <- c("TPT", "Minum", "Stunting", "IPLM", 
                   "RLS", "Gini", "PPP", "TPAK", "UHH")

data_filtered <- data[, vars_official]
data_filtered$id <- 1:nrow(data_filtered)
data_long <- melt(data_filtered, id.vars = "id")
data_long$variable <- factor(data_long$variable, levels = vars_official)
ggplot(data_long, aes(x = "", y = value)) +
  geom_boxplot(fill = "#1F77B4", color = "black", width = 0.5, outlier.size = 1) +
  facet_wrap(~ variable, scales = "free_y", ncol = 3) +
  labs(
    y = "Nilai Indikator",
    x = NULL,
  ) +
  theme_minimal(base_size = 12) +
  theme(
    strip.text = element_text(face = "bold", size = 11, color = "#333333"),
    axis.text.x = element_blank(),
    axis.ticks.x = element_blank(),
    panel.grid.major.x = element_blank(),
    panel.grid.minor = element_blank(),
    plot.title = element_text(face = "bold", size = 14, color = "#222222"),
    plot.subtitle = element_text(size = 12, color = "#555555"),
    plot.caption = element_text(size = 9, color = "#666666", hjust = 0),
    panel.spacing = unit(1.2, "lines")
  )

Preprocessing

# Scaling
min_max_scaling <- function(x) {
  return((x - min(x)) / (max(x) - min(x)))
}
num_cols <- sapply(data, is.numeric)
scaled_data <- data
scaled_data[num_cols] <- lapply(data[num_cols], min_max_scaling)
scaled_data <- scaled_data[num_cols]
head(scaled_data)
# Pengecekan Multikolinearitas
vif_result <- vif(scaled_data)
vif_result

Pengecekan Tendensi Pembentukan Cluster

distance_matrix <- dist(scaled_data)
fviz_dist(distance_matrix, 
          show_labels = TRUE,  
          lab_size = 2.8,
          gradient = list(
            low = "#313695", 
            mid = "#f7f7f7", 
            high = "#a50026"
          )) +
  labs(
    title = "Visual Assessment of Cluster Tendency",
    fill = "Nilai",
    x = NULL,
    y = NULL
  )  +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 16),
    axis.text.x = element_text(angle = 45, hjust = 1, size = 8, vjust = 1),
    axis.text.y = element_text(size = 8),
    legend.title = element_text(size = 10, face = "bold"),
    legend.text = element_text(size = 8),
    panel.grid = element_blank()
  )

Fungsi Index Validasi

# 1. Partition Coefficient
partition_coefficient <- function(uij) {
  sum(uij^2) / nrow(uij)
}

# 2. Classification Entropy
classification_entropy <- function(uij, base_log = exp(1)) {
  -sum(uij * log(uij + 1e-10, base_log)) / nrow(uij)
}

# 3. Separation-Compactness Index (SC)
separation_compactness <- function(data_matrix, cluster_labels, uij, centroids, m) {
  dist_to_centroids <- as.matrix(proxy::dist(data_matrix, centroids))^2
  numerator <- colSums((uij^m) * dist_to_centroids)
  
  sep_matrix <- as.matrix(dist(centroids))^2
  Ni <- sapply(1:nrow(centroids), function(k) sum(cluster_labels == k))

  # Kasus jika cluster ada yang kosong
  Ni[Ni == 0] <- 1
  sep_matrix <- t(t(sep_matrix) * Ni)
  denominator <- colSums(sep_matrix)
  denominator[denominator == 0] <- 1e-10 
  sum(numerator / denominator)
}

# 4. Xie-Beni Index (XB)
xie_beni_index <- function(data_matrix, uij, centroids, m) {
  dist_matrix <- as.matrix(proxy::dist(data_matrix, centroids))^2
  min_sep_sq <- min(as.matrix(dist(centroids))^2 + diag(Inf, nrow(centroids)))
  if (min_sep_sq == 0) return(Inf)
  sum((uij^m) * dist_matrix) / (nrow(data_matrix) * min_sep_sq)
}

# 5. Index of Fuzzy Validity (IFV)
index_fuzzy_validity <- function(data_matrix, uij, centroids, m) {
  inter_centroid_dist <- as.matrix(dist(centroids))^2
  sigma_d <- mean(as.matrix(proxy::dist(data_matrix, centroids))^2)
  sd_max <- max(inter_centroid_dist)
  if (sigma_d == 0) return(0)
  log2_uij <- colSums(log(uij + 1e-10, 2)) / nrow(uij)
  sum_u2ij <- colSums(uij^2)
  term <- (log(ncol(uij), 2) - log2_uij)^2
  sum(sum_u2ij * term) / nrow(data_matrix) * (sd_max / sigma_d)
}
# Fungsi utama validasi FGWC
index_fgwc <- function(data_matrix, cluster_labels, membership, centroids, m, base_log = exp(1)) {
  list(
    PC    = partition_coefficient(membership),
    CE    = classification_entropy(membership, base_log),
    SC    = separation_compactness(data_matrix, cluster_labels, membership, centroids, m),
    XB    = xie_beni_index(data_matrix, membership, centroids, m),
    IFV   = index_fuzzy_validity(data_matrix, membership, centroids, m)
  )
}

Fungsi Pembantu

## Menghitung pusat cluster dari data dan matriks keanggotaan
vi <- function(data,uij,m) {
  return (sweep(t(uij^m) %*% data, 1, colSums(uij^m), FUN="/"))
}

## Menghitung matriks jarak Euclidean kuadrat
cdist <- function(x, y) {
  return(as.matrix(proxy::dist(x, y, method = "euclidean"))^2)
}

## Menghitung matriks keanggotaan (u_ij) dari centroid
uij <- function(data, centroids, m) {
  d <- cdist(data, centroids)
  d[d == 0] <- 1e-10
  power <- 1 / (m - 1)
  dist_inv_powered <- d ^ (-power)
  u <- sweep(dist_inv_powered, 1, rowSums(dist_inv_powered), FUN="/")
  list(d = d, u = u)
}

## Menentukan cluster dari data
determine_cluster <- function(data,uij) {
    clust <- apply(uij, 1, which.max)
    return(cbind.data.frame(data, cluster = clust))
}

## Memperbarui matriks keanggotaan menggunakan bobot geografis
renew_uij <- function(old_uij, mi.mj, dist, alpha, beta, a, b) {
  diag(dist) <- 0

  dist_powered <- dist^a
  dist_powered[dist_powered == 0] <- 1e-10
  wij <- mi.mj^b / dist_powered
  diag(wij) <- 0
  wijmuj <- wij %*% old_uij
  A <- rowSums(wij)
  A[A == 0] <- 1e-10
  spatial_term <- (beta / A) * wijmuj
  new_uij <- alpha * old_uij + spatial_term
  return(new_uij)
}

## Menghasilkan pusat cluster awal
gen_vi <- function(data, ncluster, gendist, randomN) {
  p <- ncol(data)
  piclass <- matrix(0, ncluster, p)
  set.seed(randomN)
  
  min_vals <- colMins(data)
  max_vals <- colMaxs(data)
  
  for (i in 1:p) {
    if (gendist=="normal"){
      piclass[,i] <- rnorm(ncluster, mean(data[,i]), sd(data[,i]))
    }
    else if (gendist=="uniform"){
      piclass[,i] <- runif(ncluster, min_vals[i], max_vals[i])
    }
  }
  return(piclass)
}

## Fungsi Objektif FGWC
jfgwcv <- function(data, centroids, u, m) {
  d <- cdist(data, centroids)
  sum((u^m) * d)
}

Fungsi FGWC

fgwc <- function(data, pop, distmat, ncluster = 2, m = 2,
                 alpha = 0.7, a = 1, b = 1, max.iter = 100, error = 1e-5,
                 randomN = 0, initial_centroids = NA) {
  ptm <- proc.time()
  n <- nrow(data)
  beta <- 1 - alpha
  iter <- 0
  conv <- c()
  
  if (!is.matrix(data)) {
    data <- as.matrix(data)
  }

  if (alpha == 1) {
    pop <- rep(1, n)
    # matriks jarak tidak berpengaruh jika beta = 0
    distmat <- matrix(1, n, n) 
  }
  pop <- matrix(pop, ncol = 1)
  mi.mj <- pop %*% t(pop)
  # Pemeriksaan centroid awal
  if (is.na(initial_centroids[1])) {
    v_new <- gen_vi(data, ncluster, "uniform", randomN)
  } else {
    v_new <- initial_centroids
  }
  
  v_old <- v_new + 1
  obj_old <- 0

  while (iter < max.iter) {
    iter <- iter + 1
    v_old <- v_new
    # update standar FCM
    u_fcm <- uij(data, v_old, m)$u
    # update FGWC
    u_fgwc <- renew_uij(u_fcm, mi.mj, distmat, alpha, beta, a, b)
    # Update centroids
    v_new <- vi(data, u_fgwc, m)
    # Hitung nilai fungsi objektif
    obj_new <- jfgwcv(data, v_new, u_fgwc, m)
    conv <- c(conv, obj_new)
    # memeriksa konvergen
    if (abs(obj_new - obj_old) < error) {
      break
    }
    obj_old <- obj_new
  }

  finaldata <- determine_cluster(data.frame(data), u_fgwc)
  cluster <- finaldata$cluster

  result <- list(
    converg = conv,
    f_obj = tail(conv, 1),
    membership = u_fgwc,
    centroid = v_new,
    validation = index_fgwc(data, cluster, u_fgwc, v_new, m),
    iteration = iter,
    cluster = cluster,
    finaldata = finaldata,
    call = match.call(),
    time = proc.time() - ptm
  )
  class(result) <- "fgwc"
  return(result)
}

FGWC-ABC

# Mengevaluasi fitness dari solusi centroid ABC
evaluate_solution <- function(centroids, data, m, pop, distmat, alpha, beta, a, b) {
    mi.mj <- pop %*% t(pop)
    # Update standar FCM
    u_fcm <- uij(data, centroids, m)$u
    # update FGWC
    u_fgwc <- renew_uij(u_fcm, mi.mj, distmat, alpha, beta, a, b)
    # update centroid
    v_new <- vi(data, u_fgwc, m)
    # fungsi objektif
    fitness <- jfgwcv(data, v_new, u_fgwc, m)
    return(list(
        centroid = v_new,
        membership = u_fgwc,
        fitness = fitness
    ))
}

abc_fgwc <- function(data, pop = NA, distmat = NA, ncluster = 2, m = 2,
                     alpha = 0.7, a = 1, b = 1, max_iter = 100,
                     random_seed = 0, vi_dist = "uniform", n_food = 10,
                     n_onlooker = 5, scout_limit = 5, patience = 10) {

    start_time <- proc.time()
    n <- nrow(data)
    p <- ncol(data)
    beta <- 1 - alpha

    data <- as.matrix(data)
    data_original <- as.data.frame(data)

    if (alpha == 1) {
        pop <- rep(1, n)
        distmat <- matrix(1, n, n)
    }
    pop_mat <- matrix(pop, ncol = 1)
    minmax <- rbind(colMins(data), colMaxs(data))
    
    # fase inisialisasi
    set.seed(random_seed)
    food_sources <- vector("list", n_food)
    for (i in 1:n_food) {
        # Menghasilkan titik awal secara acak dan mengevaluasinya
        initial_v <- gen_vi(data, ncluster, vi_dist, random_seed + i)
        food_sources[[i]] <- evaluate_solution(initial_v, data, m, pop_mat, distmat, alpha, beta, a, b)
    }
    # Melacak jumlah percobaan untuk lebah pengintai
    trial_counters <- rep(0, n_food)
    # Menemukan solusi terbaik awal
    all_fitness <- sapply(food_sources, `[[`, "fitness")
    best_idx <- which.min(all_fitness)
    global_best <- food_sources[[best_idx]]
    convergence_history <- c(global_best$fitness)
    no_improve_counter <- 0

    # Perulangan ABC
    for (iter in 1:max_iter) {
        # Fase Employed Bee
        for (i in 1:n_food) {
            current_v <- food_sources[[i]]$centroid
            
            # Menghasilkan solusi kandidat
            set.seed(random_seed + iter * n_food + i)
            partner_idx <- sample(setdiff(1:n_food, i), 1)
            partner_v <- food_sources[[partner_idx]]$centroid
            phi <- matrix(runif(ncluster * p, -1, 1), nrow=ncluster)
            candidate_v <- current_v + phi * (current_v - partner_v)
            
            #  Evaluasi kandidat solusi terbaru
            candidate_sol <- evaluate_solution(candidate_v, data, m, pop_mat, distmat, alpha, beta, a, b)
            
            # Greedy selection
            if (candidate_sol$fitness < food_sources[[i]]$fitness) {
                food_sources[[i]] <- candidate_sol
                trial_counters[i] <- 0
            } else {
                trial_counters[i] <- trial_counters[i] + 1
            }
        }

        # Fase Onlooker Bee
        all_fitness <- sapply(food_sources, `[[`, "fitness")
        probs <- (1 / all_fitness) / sum(1 / all_fitness)
        if (any(is.na(probs))) probs <- rep(1 / n_food, n_food)
        
        for (i in 1:n_onlooker) {
            set.seed(random_seed + iter * n_food * 2 + i)
            chosen_idx <- sample(1:n_food, 1, prob = probs)
            
            # Onlooker bertindak seperti lebah pekerja pada sumber yang dipilih
            current_v <- food_sources[[chosen_idx]]$centroid
        
            set.seed(random_seed + iter * n_food * 3 + i)
            partner_idx <- sample(setdiff(1:n_food, chosen_idx), 1)
            partner_v <- food_sources[[partner_idx]]$centroid
        
            phi <- matrix(runif(ncluster * p, -1, 1), nrow = ncluster)
            candidate_v <- current_v + phi * (current_v - partner_v)
        
            candidate_sol <- evaluate_solution(candidate_v, data, m, pop_mat, distmat, alpha, beta, a, b)
        
            if (candidate_sol$fitness < food_sources[[chosen_idx]]$fitness) {
                food_sources[[chosen_idx]] <- candidate_sol
                trial_counters[chosen_idx] <- 0
            } else {
                trial_counters[chosen_idx] <- trial_counters[chosen_idx] + 1
            }
        }
        # Fase Scout Bee
        abandoned_indices <- which(trial_counters >= scout_limit)
        if (length(abandoned_indices) > 0) {
            for (idx in abandoned_indices) {
                set.seed(random_seed + iter * n_food * 4 + idx)
                initial_v <- gen_vi(data, ncluster, vi_dist, random_seed + iter * n_food * 5 + idx)
                food_sources[[idx]] <- evaluate_solution(initial_v, data, m, pop_mat, distmat, alpha, beta, a, b)
                trial_counters[idx] <- 0
            }
        }
        all_fitness <- sapply(food_sources, `[[`, "fitness")
        current_best_idx <- which.min(all_fitness)
        
        if(all_fitness[current_best_idx] < global_best$fitness) {
            global_best <- food_sources[[current_best_idx]]
            no_improve_counter <- 0
        } else {
            no_improve_counter <- no_improve_counter + 1
        }
        
        convergence_history <- c(convergence_history, global_best$fitness)
        if (no_improve_counter >= patience) {
            print(paste("Algoritma berhenti pada iterasi", iter))
            break
        }
    }
    final_data <- determine_cluster(data_original, global_best$membership)
    cluster <- final_data$cluster

    result <- list(
        converg = convergence_history,
        f_obj = global_best$fitness,
        membership = global_best$membership,
        centroid = global_best$centroid,
        validation = index_fgwc(data, cluster, global_best$membership, global_best$centroid, m),
        cluster = cluster,
        finaldata = final_data,
        call = match.call(),
        iteration = iter,
        time = proc.time() - start_time
    )
    class(result) <- "abc_fgwc"
    return(result)
}

FGWC-PSO

update_v <- function(theta, v0, vmax_abs, c1, c2, gbest_pos, pbest_pos, current_pos, random_seed) {
  n <- nrow(current_pos)
  d <- ncol(current_pos)
  
  set.seed(random_seed)
  e1 <- matrix(runif(n * d), nrow = n, ncol = d)
  e2 <- matrix(runif(n * d), nrow = n, ncol = d)
  
  cognitive_comp <- c1 * e1 * (pbest_pos - current_pos)
  social_comp <- c2 * e2 * (gbest_pos - current_pos)
  v_new <- theta * v0 + cognitive_comp + social_comp
  
  for (j in 1:ncol(v_new)) {
    col_v <- v_new[, j]
    col_v[col_v < -vmax_abs[j]] <- -vmax_abs[j]
    col_v[col_v > vmax_abs[j]] <- vmax_abs[j]
    v_new[, j] <- col_v
  }
  return(v_new)
}

# Memperbarui bobot inertia
update_inertia <- function(w_inert, wmax, wmin, map, iter, max_iter) {
  if (w_inert == "constant") {
    return(wmax)
  } else if (w_inert == "chaotic") {
    return((wmax - wmin) * (1 - iter / max_iter) + (wmin * map))
  } else if (w_inert == "sim.annealing") {
    return(wmin + ((wmax - wmin) * 0.95^(iter - 1)))
  } else if (w_inert == "nat.exponent1") {
    return(wmin + ((wmax - wmin) * exp(iter / (max_iter / 10))))
  } else if (w_inert == "nat.exponent2") {
    return(wmin + ((wmax - wmin) * exp((iter / (max_iter / 10))^2)))
  } else {
    return(wmax - (wmax - wmin) * (iter / max_iter))
  }
}

pso_fgwc <- function(data, pop = NA, distmat = NA, ncluster = 2, m = 2,
                    alpha = 0.7, a = 1, b = 1, max_iter = 100,
                    random_seed = 0, vi_dist = "uniform", n_particles = 10,
                    vmax_perc = 0.7, patience = 10, c1 = 0.7, c2 = 0.6,
                    w_inert = 'sim.annealing', wmax = 0.9, wmin = 0.2, map = 0.4) {
  
  start_time <- proc.time()
  n <- nrow(data)
  p <- ncol(data)
  beta <- 1 - alpha

  data <- as.matrix(data)
  data_original <- as.data.frame(data)

  if (alpha == 1) {
    pop <- rep(1, n)
    distmat <- matrix(1, n, n)
  }
  pop_mat <- matrix(pop, ncol = 1)
  
  vmax_abs <- (colMaxs(data) - colMins(data)) * vmax_perc
  set.seed(random_seed)
  swarm <- vector("list", n_particles)
  pbest_solutions <- vector("list", n_particles)
  velocities <- vector("list", n_particles)

  for (i in 1:n_particles) {
    initial_v <- gen_vi(data, ncluster, vi_dist, random_seed + i)
    swarm[[i]] <- evaluate_solution(initial_v, data, m, pop_mat, distmat, alpha, beta, a, b)
    pbest_solutions[[i]] <- swarm[[i]]
    velocities[[i]] <- matrix(0, nrow = ncluster, ncol = p)
  }

  all_pbest_fitness <- sapply(pbest_solutions, `[[`, "fitness")
  best_idx <- which.min(all_pbest_fitness)
  gbest_solution <- pbest_solutions[[best_idx]]
  
  convergence_history <- c(gbest_solution$fitness)
  no_improve_counter <- 0
  for (iter in 1:max_iter) {
    
    theta <- update_inertia(w_inert, wmax, wmin, map, iter, max_iter)
  
    for (i in 1:n_particles) {
      current_solution <- swarm[[i]]
      current_pos <- current_solution$centroid
      
      pbest_pos <- pbest_solutions[[i]]$centroid
      gbest_pos <- gbest_solution$centroid
      
      velocities[[i]] <- update_v(theta, velocities[[i]], vmax_abs, c1, c2, 
                                  gbest_pos, pbest_pos, current_pos, 
                                  random_seed + iter * n_particles + i)

      trial_pos <- current_pos + velocities[[i]]
      evaluated_solution <- evaluate_solution(trial_pos, data, m, pop_mat, distmat, alpha, beta, a, b)
      swarm[[i]] <- evaluated_solution
      
      if (evaluated_solution$fitness < pbest_solutions[[i]]$fitness) {
        pbest_solutions[[i]] <- evaluated_solution
      }
    }
    
    all_pbest_fitness <- sapply(pbest_solutions, `[[`, "fitness")
    best_current_idx <- which.min(all_pbest_fitness)
    
    if (all_pbest_fitness[best_current_idx] < gbest_solution$fitness) {
      gbest_solution <- pbest_solutions[[best_current_idx]]
      no_improve_counter <- 0
    } else {
      no_improve_counter <- no_improve_counter + 1
    }
    convergence_history <- c(convergence_history, gbest_solution$fitness)
    
    if (no_improve_counter >= patience) {
      print(paste("Algoritma berhenti pada iterasi", iter))
      break
    }
  } 

  final_data <- determine_cluster(data_original, gbest_solution$membership)
  cluster <- final_data$cluster

  result <- list(
    converg = convergence_history,
    f_obj = gbest_solution$fitness,
    membership = gbest_solution$membership,
    centroid = gbest_solution$centroid,
    validation = index_fgwc(data, cluster, gbest_solution$membership, gbest_solution$centroid, m),
    cluster = cluster,
    finaldata = final_data,
    call = match.call(),
    iteration = iter,
    time = proc.time() - start_time
  )
  class(result) <- "psofgwc"
  return(result)
}

FGWC-GSA

gsa_update <- function(population, velocities, G, k_best_perc, vmax_abs, random_seed) {
  n_agents <- length(population)
  
  # Menghitung Massa
  fitness_values <- sapply(population, `[[`, "fitness")
  min_fit <- min(fitness_values)
  max_fit <- max(fitness_values)
  
  if (min_fit == max_fit) {
    mass <- rep(1, n_agents)
  } else {
    mass <- (fitness_values - max_fit) / (min_fit - max_fit)
  }
  mass <- mass / sum(mass)
  
  # Menentukan K-terbaik
  num_k_best <- max(2, ceiling(n_agents * k_best_perc))
  k_best_indices <- order(mass, decreasing = TRUE)[1:num_k_best]

  # Menghitung Gaya, Percepatan dan kecepatan baru
  new_velocities <- velocities
  for (i in 1:n_agents) {
    total_force <- 0
    
    for (j in k_best_indices) {
      if (i == j) next
      
      current_pos <- population[[i]]$centroid
      attractor_pos <- population[[j]]$centroid
      dist_sq <- sum((current_pos - attractor_pos)^2)
      
      set.seed(random_seed + i * n_agents + j)
      rand_val <- runif(1)
      force_ij <- rand_val * G * (mass[j] / (dist_sq + 1e-10)) * (attractor_pos - current_pos)
      total_force <- total_force + force_ij
    }
    
    acceleration <- total_force 
    
    set.seed(random_seed + i)
    rand_vel <- runif(1)
    new_v_matrix <- rand_vel * velocities[[i]] + acceleration
    
    for (k in 1:ncol(new_v_matrix)) {
        col_v <- new_v_matrix[, k]
        col_v[col_v < -vmax_abs[k]] <- -vmax_abs[k]
        col_v[col_v > vmax_abs[k]] <- vmax_abs[k]
        new_v_matrix[, k] <- col_v
    }
    new_velocities[[i]] <- new_v_matrix
  }
  return(new_velocities) 
}

new_move <- function(current_pos, pbest_pos, gbest_pos, random_seed) {
  mu <- (current_pos + pbest_pos + gbest_pos) / 3
  sigma <- sqrt(((current_pos - mu)^2 + (pbest_pos - mu)^2 + (gbest_pos - mu)^2) / 3)
  
  set.seed(random_seed)
  dd <- dim(current_pos)
  c1 <- matrix(runif(dd[1] * dd[2]), ncol = dd[2])
  c2 <- matrix(runif(dd[1] * dd[2]), ncol = dd[2])
  z <- sqrt(-2 * log(c1)) * cos(2 * pi * c2)
  return(mu + sigma * z)
}

gsa_fgwc <- function(data, pop = NA, distmat = NA, ncluster = 2, m = 2,
                    alpha = 0.7, a = 1, b = 1, max_iter = 100,
                    random_seed = 0, vi_dist = "uniform", n_agents = 10,
                    patience = 10, G0 = 1, G_decay_rate = 0.97, 
                    k_best_perc = 0.5, vmax_perc = 0.7, use_new_move = FALSE) {

  start_time <- proc.time()
  n <- nrow(data)
  p <- ncol(data)
  beta <- 1 - alpha

  data <- as.matrix(data)
  data_original <- as.data.frame(data)

  if (alpha == 1) {
    pop <- rep(1, n)
    distmat <- matrix(1, n, n)
  }
  pop_mat <- matrix(pop, ncol = 1)
  vmax_abs <- (colMaxs(data) - colMins(data)) * vmax_perc
  set.seed(random_seed)
  population <- vector("list", n_agents)
  pbest_solutions <- vector("list", n_agents)
  velocities <- vector("list", n_agents)
  G <- G0 

  for (i in 1:n_agents) {
    initial_v <- gen_vi(data, ncluster, vi_dist, random_seed + i)
    population[[i]] <- evaluate_solution(initial_v, data, m, pop_mat, distmat, alpha, beta, a, b)
    pbest_solutions[[i]] <- population[[i]]
    velocities[[i]] <- matrix(0, nrow = ncluster, ncol = p)
  }

  all_pbest_fitness <- sapply(pbest_solutions, `[[`, "fitness")
  gbest_solution <- pbest_solutions[[which.min(all_pbest_fitness)]]
  
  convergence_history <- c(gbest_solution$fitness)
  no_improve_counter <- 0

  for (iter in 1:max_iter) {
    G <- G * G_decay_rate
    velocities <- gsa_update(population, velocities, G, k_best_perc, vmax_abs, 
                             random_seed + iter)
    for (i in 1:n_agents) {
      trial_pos <- population[[i]]$centroid + velocities[[i]]
      if (use_new_move) {
        trial_pos <- new_move(trial_pos, 
                              pbest_solutions[[i]]$centroid, 
                              gbest_solution$centroid, 
                              random_seed + iter * n_agents + i)
      }
      evaluated_solution <- evaluate_solution(trial_pos, data, m, pop_mat, distmat, alpha, beta, a, b)
      population[[i]] <- evaluated_solution
      if (evaluated_solution$fitness < pbest_solutions[[i]]$fitness) {
        pbest_solutions[[i]] <- evaluated_solution
      }
    }
    all_pbest_fitness <- sapply(pbest_solutions, `[[`, "fitness")
    best_current_idx <- which.min(all_pbest_fitness)
    
    if (all_pbest_fitness[best_current_idx] < gbest_solution$fitness) {
      gbest_solution <- pbest_solutions[[best_current_idx]]
      no_improve_counter <- 0
    } else {
      no_improve_counter <- no_improve_counter + 1
    }
    
    convergence_history <- c(convergence_history, gbest_solution$fitness)
    if (no_improve_counter >= patience) {
      print(paste("Algoritma berhenti pada iterasi", iter))
      break
    }
  } 
  final_data <- determine_cluster(data_original, gbest_solution$membership)
  cluster <- final_data$cluster

  result <- list(
    converg = convergence_history,
    f_obj = gbest_solution$fitness,
    membership = gbest_solution$membership,
    centroid = gbest_solution$centroid,
    validation = index_fgwc(data, cluster, gbest_solution$membership, gbest_solution$centroid, m),
    cluster = cluster,
    finaldata = final_data,
    call = match.call(),
    iteration = iter,
    time = proc.time() - start_time
  )
  class(result) <- "gsafgwc"
  return(result)
}

Menentukan jumlah cluster dengan metode elbow

k_range <- 2:10
fit_results_df <- data.frame()

for(current_k in k_range){
  hasil_fit <- fgwc(
    data = scaled_data,
    pop = pop,
    dist = dist,
    ncluster = current_k,
    m = 2,    
    alpha = 0.7
  )
  
  fit_results_df <- rbind(fit_results_df, data.frame(
    k = current_k,
    cost_function = hasil_fit$f_obj,
    SC_index = hasil_fit$validation$SC
  ))
}

ggplot(fit_results_df, aes(x = k, y = cost_function)) +
  geom_line(color = "red", linewidth = 1) +
  geom_point(color = "blue", size = 1) +
  labs(
    x = "Jumlah Cluster (k)",
    y = "Fungsi Objektif"
  ) +
  scale_x_continuous(breaks = k_range) +
  theme_minimal()

ggplot(fit_results_df, aes(x = k, y = SC_index)) +
  geom_line(color = "red", linewidth = 1) +
  geom_point(color = "blue", size = 1) +
  labs(
    x = "Jumlah Cluster (k)",
    y = "Nilai SC"
  ) +
  scale_x_continuous(breaks = k_range) +
  theme_minimal()

Run Data

hasil_fgwc <- fgwc(scaled_data,pop,dist,ncluster = 3)
hasil_fgwc
## $converg
##  [1] 7.006921 6.870033 6.805852 6.734685 6.660217 6.590374 6.532698 6.490396
##  [9] 6.462104 6.444324 6.433566 6.427194 6.423464 6.421292 6.420030 6.419297
## [17] 6.418871 6.418622 6.418477 6.418391 6.418340 6.418310 6.418291 6.418280
## [25] 6.418273
## 
## $f_obj
## [1] 6.418273
## 
## $membership
##                  [,1]      [,2]      [,3]     
## Bogor            0.2636842 0.3647730 0.3715428
## Sukabumi         0.1562407 0.4286367 0.4151226
## Cianjur          0.1666321 0.4215260 0.4118419
## Bandung          0.1870249 0.4088197 0.4041555
## Garut            0.1696793 0.4207432 0.4095775
## Tasikmalaya      0.1562512 0.4275822 0.4161666
## Ciamis           0.1521173 0.4243819 0.4235008
## Kuningan         0.1638170 0.4163976 0.4197855
## Cirebon          0.2546018 0.3660734 0.3793248
## Majalengka       0.1276130 0.4375843 0.4348027
## Sumedang         0.1226188 0.4432882 0.4340930
## Indramayu        0.2386746 0.3767330 0.3845924
## Subang           0.1896155 0.4020330 0.4083515
## Purwakarta       0.2238906 0.3867992 0.3893102
## Karawang         0.3916126 0.2997880 0.3085994
## Bekasi           0.5834184 0.2061791 0.2104024
## Bandung Barat    0.1585340 0.4275112 0.4139548
## Pangandaran      0.1873895 0.4087681 0.4038424
## Kota Bogor       0.5709609 0.2125458 0.2164933
## Kota Sukabumi    0.5078447 0.2447024 0.2474529
## Kota Bandung     0.4845223 0.2569667 0.2585110
## Kota Cirebon     0.4247869 0.2835191 0.2916941
## Kota Bekasi      0.5918210 0.2026126 0.2055665
## Kota Depok       0.5834527 0.2066647 0.2098826
## Kota Cimahi      0.6332517 0.1828339 0.1839144
## Kota Tasikmalaya 0.1934090 0.4052938 0.4012972
## Kota Banjar      0.1268424 0.4345220 0.4386356
## 
## $centroid
##            TPT     Minum  Stunting      IPLM      NDVI       SO2       RLS
## [1,] 0.8080764 0.8525775 0.1828573 0.5748121 0.3091262 0.5894439 0.6862134
## [2,] 0.6110835 0.5954800 0.2721697 0.4706523 0.7108683 0.2751410 0.2999295
## [3,] 0.6136917 0.6040362 0.2686256 0.4734573 0.7035481 0.2792694 0.3018775
##           Gini       PPP     TPAK       UHH        CO
## [1,] 0.6244241 0.4873771 0.207154 0.6966371 0.6479647
## [2,] 0.3739428 0.2240762 0.356446 0.4256155 0.3768461
## [3,] 0.3759603 0.2284233 0.353410 0.4287365 0.3835149
## 
## $validation
## $validation$PC
## [1] 0.3809776
## 
## $validation$CE
## [1] 1.024315
## 
## $validation$SC
## [1] 0.7657095
## 
## $validation$XB
## [1] 909.8759
## 
## $validation$IFV
## [1] 3.535079
## 
## 
## $iteration
## [1] 25
## 
## $cluster
##  [1] 3 2 2 2 2 2 2 3 3 2 2 3 3 3 1 1 2 2 1 1 1 1 1 1 1 2 3
## 
## $finaldata
##                        TPT      Minum    Stunting      IPLM       NDVI
## Bogor            0.7794317 0.59116022 0.020025840 0.2660496 0.76616915
## Sukabumi         0.7483085 0.27140884 0.476744186 0.4046869 0.96019900
## Cianjur          0.5967524 0.43162983 0.058785530 0.0000000 0.99004975
## Bandung          0.6468200 0.75345304 0.469638243 0.3162662 0.89303483
## Garut            0.7280108 0.00000000 0.650516796 0.2398582 1.00000000
## Tasikmalaya      0.2922869 0.09737569 0.490956072 0.4994092 0.88805970
## Ciamis           0.2422192 0.76312155 0.059431525 0.7489169 0.63432836
## Kuningan         0.8389716 0.86671271 0.289405685 0.5171327 0.91542289
## Cirebon          0.6982409 0.81146409 0.279715762 0.2554155 0.39552239
## Majalengka       0.3288227 0.62223757 0.096899225 0.4881843 0.63184080
## Sumedang         0.6197564 0.75000000 0.369509044 0.4013391 0.93532338
## Indramayu        0.6319350 0.83011050 0.057493540 0.7879086 0.30845771
## Subang           0.6968877 0.91988950 0.000000000 0.2697913 0.71393035
## Purwakarta       0.7794317 0.39019337 0.010981912 0.5196928 0.93283582
## Karawang         0.8741543 0.81906077 0.013565891 0.3637259 0.38557214
## Bekasi           0.9797023 0.78660221 0.006459948 0.3310358 0.29850746
## Bandung Barat    0.6928281 0.26795580 0.216408269 0.3093738 0.92288557
## Pangandaran      0.0000000 0.20649171 0.022609819 0.6413942 0.64925373
## Kota Bogor       0.8863329 0.94889503 0.046511628 0.6650256 0.30845771
## Kota Sukabumi    0.9147497 0.97306630 0.274547804 0.8511225 0.46517413
## Kota Bandung     0.7875507 0.84599448 0.468346253 0.8316266 0.07462687
## Kota Cirebon     0.6373478 0.88812155 0.739018088 1.0000000 0.17412935
## Kota Bekasi      0.8443843 0.93370166 0.083333333 0.2908625 0.00000000
## Kota Depok       0.6346414 1.00000000 0.127906977 0.7282395 0.17412935
## Kota Cimahi      1.0000000 0.98273481 0.074935401 0.6096889 0.12686567
## Kota Tasikmalaya 0.6644114 0.58149171 1.000000000 0.5563214 0.63930348
## Kota Banjar      0.5223275 0.80110497 0.288759690 0.6910201 0.80597015
##                         SO2        RLS      Gini         PPP       TPAK
## Bogor            0.50456323 0.29752066 0.5863874 0.264292981 0.21208666
## Sukabumi         0.43937419 0.08057851 0.2931937 0.086469990 0.40877993
## Cianjur          0.09647979 0.07851240 0.2722513 0.006205493 0.57297605
## Bandung          0.21512386 0.45454545 0.4083770 0.246897253 0.26453820
## Garut            0.23337679 0.18595041 0.1989529 0.020651068 0.49942987
## Tasikmalaya      0.06258149 0.21074380 0.4031414 0.000000000 0.35233751
## Ciamis           0.02607562 0.23760331 0.2094241 0.113936928 0.31698974
## Kuningan         0.23207301 0.19628099 0.4345550 0.147812818 0.18586089
## Cirebon          0.36114733 0.14462810 0.4607330 0.260834181 0.38141391
## Majalengka       0.26727510 0.11983471 0.3560209 0.190946083 0.40250855
## Sumedang         0.13298566 0.36983471 0.2670157 0.266937945 0.37970353
## Indramayu        0.35593220 0.00000000 0.1047120 0.208036623 0.21949829
## Subang           0.20599739 0.10537190 0.1780105 0.297965412 0.52052452
## Purwakarta       0.59582790 0.24586777 0.5863874 0.420549339 0.23033067
## Karawang         0.41329857 0.22727273 0.4712042 0.404577823 0.06214367
## Bekasi           0.59582790 0.58057851 0.4240838 0.359613428 0.14424173
## Bandung Barat    0.13689700 0.26652893 0.5968586 0.062868769 0.32611174
## Pangandaran      0.14080834 0.23760331 0.0000000 0.070091556 1.00000000
## Kota Bogor       1.00000000 0.77685950 1.0000000 0.426144456 0.27194983
## Kota Sukabumi    0.63494133 0.70867769 0.7853403 0.334384537 0.00000000
## Kota Bandung     0.32333768 0.85123967 0.8062827 1.000000000 0.30501710
## Kota Cirebon     0.54367666 0.73966942 0.7225131 0.397151577 0.34036488
## Kota Bekasi      0.60886571 1.00000000 0.7801047 0.794506612 0.17103763
## Kota Depok       0.86962190 0.95867769 0.5863874 0.780773143 0.01767389
## Kota Cimahi      0.68709257 0.94421488 0.6073298 0.438758901 0.22462942
## Kota Tasikmalaya 0.00000000 0.55371901 0.3821990 0.250864700 0.36145952
## Kota Banjar      0.19165580 0.38842975 0.1675393 0.289521872 0.26453820
##                         UHH         CO cluster
## Bogor            0.30890052 0.57252632       3
## Sukabumi         0.29144852 0.29200769       2
## Cianjur          0.09947644 0.28396951       2
## Bandung          0.72251309 0.00000000       2
## Garut            0.32984293 0.02874127       2
## Tasikmalaya      0.00000000 0.15377619       2
## Ciamis           0.43280977 0.24799974       2
## Kuningan         0.72251309 0.26154917       3
## Cirebon          0.46247818 0.60972438       3
## Majalengka       0.16055846 0.37627743       2
## Sumedang         0.53403141 0.27745785       2
## Indramayu        0.41535777 0.64395866       3
## Subang           0.54450262 0.54076588       3
## Purwakarta       0.27923211 0.58125959       3
## Karawang         0.47993019 0.73674735       1
## Bekasi           0.72949389 0.85122786       1
## Bandung Barat    0.51483421 0.28045833       2
## Pangandaran      0.35253054 0.29463949       2
## Kota Bogor       0.75916230 0.74560264       1
## Kota Sukabumi    0.51657941 0.37711989       1
## Kota Bandung     0.86910995 0.42131104       1
## Kota Cirebon     0.51483421 0.64601499       1
## Kota Bekasi      1.00000000 0.96425057       1
## Kota Depok       0.90052356 1.00000000       1
## Kota Cimahi      0.82198953 0.48393440       1
## Kota Tasikmalaya 0.48342059 0.24650447       2
## Kota Banjar      0.28621291 0.44451659       3
## 
## $call
## fgwc(data = scaled_data, pop = pop, distmat = dist, ncluster = 3)
## 
## $time
##    user  system elapsed 
##    0.05    0.00    0.05 
## 
## attr(,"class")
## [1] "fgwc"
hasil_fgwc_abc <-abc_fgwc(scaled_data,pop,dist,ncluster = 3)
## [1] "Algoritma berhenti pada iterasi 27"
hasil_fgwc_abc
## $converg
##  [1] 7.041366 6.866848 6.734375 6.639630 6.639630 6.470356 6.399762 6.399762
##  [9] 6.399762 6.399762 6.399762 6.399762 6.399762 6.399762 6.399762 6.399762
## [17] 6.390170 6.357835 6.357835 6.357835 6.357835 6.357835 6.357835 6.357835
## [25] 6.357835 6.357835 6.357835 6.357835
## 
## $f_obj
## [1] 6.357835
## 
## $membership
##                  [,1]      [,2]      [,3]     
## Bogor            0.3224553 0.2491541 0.4283906
## Sukabumi         0.4538183 0.1445105 0.4016712
## Cianjur          0.4342873 0.1537866 0.4119260
## Bandung          0.4544347 0.1595538 0.3860115
## Garut            0.4413947 0.1594655 0.3991399
## Tasikmalaya      0.4193010 0.1543871 0.4263119
## Ciamis           0.4250551 0.1362101 0.4387348
## Kuningan         0.4900060 0.1202781 0.3897160
## Cirebon          0.3286721 0.2334265 0.4379014
## Majalengka       0.3999898 0.1200985 0.4799117
## Sumedang         0.5097304 0.1020827 0.3881868
## Indramayu        0.3821969 0.2047522 0.4130509
## Subang           0.4290656 0.1531152 0.4178192
## Purwakarta       0.3627566 0.2055514 0.4316920
## Karawang         0.3000523 0.3355001 0.3644476
## Bekasi           0.2053321 0.5515644 0.2431035
## Bandung Barat    0.4101242 0.1559216 0.4339542
## Pangandaran      0.4013156 0.1812754 0.4174090
## Kota Bogor       0.1744664 0.6059578 0.2195758
## Kota Sukabumi    0.2412871 0.4836793 0.2750336
## Kota Bandung     0.2402676 0.5004883 0.2592441
## Kota Cirebon     0.2456915 0.4340689 0.3202396
## Kota Bekasi      0.1716624 0.6293795 0.1989580
## Kota Depok       0.1821628 0.6035354 0.2143017
## Kota Cimahi      0.1668088 0.6528613 0.1803299
## Kota Tasikmalaya 0.3977609 0.1866446 0.4155945
## Kota Banjar      0.4238952 0.1082313 0.4678735
## 
## $centroid
##            TPT     Minum  Stunting      IPLM      NDVI       SO2       RLS
## [1,] 0.6155800 0.5969622 0.2798659 0.4621016 0.7351204 0.2608152 0.2885778
## [2,] 0.8108594 0.8630802 0.1837616 0.5834480 0.2844744 0.6089719 0.7205593
## [3,] 0.6143211 0.6088997 0.2563588 0.4770644 0.6873544 0.2891078 0.2998160
##           Gini       PPP      TPAK       UHH        CO
## [1,] 0.3592671 0.2141009 0.3581582 0.4326458 0.3574136
## [2,] 0.6456776 0.5080921 0.2067738 0.7168557 0.6609066
## [3,] 0.3826383 0.2333157 0.3476317 0.4208524 0.4013125
## 
## $validation
## $validation$PC
## [1] 0.3904484
## 
## $validation$CE
## [1] 1.008636
## 
## $validation$SC
## [1] 0.6425318
## 
## $validation$XB
## [1] 32.60823
## 
## $validation$IFV
## [1] 4.302581
## 
## 
## $cluster
##  [1] 3 1 1 1 1 3 3 1 3 3 1 3 1 3 3 2 3 3 2 2 2 2 2 2 2 3 3
## 
## $finaldata
##                        TPT      Minum    Stunting      IPLM       NDVI
## Bogor            0.7794317 0.59116022 0.020025840 0.2660496 0.76616915
## Sukabumi         0.7483085 0.27140884 0.476744186 0.4046869 0.96019900
## Cianjur          0.5967524 0.43162983 0.058785530 0.0000000 0.99004975
## Bandung          0.6468200 0.75345304 0.469638243 0.3162662 0.89303483
## Garut            0.7280108 0.00000000 0.650516796 0.2398582 1.00000000
## Tasikmalaya      0.2922869 0.09737569 0.490956072 0.4994092 0.88805970
## Ciamis           0.2422192 0.76312155 0.059431525 0.7489169 0.63432836
## Kuningan         0.8389716 0.86671271 0.289405685 0.5171327 0.91542289
## Cirebon          0.6982409 0.81146409 0.279715762 0.2554155 0.39552239
## Majalengka       0.3288227 0.62223757 0.096899225 0.4881843 0.63184080
## Sumedang         0.6197564 0.75000000 0.369509044 0.4013391 0.93532338
## Indramayu        0.6319350 0.83011050 0.057493540 0.7879086 0.30845771
## Subang           0.6968877 0.91988950 0.000000000 0.2697913 0.71393035
## Purwakarta       0.7794317 0.39019337 0.010981912 0.5196928 0.93283582
## Karawang         0.8741543 0.81906077 0.013565891 0.3637259 0.38557214
## Bekasi           0.9797023 0.78660221 0.006459948 0.3310358 0.29850746
## Bandung Barat    0.6928281 0.26795580 0.216408269 0.3093738 0.92288557
## Pangandaran      0.0000000 0.20649171 0.022609819 0.6413942 0.64925373
## Kota Bogor       0.8863329 0.94889503 0.046511628 0.6650256 0.30845771
## Kota Sukabumi    0.9147497 0.97306630 0.274547804 0.8511225 0.46517413
## Kota Bandung     0.7875507 0.84599448 0.468346253 0.8316266 0.07462687
## Kota Cirebon     0.6373478 0.88812155 0.739018088 1.0000000 0.17412935
## Kota Bekasi      0.8443843 0.93370166 0.083333333 0.2908625 0.00000000
## Kota Depok       0.6346414 1.00000000 0.127906977 0.7282395 0.17412935
## Kota Cimahi      1.0000000 0.98273481 0.074935401 0.6096889 0.12686567
## Kota Tasikmalaya 0.6644114 0.58149171 1.000000000 0.5563214 0.63930348
## Kota Banjar      0.5223275 0.80110497 0.288759690 0.6910201 0.80597015
##                         SO2        RLS      Gini         PPP       TPAK
## Bogor            0.50456323 0.29752066 0.5863874 0.264292981 0.21208666
## Sukabumi         0.43937419 0.08057851 0.2931937 0.086469990 0.40877993
## Cianjur          0.09647979 0.07851240 0.2722513 0.006205493 0.57297605
## Bandung          0.21512386 0.45454545 0.4083770 0.246897253 0.26453820
## Garut            0.23337679 0.18595041 0.1989529 0.020651068 0.49942987
## Tasikmalaya      0.06258149 0.21074380 0.4031414 0.000000000 0.35233751
## Ciamis           0.02607562 0.23760331 0.2094241 0.113936928 0.31698974
## Kuningan         0.23207301 0.19628099 0.4345550 0.147812818 0.18586089
## Cirebon          0.36114733 0.14462810 0.4607330 0.260834181 0.38141391
## Majalengka       0.26727510 0.11983471 0.3560209 0.190946083 0.40250855
## Sumedang         0.13298566 0.36983471 0.2670157 0.266937945 0.37970353
## Indramayu        0.35593220 0.00000000 0.1047120 0.208036623 0.21949829
## Subang           0.20599739 0.10537190 0.1780105 0.297965412 0.52052452
## Purwakarta       0.59582790 0.24586777 0.5863874 0.420549339 0.23033067
## Karawang         0.41329857 0.22727273 0.4712042 0.404577823 0.06214367
## Bekasi           0.59582790 0.58057851 0.4240838 0.359613428 0.14424173
## Bandung Barat    0.13689700 0.26652893 0.5968586 0.062868769 0.32611174
## Pangandaran      0.14080834 0.23760331 0.0000000 0.070091556 1.00000000
## Kota Bogor       1.00000000 0.77685950 1.0000000 0.426144456 0.27194983
## Kota Sukabumi    0.63494133 0.70867769 0.7853403 0.334384537 0.00000000
## Kota Bandung     0.32333768 0.85123967 0.8062827 1.000000000 0.30501710
## Kota Cirebon     0.54367666 0.73966942 0.7225131 0.397151577 0.34036488
## Kota Bekasi      0.60886571 1.00000000 0.7801047 0.794506612 0.17103763
## Kota Depok       0.86962190 0.95867769 0.5863874 0.780773143 0.01767389
## Kota Cimahi      0.68709257 0.94421488 0.6073298 0.438758901 0.22462942
## Kota Tasikmalaya 0.00000000 0.55371901 0.3821990 0.250864700 0.36145952
## Kota Banjar      0.19165580 0.38842975 0.1675393 0.289521872 0.26453820
##                         UHH         CO cluster
## Bogor            0.30890052 0.57252632       3
## Sukabumi         0.29144852 0.29200769       1
## Cianjur          0.09947644 0.28396951       1
## Bandung          0.72251309 0.00000000       1
## Garut            0.32984293 0.02874127       1
## Tasikmalaya      0.00000000 0.15377619       3
## Ciamis           0.43280977 0.24799974       3
## Kuningan         0.72251309 0.26154917       1
## Cirebon          0.46247818 0.60972438       3
## Majalengka       0.16055846 0.37627743       3
## Sumedang         0.53403141 0.27745785       1
## Indramayu        0.41535777 0.64395866       3
## Subang           0.54450262 0.54076588       1
## Purwakarta       0.27923211 0.58125959       3
## Karawang         0.47993019 0.73674735       3
## Bekasi           0.72949389 0.85122786       2
## Bandung Barat    0.51483421 0.28045833       3
## Pangandaran      0.35253054 0.29463949       3
## Kota Bogor       0.75916230 0.74560264       2
## Kota Sukabumi    0.51657941 0.37711989       2
## Kota Bandung     0.86910995 0.42131104       2
## Kota Cirebon     0.51483421 0.64601499       2
## Kota Bekasi      1.00000000 0.96425057       2
## Kota Depok       0.90052356 1.00000000       2
## Kota Cimahi      0.82198953 0.48393440       2
## Kota Tasikmalaya 0.48342059 0.24650447       3
## Kota Banjar      0.28621291 0.44451659       3
## 
## $call
## abc_fgwc(data = scaled_data, pop = pop, distmat = dist, ncluster = 3)
## 
## $iteration
## [1] 27
## 
## $time
##    user  system elapsed 
##    0.69    0.02    0.75 
## 
## attr(,"class")
## [1] "abc_fgwc"
hasil_fgwc_pso <- pso_fgwc(scaled_data,pop,dist,ncluster = 3)
## [1] "Algoritma berhenti pada iterasi 17"
hasil_fgwc_pso
## $converg
##  [1] 7.041366 6.906049 6.829764 6.676970 6.442262 6.341654 6.319820 6.314910
##  [9] 6.314910 6.314910 6.314910 6.314910 6.314910 6.314910 6.314910 6.314910
## [17] 6.314910 6.314910
## 
## $f_obj
## [1] 6.31491
## 
## $membership
##                  [,1]      [,2]      [,3]     
## Bogor            0.3287791 0.4175393 0.2536816
## Sukabumi         0.5016264 0.3597985 0.1385750
## Cianjur          0.4796009 0.3726386 0.1477605
## Bandung          0.4256380 0.4043531 0.1700089
## Garut            0.4856157 0.3663422 0.1480422
## Tasikmalaya      0.4983269 0.3675397 0.1341334
## Ciamis           0.4386519 0.4264985 0.1348496
## Kuningan         0.3928998 0.4632817 0.1438185
## Cirebon          0.3068440 0.4627471 0.2304089
## Majalengka       0.4617791 0.4248362 0.1133847
## Sumedang         0.4653115 0.4240938 0.1105946
## Indramayu        0.3492066 0.4347380 0.2160554
## Subang           0.3737219 0.4532271 0.1730511
## Purwakarta       0.3785559 0.4155454 0.2058986
## Karawang         0.2702533 0.3757776 0.3539691
## Bekasi           0.1879065 0.2381744 0.5739191
## Bandung Barat    0.4888355 0.3676770 0.1434875
## Pangandaran      0.4458936 0.3849243 0.1691821
## Kota Bogor       0.1741554 0.2169370 0.6089076
## Kota Sukabumi    0.2374420 0.2743038 0.4882542
## Kota Bandung     0.2389257 0.2598634 0.5012108
## Kota Cirebon     0.2457866 0.3412116 0.4130018
## Kota Bekasi      0.1639679 0.1936349 0.6423973
## Kota Depok       0.1654823 0.1971575 0.6373602
## Kota Cimahi      0.1597137 0.1707554 0.6695310
## Kota Tasikmalaya 0.4251918 0.4031366 0.1716716
## Kota Banjar      0.4122786 0.4763921 0.1113293
## 
## $centroid
##            TPT     Minum  Stunting      IPLM      NDVI       SO2       RLS
## [1,] 0.5938002 0.5461355 0.2885532 0.4560836 0.7485892 0.2518315 0.2808589
## [2,] 0.6284521 0.6433423 0.2562308 0.4830957 0.6776999 0.2925710 0.3029397
## [3,] 0.8149137 0.8700284 0.1744078 0.5797697 0.2808072 0.6142694 0.7235746
##           Gini       PPP      TPAK       UHH        CO
## [1,] 0.3592425 0.1964082 0.3746741 0.4010661 0.3424464
## [2,] 0.3819518 0.2435009 0.3382882 0.4405802 0.4100456
## [3,] 0.6433099 0.5130005 0.2005900 0.7239676 0.6688709
## 
## $validation
## $validation$PC
## [1] 0.3948802
## 
## $validation$CE
## [1] 1.002589
## 
## $validation$SC
## [1] 0.6047965
## 
## $validation$XB
## [1] 7.852392
## 
## $validation$IFV
## [1] 4.934205
## 
## 
## $cluster
##  [1] 2 1 1 1 1 1 1 2 2 1 1 2 2 2 2 3 1 1 3 3 3 3 3 3 3 1 2
## 
## $finaldata
##                        TPT      Minum    Stunting      IPLM       NDVI
## Bogor            0.7794317 0.59116022 0.020025840 0.2660496 0.76616915
## Sukabumi         0.7483085 0.27140884 0.476744186 0.4046869 0.96019900
## Cianjur          0.5967524 0.43162983 0.058785530 0.0000000 0.99004975
## Bandung          0.6468200 0.75345304 0.469638243 0.3162662 0.89303483
## Garut            0.7280108 0.00000000 0.650516796 0.2398582 1.00000000
## Tasikmalaya      0.2922869 0.09737569 0.490956072 0.4994092 0.88805970
## Ciamis           0.2422192 0.76312155 0.059431525 0.7489169 0.63432836
## Kuningan         0.8389716 0.86671271 0.289405685 0.5171327 0.91542289
## Cirebon          0.6982409 0.81146409 0.279715762 0.2554155 0.39552239
## Majalengka       0.3288227 0.62223757 0.096899225 0.4881843 0.63184080
## Sumedang         0.6197564 0.75000000 0.369509044 0.4013391 0.93532338
## Indramayu        0.6319350 0.83011050 0.057493540 0.7879086 0.30845771
## Subang           0.6968877 0.91988950 0.000000000 0.2697913 0.71393035
## Purwakarta       0.7794317 0.39019337 0.010981912 0.5196928 0.93283582
## Karawang         0.8741543 0.81906077 0.013565891 0.3637259 0.38557214
## Bekasi           0.9797023 0.78660221 0.006459948 0.3310358 0.29850746
## Bandung Barat    0.6928281 0.26795580 0.216408269 0.3093738 0.92288557
## Pangandaran      0.0000000 0.20649171 0.022609819 0.6413942 0.64925373
## Kota Bogor       0.8863329 0.94889503 0.046511628 0.6650256 0.30845771
## Kota Sukabumi    0.9147497 0.97306630 0.274547804 0.8511225 0.46517413
## Kota Bandung     0.7875507 0.84599448 0.468346253 0.8316266 0.07462687
## Kota Cirebon     0.6373478 0.88812155 0.739018088 1.0000000 0.17412935
## Kota Bekasi      0.8443843 0.93370166 0.083333333 0.2908625 0.00000000
## Kota Depok       0.6346414 1.00000000 0.127906977 0.7282395 0.17412935
## Kota Cimahi      1.0000000 0.98273481 0.074935401 0.6096889 0.12686567
## Kota Tasikmalaya 0.6644114 0.58149171 1.000000000 0.5563214 0.63930348
## Kota Banjar      0.5223275 0.80110497 0.288759690 0.6910201 0.80597015
##                         SO2        RLS      Gini         PPP       TPAK
## Bogor            0.50456323 0.29752066 0.5863874 0.264292981 0.21208666
## Sukabumi         0.43937419 0.08057851 0.2931937 0.086469990 0.40877993
## Cianjur          0.09647979 0.07851240 0.2722513 0.006205493 0.57297605
## Bandung          0.21512386 0.45454545 0.4083770 0.246897253 0.26453820
## Garut            0.23337679 0.18595041 0.1989529 0.020651068 0.49942987
## Tasikmalaya      0.06258149 0.21074380 0.4031414 0.000000000 0.35233751
## Ciamis           0.02607562 0.23760331 0.2094241 0.113936928 0.31698974
## Kuningan         0.23207301 0.19628099 0.4345550 0.147812818 0.18586089
## Cirebon          0.36114733 0.14462810 0.4607330 0.260834181 0.38141391
## Majalengka       0.26727510 0.11983471 0.3560209 0.190946083 0.40250855
## Sumedang         0.13298566 0.36983471 0.2670157 0.266937945 0.37970353
## Indramayu        0.35593220 0.00000000 0.1047120 0.208036623 0.21949829
## Subang           0.20599739 0.10537190 0.1780105 0.297965412 0.52052452
## Purwakarta       0.59582790 0.24586777 0.5863874 0.420549339 0.23033067
## Karawang         0.41329857 0.22727273 0.4712042 0.404577823 0.06214367
## Bekasi           0.59582790 0.58057851 0.4240838 0.359613428 0.14424173
## Bandung Barat    0.13689700 0.26652893 0.5968586 0.062868769 0.32611174
## Pangandaran      0.14080834 0.23760331 0.0000000 0.070091556 1.00000000
## Kota Bogor       1.00000000 0.77685950 1.0000000 0.426144456 0.27194983
## Kota Sukabumi    0.63494133 0.70867769 0.7853403 0.334384537 0.00000000
## Kota Bandung     0.32333768 0.85123967 0.8062827 1.000000000 0.30501710
## Kota Cirebon     0.54367666 0.73966942 0.7225131 0.397151577 0.34036488
## Kota Bekasi      0.60886571 1.00000000 0.7801047 0.794506612 0.17103763
## Kota Depok       0.86962190 0.95867769 0.5863874 0.780773143 0.01767389
## Kota Cimahi      0.68709257 0.94421488 0.6073298 0.438758901 0.22462942
## Kota Tasikmalaya 0.00000000 0.55371901 0.3821990 0.250864700 0.36145952
## Kota Banjar      0.19165580 0.38842975 0.1675393 0.289521872 0.26453820
##                         UHH         CO cluster
## Bogor            0.30890052 0.57252632       2
## Sukabumi         0.29144852 0.29200769       1
## Cianjur          0.09947644 0.28396951       1
## Bandung          0.72251309 0.00000000       1
## Garut            0.32984293 0.02874127       1
## Tasikmalaya      0.00000000 0.15377619       1
## Ciamis           0.43280977 0.24799974       1
## Kuningan         0.72251309 0.26154917       2
## Cirebon          0.46247818 0.60972438       2
## Majalengka       0.16055846 0.37627743       1
## Sumedang         0.53403141 0.27745785       1
## Indramayu        0.41535777 0.64395866       2
## Subang           0.54450262 0.54076588       2
## Purwakarta       0.27923211 0.58125959       2
## Karawang         0.47993019 0.73674735       2
## Bekasi           0.72949389 0.85122786       3
## Bandung Barat    0.51483421 0.28045833       1
## Pangandaran      0.35253054 0.29463949       1
## Kota Bogor       0.75916230 0.74560264       3
## Kota Sukabumi    0.51657941 0.37711989       3
## Kota Bandung     0.86910995 0.42131104       3
## Kota Cirebon     0.51483421 0.64601499       3
## Kota Bekasi      1.00000000 0.96425057       3
## Kota Depok       0.90052356 1.00000000       3
## Kota Cimahi      0.82198953 0.48393440       3
## Kota Tasikmalaya 0.48342059 0.24650447       1
## Kota Banjar      0.28621291 0.44451659       2
## 
## $call
## pso_fgwc(data = scaled_data, pop = pop, distmat = dist, ncluster = 3)
## 
## $iteration
## [1] 17
## 
## $time
##    user  system elapsed 
##    0.33    0.00    0.34 
## 
## attr(,"class")
## [1] "psofgwc"
hasil_fgwc_gsa <- gsa_fgwc(scaled_data,pop,dist,ncluster = 3)
## [1] "Algoritma berhenti pada iterasi 13"
hasil_fgwc_gsa
## $converg
##  [1] 7.041366 6.423294 6.285707 6.263247 6.263247 6.263247 6.263247 6.263247
##  [9] 6.263247 6.263247 6.263247 6.263247 6.263247 6.263247
## 
## $f_obj
## [1] 6.263247
## 
## $membership
##                  [,1]      [,2]      [,3]     
## Bogor            0.2897220 0.4499141 0.2603639
## Sukabumi         0.4441530 0.4278783 0.1279686
## Cianjur          0.3506553 0.5218441 0.1275006
## Bandung          0.5708611 0.2822482 0.1468907
## Garut            0.5099842 0.3651109 0.1249049
## Tasikmalaya      0.4603231 0.4247816 0.1148953
## Ciamis           0.3899541 0.4855633 0.1244827
## Kuningan         0.4764663 0.3865907 0.1369430
## Cirebon          0.3376004 0.4228997 0.2394998
## Majalengka       0.2567834 0.6464266 0.0967900
## Sumedang         0.5932041 0.3060463 0.1007496
## Indramayu        0.3257656 0.4614823 0.2127521
## Subang           0.3248220 0.5117137 0.1634643
## Purwakarta       0.3323702 0.4693833 0.1982465
## Karawang         0.2820874 0.3622336 0.3556789
## Bekasi           0.2024110 0.2248547 0.5727344
## Bandung Barat    0.4746960 0.3925499 0.1327541
## Pangandaran      0.3901214 0.4600384 0.1498403
## Kota Bogor       0.1501886 0.1951375 0.6546739
## Kota Sukabumi    0.2590762 0.2490160 0.4919077
## Kota Bandung     0.2606518 0.2161296 0.5232186
## Kota Cirebon     0.2860998 0.2880537 0.4258465
## Kota Bekasi      0.1439021 0.1557558 0.7003421
## Kota Depok       0.1377036 0.1605087 0.7017877
## Kota Cimahi      0.1594580 0.1412422 0.6992998
## Kota Tasikmalaya 0.5645748 0.2968792 0.1385459
## Kota Banjar      0.4230612 0.4652077 0.1117311
## 
## $centroid
##            TPT     Minum  Stunting      IPLM      NDVI       SO2       RLS
## [1,] 0.6250812 0.5779886 0.3537504 0.4640468 0.7516641 0.2394950 0.3200836
## [2,] 0.5862775 0.6008181 0.2055456 0.4664728 0.6980001 0.2829156 0.2513822
## [3,] 0.8184625 0.8843256 0.1678602 0.5841680 0.2600921 0.6331987 0.7468755
##           Gini       PPP      TPAK       UHH        CO
## [1,] 0.3691671 0.2118664 0.3535746 0.4511055 0.3195951
## [2,] 0.3580083 0.2149461 0.3678328 0.3808396 0.4081696
## [3,] 0.6576993 0.5322471 0.1936345 0.7416174 0.6882314
## 
## $validation
## $validation$PC
## [1] 0.4150499
## 
## $validation$CE
## [1] 0.9738845
## 
## $validation$SC
## [1] 0.4889137
## 
## $validation$XB
## [1] 4.977669
## 
## $validation$IFV
## [1] 5.322647
## 
## 
## $cluster
##  [1] 2 1 2 1 1 1 2 1 2 2 1 2 2 2 2 3 1 2 3 3 3 3 3 3 3 1 2
## 
## $finaldata
##                        TPT      Minum    Stunting      IPLM       NDVI
## Bogor            0.7794317 0.59116022 0.020025840 0.2660496 0.76616915
## Sukabumi         0.7483085 0.27140884 0.476744186 0.4046869 0.96019900
## Cianjur          0.5967524 0.43162983 0.058785530 0.0000000 0.99004975
## Bandung          0.6468200 0.75345304 0.469638243 0.3162662 0.89303483
## Garut            0.7280108 0.00000000 0.650516796 0.2398582 1.00000000
## Tasikmalaya      0.2922869 0.09737569 0.490956072 0.4994092 0.88805970
## Ciamis           0.2422192 0.76312155 0.059431525 0.7489169 0.63432836
## Kuningan         0.8389716 0.86671271 0.289405685 0.5171327 0.91542289
## Cirebon          0.6982409 0.81146409 0.279715762 0.2554155 0.39552239
## Majalengka       0.3288227 0.62223757 0.096899225 0.4881843 0.63184080
## Sumedang         0.6197564 0.75000000 0.369509044 0.4013391 0.93532338
## Indramayu        0.6319350 0.83011050 0.057493540 0.7879086 0.30845771
## Subang           0.6968877 0.91988950 0.000000000 0.2697913 0.71393035
## Purwakarta       0.7794317 0.39019337 0.010981912 0.5196928 0.93283582
## Karawang         0.8741543 0.81906077 0.013565891 0.3637259 0.38557214
## Bekasi           0.9797023 0.78660221 0.006459948 0.3310358 0.29850746
## Bandung Barat    0.6928281 0.26795580 0.216408269 0.3093738 0.92288557
## Pangandaran      0.0000000 0.20649171 0.022609819 0.6413942 0.64925373
## Kota Bogor       0.8863329 0.94889503 0.046511628 0.6650256 0.30845771
## Kota Sukabumi    0.9147497 0.97306630 0.274547804 0.8511225 0.46517413
## Kota Bandung     0.7875507 0.84599448 0.468346253 0.8316266 0.07462687
## Kota Cirebon     0.6373478 0.88812155 0.739018088 1.0000000 0.17412935
## Kota Bekasi      0.8443843 0.93370166 0.083333333 0.2908625 0.00000000
## Kota Depok       0.6346414 1.00000000 0.127906977 0.7282395 0.17412935
## Kota Cimahi      1.0000000 0.98273481 0.074935401 0.6096889 0.12686567
## Kota Tasikmalaya 0.6644114 0.58149171 1.000000000 0.5563214 0.63930348
## Kota Banjar      0.5223275 0.80110497 0.288759690 0.6910201 0.80597015
##                         SO2        RLS      Gini         PPP       TPAK
## Bogor            0.50456323 0.29752066 0.5863874 0.264292981 0.21208666
## Sukabumi         0.43937419 0.08057851 0.2931937 0.086469990 0.40877993
## Cianjur          0.09647979 0.07851240 0.2722513 0.006205493 0.57297605
## Bandung          0.21512386 0.45454545 0.4083770 0.246897253 0.26453820
## Garut            0.23337679 0.18595041 0.1989529 0.020651068 0.49942987
## Tasikmalaya      0.06258149 0.21074380 0.4031414 0.000000000 0.35233751
## Ciamis           0.02607562 0.23760331 0.2094241 0.113936928 0.31698974
## Kuningan         0.23207301 0.19628099 0.4345550 0.147812818 0.18586089
## Cirebon          0.36114733 0.14462810 0.4607330 0.260834181 0.38141391
## Majalengka       0.26727510 0.11983471 0.3560209 0.190946083 0.40250855
## Sumedang         0.13298566 0.36983471 0.2670157 0.266937945 0.37970353
## Indramayu        0.35593220 0.00000000 0.1047120 0.208036623 0.21949829
## Subang           0.20599739 0.10537190 0.1780105 0.297965412 0.52052452
## Purwakarta       0.59582790 0.24586777 0.5863874 0.420549339 0.23033067
## Karawang         0.41329857 0.22727273 0.4712042 0.404577823 0.06214367
## Bekasi           0.59582790 0.58057851 0.4240838 0.359613428 0.14424173
## Bandung Barat    0.13689700 0.26652893 0.5968586 0.062868769 0.32611174
## Pangandaran      0.14080834 0.23760331 0.0000000 0.070091556 1.00000000
## Kota Bogor       1.00000000 0.77685950 1.0000000 0.426144456 0.27194983
## Kota Sukabumi    0.63494133 0.70867769 0.7853403 0.334384537 0.00000000
## Kota Bandung     0.32333768 0.85123967 0.8062827 1.000000000 0.30501710
## Kota Cirebon     0.54367666 0.73966942 0.7225131 0.397151577 0.34036488
## Kota Bekasi      0.60886571 1.00000000 0.7801047 0.794506612 0.17103763
## Kota Depok       0.86962190 0.95867769 0.5863874 0.780773143 0.01767389
## Kota Cimahi      0.68709257 0.94421488 0.6073298 0.438758901 0.22462942
## Kota Tasikmalaya 0.00000000 0.55371901 0.3821990 0.250864700 0.36145952
## Kota Banjar      0.19165580 0.38842975 0.1675393 0.289521872 0.26453820
##                         UHH         CO cluster
## Bogor            0.30890052 0.57252632       2
## Sukabumi         0.29144852 0.29200769       1
## Cianjur          0.09947644 0.28396951       2
## Bandung          0.72251309 0.00000000       1
## Garut            0.32984293 0.02874127       1
## Tasikmalaya      0.00000000 0.15377619       1
## Ciamis           0.43280977 0.24799974       2
## Kuningan         0.72251309 0.26154917       1
## Cirebon          0.46247818 0.60972438       2
## Majalengka       0.16055846 0.37627743       2
## Sumedang         0.53403141 0.27745785       1
## Indramayu        0.41535777 0.64395866       2
## Subang           0.54450262 0.54076588       2
## Purwakarta       0.27923211 0.58125959       2
## Karawang         0.47993019 0.73674735       2
## Bekasi           0.72949389 0.85122786       3
## Bandung Barat    0.51483421 0.28045833       1
## Pangandaran      0.35253054 0.29463949       2
## Kota Bogor       0.75916230 0.74560264       3
## Kota Sukabumi    0.51657941 0.37711989       3
## Kota Bandung     0.86910995 0.42131104       3
## Kota Cirebon     0.51483421 0.64601499       3
## Kota Bekasi      1.00000000 0.96425057       3
## Kota Depok       0.90052356 1.00000000       3
## Kota Cimahi      0.82198953 0.48393440       3
## Kota Tasikmalaya 0.48342059 0.24650447       1
## Kota Banjar      0.28621291 0.44451659       2
## 
## $call
## gsa_fgwc(data = scaled_data, pop = pop, distmat = dist, ncluster = 3)
## 
## $iteration
## [1] 13
## 
## $time
##    user  system elapsed 
##    0.25    0.00    0.25 
## 
## attr(,"class")
## [1] "gsafgwc"

Ringkasan hasil evaluasi

hasil_eval <- data.frame(
  Metode = c("FGWC", "FGWC + ABC", "FGWC + PSO", "FGWC + GSA"),
  fungsi_Objektif = c(
    hasil_fgwc$f_obj,
    hasil_fgwc_abc$f_obj,
    hasil_fgwc_pso$f_obj,
    hasil_fgwc_gsa$f_obj
  ),
  PC = c(
    hasil_fgwc$validation$PC,
    hasil_fgwc_abc$validation$PC,
    hasil_fgwc_pso$validation$PC,
    hasil_fgwc_gsa$validation$PC
  ),
  CE = c(
    hasil_fgwc$validation$CE,
    hasil_fgwc_abc$validation$CE,
    hasil_fgwc_pso$validation$CE,
    hasil_fgwc_gsa$validation$CE
  ),
  SC = c(
    hasil_fgwc$validation$SC,
    hasil_fgwc_abc$validation$SC,
    hasil_fgwc_pso$validation$SC,
    hasil_fgwc_gsa$validation$SC
  ),
  XB = c(
    hasil_fgwc$validation$XB,
    hasil_fgwc_abc$validation$XB,
    hasil_fgwc_pso$validation$XB,
    hasil_fgwc_gsa$validation$XB
  ),
  IFV = c(
    hasil_fgwc$validation$IFV,
    hasil_fgwc_abc$validation$IFV,
    hasil_fgwc_pso$validation$IFV,
    hasil_fgwc_gsa$validation$IFV
  ),
  Iterasi = c(
     hasil_fgwc$iteration,
    hasil_fgwc_abc$iteration,
    hasil_fgwc_pso$iteration,
    hasil_fgwc_gsa$iteration
  )
)
print(hasil_eval)
##       Metode fungsi_Objektif        PC        CE        SC         XB      IFV
## 1       FGWC        6.418273 0.3809776 1.0243155 0.7657095 909.875910 3.535079
## 2 FGWC + ABC        6.357835 0.3904484 1.0086363 0.6425318  32.608232 4.302581
## 3 FGWC + PSO        6.314910 0.3948802 1.0025888 0.6047965   7.852392 4.934205
## 4 FGWC + GSA        6.263247 0.4150499 0.9738845 0.4889137   4.977669 5.322647
##   Iterasi
## 1      25
## 2      27
## 3      17
## 4      13
# Simpan cluster
data$cluster <- as.factor(hasil_fgwc_gsa$cluster)
head(data)

Unscale

numeric_data <- data[, sapply(data, is.numeric)]
min_vals <- apply(numeric_data, 2, min)
max_vals <- apply(numeric_data, 2, max)
centroids <- sweep(hasil_fgwc_gsa$centroid, 2, max_vals - min_vals, FUN = "*")
centroids <- sweep(centroids, 2, min_vals, FUN = "+")
print(centroids)
##           TPT    Minum Stunting     IPLM      NDVI          SO2       RLS
## [1,] 6.199350 93.73927 7.076056 68.15430 0.5621690 8.866926e-05  8.499205
## [2,] 5.912591 94.06985 4.781845 68.27749 0.5405961 9.199963e-05  8.166690
## [3,] 7.628438 98.17503 4.198475 74.25405 0.3645570 1.188663e-04 10.564878
##           Gini      PPP     TPAK      UHH         CO
## [1,] 0.3565109 11047.65 68.78170 72.97483 0.03026258
## [2,] 0.3543796 11077.92 69.03179 72.57221 0.03107341
## [3,] 0.4116206 14196.99 65.97635 74.63947 0.03363715

Uji Beda Kruskal Wallis

variables <- c("TPT","PPP","TPAK", "Gini","Stunting","UHH", "Minum", "RLS", "IPLM", "NDVI", "SO2","CO")
hasil_kruskal <- list()
for(variable in variables){
  formula <- as.formula(paste(variable,'~ cluster'))
  hasil_tes <- kruskal.test(formula, data = data)
  hasil_kruskal[[variable]] <- hasil_tes
}
for(variable in names(hasil_kruskal)){
  print(hasil_kruskal[[variable]])
}
## 
##  Kruskal-Wallis rank sum test
## 
## data:  TPT by cluster
## Kruskal-Wallis chi-squared = 7.6436, df = 2, p-value = 0.02189
## 
## 
##  Kruskal-Wallis rank sum test
## 
## data:  PPP by cluster
## Kruskal-Wallis chi-squared = 15.555, df = 2, p-value = 0.0004191
## 
## 
##  Kruskal-Wallis rank sum test
## 
## data:  TPAK by cluster
## Kruskal-Wallis chi-squared = 6.3421, df = 2, p-value = 0.04196
## 
## 
##  Kruskal-Wallis rank sum test
## 
## data:  Gini by cluster
## Kruskal-Wallis chi-squared = 13.372, df = 2, p-value = 0.001248
## 
## 
##  Kruskal-Wallis rank sum test
## 
## data:  Stunting by cluster
## Kruskal-Wallis chi-squared = 13.088, df = 2, p-value = 0.001439
## 
## 
##  Kruskal-Wallis rank sum test
## 
## data:  UHH by cluster
## Kruskal-Wallis chi-squared = 14.215, df = 2, p-value = 0.0008188
## 
## 
##  Kruskal-Wallis rank sum test
## 
## data:  Minum by cluster
## Kruskal-Wallis chi-squared = 14.138, df = 2, p-value = 0.000851
## 
## 
##  Kruskal-Wallis rank sum test
## 
## data:  RLS by cluster
## Kruskal-Wallis chi-squared = 16.963, df = 2, p-value = 0.0002073
## 
## 
##  Kruskal-Wallis rank sum test
## 
## data:  IPLM by cluster
## Kruskal-Wallis chi-squared = 5.0013, df = 2, p-value = 0.08203
## 
## 
##  Kruskal-Wallis rank sum test
## 
## data:  NDVI by cluster
## Kruskal-Wallis chi-squared = 17.808, df = 2, p-value = 0.0001358
## 
## 
##  Kruskal-Wallis rank sum test
## 
## data:  SO2 by cluster
## Kruskal-Wallis chi-squared = 14.243, df = 2, p-value = 0.0008074
## 
## 
##  Kruskal-Wallis rank sum test
## 
## data:  CO by cluster
## Kruskal-Wallis chi-squared = 16.373, df = 2, p-value = 0.0002783

Visualisasi

# Jumlah klaster
jumlah_klaster <- nrow(hasil_fgwc_gsa$centroid)

# Indikator Ekonomi
indikator_ekonomi <- data.frame(
  TPT = hasil_fgwc_gsa$centroid[, "TPT"],
  Gini = hasil_fgwc_gsa$centroid[, "Gini"],
  PPP = hasil_fgwc_gsa$centroid[, "PPP"],
  TPAK = hasil_fgwc_gsa$centroid[, "TPAK"]
)

# Indikator Kesehatan dan pendidikan
indikator_kesehatan_pendidikan <- data.frame(
  Minum = hasil_fgwc_gsa$centroid[, "Minum"],
  Stunting =hasil_fgwc_gsa$centroid[, "Stunting"],
  UHH = hasil_fgwc_gsa$centroid[, "UHH"],
  RLS = hasil_fgwc_gsa$centroid[, "RLS"],
  IPLM = hasil_fgwc_gsa$centroid[, "IPLM"]
)

# Citra Satelit
indikator_lingkungan <- data.frame(
  NDVI = hasil_fgwc_gsa$centroid[,"NDVI"],
  SO2 = hasil_fgwc_gsa$centroid[,"SO2"],
  CO = hasil_fgwc_gsa$centroid[,"CO"]
)

# Atur nama klaster
rownames(indikator_ekonomi) <- paste("Klaster", 1:jumlah_klaster)
rownames(indikator_kesehatan_pendidikan) <- paste("Klaster", 1:jumlah_klaster)
rownames(indikator_lingkungan) <- paste("Klaster", 1:jumlah_klaster)
warna_klaster <- c("#4C78A8", "#e7298a","#54A24B")

# Normalisasi ke skala 0–1
normalize <- function(x) (x - min(x)) / (max(x) - min(x))
indikator_ekonomi_norm <- as.data.frame(lapply(indikator_ekonomi, normalize))
indikator_kesehatan_pendidikan_norm <- as.data.frame(lapply(indikator_kesehatan_pendidikan, normalize))
indikator_lingkungan_norm <- as.data.frame(lapply(indikator_lingkungan, normalize))

# Tambahkan baris max-min
indikator_ekonomi_plot <- rbind(
  max = rep(1, ncol(indikator_ekonomi_norm)),
  min = rep(0, ncol(indikator_ekonomi_norm)),
  indikator_ekonomi_norm
)

indikator_kesehatan_pendidikan_plot <- rbind(
  max = rep(1, ncol(indikator_kesehatan_pendidikan_norm)),
  min = rep(0, ncol(indikator_kesehatan_pendidikan_norm)),
  indikator_kesehatan_pendidikan_norm
)

indikator_lingkungan_plot <- rbind(
  max = rep(1, ncol(indikator_lingkungan_norm)),
  min = rep(0, ncol(indikator_lingkungan_norm)),
  indikator_lingkungan_norm
)

# Spider chart Ekonomi
par(mar = c(1, 2, 3, 1))  
radarchart(indikator_ekonomi_plot,
           axistype = 0, 
           pcol = warna_klaster,
           pfcol = alpha(warna_klaster, 0.4),
           plwd = 2,
           plty = 1,
           cglcol = "grey80",
           cglty = 1,
           cglwd = 1,
           vlcex = 1.3,
           title = "Indikator Ekonomi")

# Spider chart Kesehatan dan pendidikan
par(mar = c(1, 2, 3, 1))
radarchart(indikator_kesehatan_pendidikan_plot,
           axistype = 0,
           pcol = warna_klaster,
           pfcol = alpha(warna_klaster, 0.4),
           plwd = 2,
           plty = 1,
           cglcol = "grey80",
           cglty = 1,
           cglwd = 1,
           vlcex = 1.3,
           title = "Indikator Kesehatan dan Pendidikan")

# Spider chart lingkungan
par(mar = c(1, 2, 3, 1))  
radarchart(indikator_lingkungan_plot,
           axistype = 0,
           pcol = warna_klaster,
           pfcol = alpha(warna_klaster, 0.4),
           plwd = 2,
           plty = 1,
           cglcol = "grey80",
           cglty = 1,
           cglwd = 1,
           vlcex = 1.3,
           title = "Indikator Lingkungan")
legend("topright", legend = rownames(indikator_lingkungan),
       col = warna_klaster, lty = 1, lwd = 3,
       bty = "n", cex = 1.2)