/* * Copyright 2012 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.optaplanner.examples.nqueens.solver.score; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.optaplanner.core.api.score.buildin.simple.SimpleScore; import org.optaplanner.core.impl.score.director.incremental.AbstractIncrementalScoreCalculator; import org.optaplanner.examples.nqueens.domain.NQueens; import org.optaplanner.examples.nqueens.domain.Queen; import org.optaplanner.examples.nqueens.domain.Row; public class NQueensAdvancedIncrementalScoreCalculator extends AbstractIncrementalScoreCalculator<NQueens> { private Map<Integer, List<Queen>> rowIndexMap; private Map<Integer, List<Queen>> ascendingDiagonalIndexMap; private Map<Integer, List<Queen>> descendingDiagonalIndexMap; private int score; @Override public void resetWorkingSolution(NQueens nQueens) { int n = nQueens.getN(); rowIndexMap = new HashMap<>(n); ascendingDiagonalIndexMap = new HashMap<>(n * 2); descendingDiagonalIndexMap = new HashMap<>(n * 2); for (int i = 0; i < n; i++) { rowIndexMap.put(i, new ArrayList<>(n)); ascendingDiagonalIndexMap.put(i, new ArrayList<>(n)); descendingDiagonalIndexMap.put(i, new ArrayList<>(n)); if (i != 0) { ascendingDiagonalIndexMap.put(n - 1 + i, new ArrayList<>(n)); descendingDiagonalIndexMap.put((-i), new ArrayList<>(n)); } } score = 0; for (Queen queen : nQueens.getQueenList()) { insert(queen); } } @Override public void beforeEntityAdded(Object entity) { // Do nothing } @Override public void afterEntityAdded(Object entity) { insert((Queen) entity); } @Override public void beforeVariableChanged(Object entity, String variableName) { retract((Queen) entity); } @Override public void afterVariableChanged(Object entity, String variableName) { insert((Queen) entity); } @Override public void beforeEntityRemoved(Object entity) { retract((Queen) entity); } @Override public void afterEntityRemoved(Object entity) { // Do nothing } private void insert(Queen queen) { Row row = queen.getRow(); if (row != null) { int rowIndex = queen.getRowIndex(); List<Queen> rowIndexList = rowIndexMap.get(rowIndex); score -= rowIndexList.size(); rowIndexList.add(queen); List<Queen> ascendingDiagonalIndexList = ascendingDiagonalIndexMap.get(queen.getAscendingDiagonalIndex()); score -= ascendingDiagonalIndexList.size(); ascendingDiagonalIndexList.add(queen); List<Queen> descendingDiagonalIndexList = descendingDiagonalIndexMap.get(queen.getDescendingDiagonalIndex()); score -= descendingDiagonalIndexList.size(); descendingDiagonalIndexList.add(queen); } } private void retract(Queen queen) { Row row = queen.getRow(); if (row != null) { List<Queen> rowIndexList = rowIndexMap.get(queen.getRowIndex()); rowIndexList.remove(queen); score += rowIndexList.size(); List<Queen> ascendingDiagonalIndexList = ascendingDiagonalIndexMap.get(queen.getAscendingDiagonalIndex()); ascendingDiagonalIndexList.remove(queen); score += ascendingDiagonalIndexList.size(); List<Queen> descendingDiagonalIndexList = descendingDiagonalIndexMap.get(queen.getDescendingDiagonalIndex()); descendingDiagonalIndexList.remove(queen); score += descendingDiagonalIndexList.size(); } } @Override public SimpleScore calculateScore() { return SimpleScore.valueOf(score); } }