opta

凛冬雪夜發表於2024-09-12
 <dependency>
            <groupId>org.optaplanner</groupId>
            <artifactId>optaplanner-spring-boot-starter</artifactId>
            <version>9.44.0.Final</version>
        </dependency>





import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.optaplanner.core.api.domain.solution.PlanningEntityCollectionProperty;
import org.optaplanner.core.api.domain.solution.PlanningScore;
import org.optaplanner.core.api.domain.solution.PlanningSolution;
import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider;
import org.optaplanner.core.api.score.buildin.simple.SimpleScore;

@Data
@AllArgsConstructor
@NoArgsConstructor
@PlanningSolution
public class NQueens {
    private int n;
    private List<Queen> queenList;
    private SimpleScore score;

    @ValueRangeProvider(id = "columnRange")
    public List<Integer> getColumnList() {
        return IntStream.range(0, n).boxed().collect(Collectors.toList());
    }

    @PlanningEntityCollectionProperty
    public List<Queen> getQueenList() {
        return queenList;
    }

    @PlanningScore
    public SimpleScore getScore() {
        return score;
    }

}




import org.optaplanner.core.api.score.buildin.simple.SimpleScore;
import org.optaplanner.core.api.score.stream.Constraint;
import org.optaplanner.core.api.score.stream.ConstraintFactory;
import org.optaplanner.core.api.score.stream.ConstraintProvider;
import org.optaplanner.core.api.score.stream.Joiners;

import static org.optaplanner.core.api.score.stream.Joiners.equal;

public class NQueensConstraintProvider implements ConstraintProvider {


    @Override
    public Constraint[] defineConstraints(ConstraintFactory factory) {
        return new Constraint[] {
                horizontalConflict(factory),
                verticalConflict(factory),
                ascendingDiagonalConflict(factory),
                descendingDiagonalConflict(factory),
        };
    }

    // ************************************************************************
    // Hard constraints
    // ************************************************************************

    protected Constraint horizontalConflict(ConstraintFactory factory) {
        return factory.forEachUniquePair(Queen.class, equal(Queen::getRow))
                .penalize(SimpleScore.ONE)
                .asConstraint("Horizontal conflict");
    }
    protected Constraint verticalConflict(ConstraintFactory factory) {
        return factory.forEachUniquePair(Queen.class, equal(Queen::getColumn))
                .penalize(SimpleScore.ONE)
                .asConstraint("vertical conflict");
    }

    protected Constraint ascendingDiagonalConflict(ConstraintFactory factory) {
        return factory.forEachUniquePair(Queen.class, equal(queen -> queen.getRow()- queen.getColumn()))
                .penalize(SimpleScore.ONE)
                .asConstraint("Ascending diagonal conflict");
    }

    protected Constraint descendingDiagonalConflict(ConstraintFactory factory) {
        return factory.forEachUniquePair(Queen.class, equal(queen -> queen.getRow()+ queen.getColumn()))
                .penalize(SimpleScore.ONE)
                .asConstraint("Descending diagonal conflict");
    }
 
}






import org.optaplanner.core.api.solver.SolverJob;
import org.optaplanner.core.api.solver.SolverManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.UUID;
import java.util.concurrent.ExecutionException;

@Service
public class NQueensService {

    @Resource
    private SolverManager<NQueens, UUID> solverManager;

    public NQueens solve(NQueens problem) {
        UUID problemId = UUID.randomUUID();
        SolverJob<NQueens, UUID> solverJob = solverManager.solve(problemId, problem);
        try {
            return solverJob.getFinalBestSolution();
        } catch (InterruptedException | ExecutionException e) {
            throw new IllegalStateException("Solving failed.", e);
        }
    }
}






import lombok.Data;
import org.optaplanner.core.api.domain.entity.PlanningEntity;
import org.optaplanner.core.api.domain.variable.PlanningVariable;

@Data
@PlanningEntity
public class Queen {
    private int row;
    private int column;

    @PlanningVariable(valueRangeProviderRefs = "columnRange")
    public int getColumn() {
        return column;
    }

    public void setColumn(int column) {
        this.column = column;
    }

    // 建構函式、getter 和 setter
}




1




1




1