package com.ruoyi.buss;
|
|
import java.util.*;
|
|
class Port {
|
String name;
|
int berths;
|
int supplyCapacity;
|
int x, y; // Coordinates for distance calculation
|
|
public Port(String name, int berths, int supplyCapacity, int x, int y) {
|
this.name = name;
|
this.berths = berths;
|
this.supplyCapacity = supplyCapacity;
|
this.x = x;
|
this.y = y;
|
}
|
}
|
|
class Ship {
|
String name;
|
int supplyNeed;
|
int x, y; // Current coordinates
|
|
public Ship(String name, int supplyNeed, int x, int y) {
|
this.name = name;
|
this.supplyNeed = supplyNeed;
|
this.x = x;
|
this.y = y;
|
}
|
}
|
|
class Assignment {
|
List<Integer> assignments; // Index of port for each ship
|
double fitness;
|
|
public Assignment(List<Integer> assignments) {
|
this.assignments = assignments;
|
this.fitness = 0.0;
|
}
|
}
|
|
public class GeneticFleetAssignment {
|
|
private static final int POPULATION_SIZE = 50;
|
private static final int GENERATIONS = 100;
|
private static final double MUTATION_RATE = 0.1;
|
|
public static double calculateDistance(Ship ship, Port port) {
|
return Math.sqrt(Math.pow(ship.x - port.x, 2) + Math.pow(ship.y - port.y, 2));
|
}
|
|
public static double evaluateFitness(Assignment assignment, List<Ship> ships, List<Port> ports) {
|
double totalDistance = 0.0;
|
int[] portBerths = new int[ports.size()];
|
int[] portSupply = new int[ports.size()];
|
|
for (int i = 0; i < assignment.assignments.size(); i++) {
|
int portIndex = assignment.assignments.get(i);
|
Ship ship = ships.get(i);
|
Port port = ports.get(portIndex);
|
|
totalDistance += calculateDistance(ship, port);
|
portBerths[portIndex]++;
|
portSupply[portIndex] += ship.supplyNeed;
|
}
|
|
for (int i = 0; i < ports.size(); i++) {
|
if (portBerths[i] > ports.get(i).berths || portSupply[i] > ports.get(i).supplyCapacity) {
|
return Double.MAX_VALUE; // Invalid assignment
|
}
|
}
|
|
return totalDistance;
|
}
|
|
public static Assignment crossover(Assignment parent1, Assignment parent2) {
|
Random rand = new Random();
|
int crossoverPoint = rand.nextInt(parent1.assignments.size());
|
List<Integer> childAssignments = new ArrayList<>(parent1.assignments.subList(0, crossoverPoint));
|
childAssignments.addAll(parent2.assignments.subList(crossoverPoint, parent2.assignments.size()));
|
return new Assignment(childAssignments);
|
}
|
|
public static void mutate(Assignment assignment, int numPorts) {
|
Random rand = new Random();
|
if (rand.nextDouble() < MUTATION_RATE) {
|
int index = rand.nextInt(assignment.assignments.size());
|
assignment.assignments.set(index, rand.nextInt(numPorts));
|
}
|
}
|
|
public static Assignment geneticAlgorithm(List<Ship> ships, List<Port> ports) {
|
Random rand = new Random();
|
List<Assignment> population = new ArrayList<>();
|
|
// Initialize population
|
for (int i = 0; i < POPULATION_SIZE; i++) {
|
List<Integer> assignments = new ArrayList<>();
|
for (int j = 0; j < ships.size(); j++) {
|
assignments.add(rand.nextInt(ports.size()));
|
}
|
population.add(new Assignment(assignments));
|
}
|
|
for (int generation = 0; generation < GENERATIONS; generation++) {
|
// Evaluate fitness
|
for (Assignment assignment : population) {
|
assignment.fitness = evaluateFitness(assignment, ships, ports);
|
}
|
|
// Sort by fitness
|
population.sort(Comparator.comparingDouble(a -> a.fitness));
|
|
// Selection and reproduction
|
List<Assignment> newPopulation = new ArrayList<>();
|
for (int i = 0; i < POPULATION_SIZE / 2; i++) {
|
Assignment parent1 = population.get(i);
|
Assignment parent2 = population.get(rand.nextInt(POPULATION_SIZE / 2));
|
Assignment child = crossover(parent1, parent2);
|
mutate(child, ports.size());
|
newPopulation.add(child);
|
}
|
|
population = newPopulation;
|
}
|
|
// Return the best solution
|
return population.get(0);
|
}
|
|
public static void main(String[] args) {
|
List<Port> ports = Arrays.asList(
|
new Port("Port A", 2, 100, 0, 0),
|
new Port("Port B", 1, 50, 5, 5),
|
new Port("Port C", 3, 150, 10, 10)
|
);
|
|
List<Ship> ships = Arrays.asList(
|
new Ship("Ship 1", 30, 0, 0),
|
new Ship("Ship 2", 70, 0, 0),
|
new Ship("Ship 3", 50, 9, 9)
|
);
|
|
Assignment bestAssignment = geneticAlgorithm(ships, ports);
|
|
for (int i = 0; i < ships.size(); i++) {
|
System.out.println("Ship " + ships.get(i).name + " assigned to port " + ports.get(bestAssignment.assignments.get(i)).name);
|
}
|
}
|
}
|