You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Java的遗传算法家电调度项目技术求助

Hey there! Let's break down how you can tackle this Java-based genetic algorithm (GA) project for home appliance scheduling—no need to feel overwhelmed, we'll take it step by step.

Step 1: Map Your Project to Core Genetic Algorithm Concepts

First, let's translate your project requirements into standard GA terminology, since you're new to this:

  • Chromosome: This is your n×m binary matrix. n = number of appliances, m = 48 time slots. Each 0 means the appliance is off in that slot, 1 means it's on.
  • Fitness Function: The heart of your GA—we need to calculate the total cost of a schedule, then invert it (since GA favors higher fitness values). The formula:

    Total Cost = Sum over all 48 slots of (Slot Price × Total Running Power in Slot × Slot Duration)
    Fitness = 1 / (Total Cost + 1) // +1 avoids division by zero if all appliances are off

  • Selection: Pick the "best" chromosomes (lowest cost) to breed the next generation. Tournament selection is easy to implement and works well here.
  • Crossover: Combine two parent chromosomes to create a child. For your matrix, a single-point crossover (split the time slots at a random index) is straightforward.
  • Mutation: Randomly flip a small number of bits (0→1 or 1→0) to avoid getting stuck in local optima. Keep the mutation rate low (e.g., 0.01).
Step 2: Java Project Structure (Clean & Maintainable)

Split your code into dedicated classes to keep things organized:

  • Appliance: Stores basic info like name and power consumption.
  • Chromosome: Encapsulates the binary matrix and fitness calculation.
  • GeneticAlgorithm: Handles selection, crossover, mutation, and population evolution.
  • Main: Entry point to initialize parameters, run the GA, and output results.
Step 3: Key Code Snippets

Let's write the core parts with comments to explain what's happening:

Appliance Class

public class Appliance {
    private String name;
    private double power; // Unit: kW

    public Appliance(String name, double power) {
        this.name = name;
        this.power = power;
    }

    // Getter for power (used to calculate cost)
    public double getPower() {
        return power;
    }

    public String getName() {
        return name;
    }
}

Chromosome Class

import java.util.Random;

public class Chromosome {
    private boolean[][] genes; // [appliance index][time slot index]
    private double fitness;
    private Appliance[] appliances;
    private double[] slotPrices; // 48 time slot prices (yuan/kWh)
    private static final double SLOT_DURATION = 0.5; // Assume 30-minute slots (0.5 hours)

    // Initialize random chromosome
    public Chromosome(Appliance[] appliances, double[] slotPrices) {
        this.appliances = appliances;
        this.slotPrices = slotPrices;
        this.genes = new boolean[appliances.length][slotPrices.length];
        
        Random rand = new Random();
        for (int app = 0; app < appliances.length; app++) {
            for (int slot = 0; slot < slotPrices.length; slot++) {
                genes[app][slot] = rand.nextBoolean();
            }
        }
        calculateFitness();
    }

    // Calculate fitness based on total cost
    private void calculateFitness() {
        double totalCost = 0.0;
        for (int slot = 0; slot < slotPrices.length; slot++) {
            double totalPower = 0.0;
            // Sum power of all running appliances in this slot
            for (int app = 0; app < appliances.length; app++) {
                if (genes[app][slot]) {
                    totalPower += appliances[app].getPower();
                }
            }
            // Add cost for this slot
            totalCost += slotPrices[slot] * totalPower * SLOT_DURATION;
        }
        // Convert cost to fitness (lower cost = higher fitness)
        this.fitness = 1 / (totalCost + 1);
    }

    // Getters and helper to update fitness after modifying genes
    public boolean[][] getGenes() {
        return genes;
    }

    public double getFitness() {
        return fitness;
    }

    public void updateFitness() {
        calculateFitness();
    }
}

GeneticAlgorithm Class

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Random;

public class GeneticAlgorithm {
    private ArrayList<Chromosome> population;
    private Appliance[] appliances;
    private double[] slotPrices;
    private int populationSize;
    private double crossoverRate;
    private double mutationRate;
    private Random rand;

    public GeneticAlgorithm(Appliance[] appliances, double[] slotPrices, int populationSize, double crossoverRate, double mutationRate) {
        this.appliances = appliances;
        this.slotPrices = slotPrices;
        this.populationSize = populationSize;
        this.crossoverRate = crossoverRate;
        this.mutationRate = mutationRate;
        this.rand = new Random();
        this.population = new ArrayList<>();

        // Initialize population with random chromosomes
        for (int i = 0; i < populationSize; i++) {
            population.add(new Chromosome(appliances, slotPrices));
        }
    }

    // Tournament selection: pick 3 random chromosomes, return the best one
    private Chromosome tournamentSelection() {
        ArrayList<Chromosome> tournament = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            int randomIdx = rand.nextInt(population.size());
            tournament.add(population.get(randomIdx));
        }
        return Collections.max(tournament, Comparator.comparingDouble(Chromosome::getFitness));
    }

    // Single-point crossover between two parents
    private Chromosome crossover(Chromosome parent1, Chromosome parent2) {
        Chromosome child = new Chromosome(appliances, slotPrices);
        boolean[][] childGenes = child.getGenes();
        boolean[][] p1Genes = parent1.getGenes();
        boolean[][] p2Genes = parent2.getGenes();

        // Pick random slot index to split genes
        int crossoverPoint = rand.nextInt(slotPrices.length);
        for (int app = 0; app < appliances.length; app++) {
            // Copy parent1's genes before crossover point
            for (int slot = 0; slot < crossoverPoint; slot++) {
                childGenes[app][slot] = p1Genes[app][slot];
            }
            // Copy parent2's genes after crossover point
            for (int slot = crossoverPoint; slot < slotPrices.length; slot++) {
                childGenes[app][slot] = p2Genes[app][slot];
            }
        }
        child.updateFitness();
        return child;
    }

    // Mutate a chromosome by flipping random bits
    private void mutate(Chromosome chromosome) {
        boolean[][] genes = chromosome.getGenes();
        for (int app = 0; app < appliances.length; app++) {
            for (int slot = 0; slot < slotPrices.length; slot++) {
                if (rand.nextDouble() < mutationRate) {
                    genes[app][slot] = !genes[app][slot];
                }
            }
        }
        chromosome.updateFitness();
    }

    // Evolve population to next generation
    public void evolve() {
        ArrayList<Chromosome> newPopulation = new ArrayList<>();
        // Keep the best chromosome (elite preservation)
        Chromosome best = Collections.max(population, Comparator.comparingDouble(Chromosome::getFitness));
        newPopulation.add(best);

        // Fill rest of new population
        while (newPopulation.size() < populationSize) {
            Chromosome parent1 = tournamentSelection();
            Chromosome parent2 = tournamentSelection();

            Chromosome child;
            if (rand.nextDouble() < crossoverRate) {
                child = crossover(parent1, parent2);
            } else {
                // No crossover: copy parent directly
                child = parent1;
            }

            mutate(child);
            newPopulation.add(child);
        }

        population = newPopulation;
    }

    // Get the best chromosome in current population
    public Chromosome getBestChromosome() {
        return Collections.max(population, Comparator.comparingDouble(Chromosome::getFitness));
    }
}

Main Entry Point

public class Main {
    public static void main(String[] args) {
        // Initialize appliances (example values)
        Appliance[] appliances = {
                new Appliance("Washing Machine", 1.0),
                new Appliance("Air Conditioner", 1.5),
                new Appliance("Refrigerator", 0.2)
        };

        // Initialize 48-slot prices (example: cheap at night, expensive during day)
        double[] slotPrices = new double[48];
        for (int i = 0; i < 16; i++) slotPrices[i] = 0.3; // 00:00-08:00
        for (int i = 16; i < 48; i++) slotPrices[i] = 0.6; // 08:00-24:00

        // GA parameters (tweak these based on testing)
        int populationSize = 50;
        double crossoverRate = 0.8;
        double mutationRate = 0.01;
        int generations = 100;

        // Run GA
        GeneticAlgorithm ga = new GeneticAlgorithm(appliances, slotPrices, populationSize, crossoverRate, mutationRate);
        for (int gen = 0; gen < generations; gen++) {
            ga.evolve();
            Chromosome best = ga.getBestChromosome();
            double totalCost = 1 / best.getFitness() - 1; // Convert fitness back to cost
            System.out.printf("Generation %d: Minimum Cost = %.2f yuan%n", gen+1, totalCost);
        }

        // Print final optimal schedule
        Chromosome finalBest = ga.getBestChromosome();
        boolean[][] bestGenes = finalBest.getGenes();
        System.out.println("\nOptimal Scheduling Matrix (0=Off, 1=On):");
        System.out.print("          ");
        for (int slot = 0; slot < 48; slot++) {
            System.out.printf("%2d ", slot+1);
        }
        System.out.println();
        for (int app = 0; app < appliances.length; app++) {
            System.out.printf("%-15s", appliances[app].getName());
            for (int slot = 0; slot < 48; slot++) {
                System.out.printf("%2d ", bestGenes[app][slot] ? 1 : 0);
            }
            System.out.println();
        }
    }
}
Step 4: Next Steps & Tips
  • Add Constraints: If appliances have rules (e.g., washing machine needs 2 consecutive slots), modify the Chromosome class to penalize invalid schedules (set fitness to a very low value).
  • Optimize Performance: Use BitSet instead of boolean[][] to save memory, especially if you have many appliances.
  • Tune Parameters: Adjust population size, crossover rate, and generations based on your results—too small a population can lead to premature convergence, too large slows things down.
  • Learn Java Basics: Brush up on collections (ArrayList), random number generation, and OOP principles if you're still getting comfortable with Java.

内容的提问来源于stack exchange,提问作者newtojade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:06:51