Нет entityClass, и поскольку в entityClassSet их несколько, он не может быть выведен автоматически

#optaplanner

#optaplanner

Вопрос:

Я пытаюсь реализовать решение с несколькими классами сущностей, и оно завершается неудачей со следующим сообщением об ошибке:

не настроен entityClass (null), и поскольку в entityClassSet их несколько ([class com.myspace.wla.JobA, class com.myspace.wla.JobB]), он не может быть выведен автоматически

Это конфигурация решателя:

 <?xml version="1.0" encoding="UTF-8"?>
<solver xStreamId="1">
    <solutionClass>com.myspace.wla.AllocationSolution</solutionClass>
    <entityClass>com.myspace.wla.JobA</entityClass>
    <entityClass>com.myspace.wla.JobB</entityClass>
    <scoreDirectorFactory xStreamId="3"/>
    <termination xStreamId="4">
        <millisecondsSpentLimit>0</millisecondsSpentLimit>
        <secondsSpentLimit>30</secondsSpentLimit>
        <minutesSpentLimit>0</minutesSpentLimit>
        <hoursSpentLimit>0</hoursSpentLimit>
        <daysSpentLimit>0</daysSpentLimit>
    </termination>
    <constructionHeuristic xStreamId="5">
        <constructionHeuristicType>FIRST_FIT</constructionHeuristicType>
        <entitySorterManner>NONE</entitySorterManner>
    </constructionHeuristic>
    <localSearch xStreamId="6">
        <unionMoveSelector>
          <changeMoveSelector>
            <entitySelector>
              <entityClass>com.myspace.wla.JobA</entityClass>
            </entitySelector>
            <valueSelector>
                <variableName>Computer</variableName>
                <selectionOrder>SORTED</selectionOrder>
            </valueSelector>
          </changeMoveSelector>
          <changeMoveSelector>
            <entitySelector>
              <entityClass>com.myspace.wla.JobB</entityClass>
            </entitySelector>
            <valueSelector>
                <variableName>Computer</variableName>
                <selectionOrder>SORTED</selectionOrder>
            </valueSelector>
          </changeMoveSelector>
        </unionMoveSelector>
    </localSearch>
</solver>
  

Это объект решения:

 package com.myspace.wla;

import java.util.List;
import org.optaplanner.core.api.domain.solution.PlanningSolution;
import org.optaplanner.core.api.domain.solution.PlanningEntityCollectionProperty;
import org.optaplanner.core.api.domain.solution.drools.ProblemFactCollectionProperty;
import org.optaplanner.core.api.domain.solution.PlanningScore;
import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider;

@PlanningSolution
@javax.xml.bind.annotation.XmlRootElement
@javax.xml.bind.annotation.XmlAccessorType(javax.xml.bind.annotation.XmlAccessType.FIELD)
public class AllocationSolution implements java.io.Serializable {

	static final long serialVersionUID = 1L;

	@javax.annotation.Generated({"org.optaplanner.workbench.screens.domaineditor.client.widgets.planner.PlannerDataObjectEditor"})
	@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter(org.optaplanner.persistence.jaxb.api.score.buildin.hardsoft.HardSoftScoreJaxbXmlAdapter.class)
	@org.kie.api.definition.type.Label("Generated Planner score field")
	private org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore score;

	private java.util.List<com.myspace.wla.Computer> computerList;

	private java.util.List<com.myspace.wla.JobA> jobAList;

	private int id;

	private java.util.List<com.myspace.wla.JobB> jobBList;

	public AllocationSolution() {
	}

	@PlanningScore
	public org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore getScore() {
		return this.score;
	}

	public void setScore(
			org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore score) {
		this.score = score;
	}

	@ValueRangeProvider(id = "computerRange")
	@ProblemFactCollectionProperty
	public java.util.List<com.myspace.wla.Computer> getComputerList() {
		return this.computerList;
	}

	public void setComputerList(
			List<com.myspace.wla.Computer> computerList) {
		this.computerList = computerList;
	}

	@PlanningEntityCollectionProperty
	@ValueRangeProvider(id = "jobARange")
	public List<com.myspace.wla.JobA> getJobAList() {
		return this.jobAList;
	}

	public void setJobAList(java.util.List<com.myspace.wla.JobA> jobAList) {
		this.jobAList = jobAList;
	}

	public int getId() {
		return this.id;
	}

	public void setId(int id) {
		this.id = id;
	}

	@PlanningEntityCollectionProperty
	@ValueRangeProvider(id = "jobBRange")
	public List<com.myspace.wla.JobB> getJobBList() {
		return this.jobBList;
	}

	public void setJobBList(java.util.List<com.myspace.wla.JobB> jobBList) {
		this.jobBList = jobBList;
	}

	public AllocationSolution(
			org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore score,
			java.util.List<com.myspace.wla.Computer> computerList,
			java.util.List<com.myspace.wla.JobA> jobAList, int id,
			java.util.List<com.myspace.wla.JobB> jobBList) {
		this.score = score;
		this.computerList = computerList;
		this.jobAList = jobAList;
		this.id = id;
		this.jobBList = jobBList;
	}

}  

Это объект fact:

 package com.myspace.wla;

public class Computer implements java.io.Serializable {

	static final long serialVersionUID = 1L;

	private int id;

	private int color;

	public Computer() {
	}

	public int getId() {
		return this.id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public int getColor() {
		return this.color;
	}

	public void setColor(int color) {
		this.color = color;
	}

	public Computer(int id, int color) {
		this.id = id;
		this.color = color;
	}

}  

Это первый объект планирования (второй идентичен с другим именем):

 package com.myspace.wla;

import org.optaplanner.core.api.domain.solution.drools.ProblemFactCollectionProperty;
import org.optaplanner.core.api.domain.entity.PlanningEntity;
import org.optaplanner.core.api.domain.variable.PlanningVariable;

@PlanningEntity
public class JobA implements java.io.Serializable {

	static final long serialVersionUID = 1L;

	private int id;
	private com.myspace.wla.Computer computer;

	private int color;

	public JobA() {
	}

	public int getId() {
		return this.id;
	}

	public void setId(int id) {
		this.id = id;
	}

	@PlanningVariable(valueRangeProviderRefs = {"computerRange"})
	public com.myspace.wla.Computer getComputer() {
		return this.computer;
	}

	public void setComputer(com.myspace.wla.Computer computer) {
		this.computer = computer;
	}

	public int getColor() {
		return this.color;
	}

	public void setColor(int color) {
		this.color = color;
	}

	public JobA(int id, com.myspace.wla.Computer computer, int color) {
		this.id = id;
		this.computer = computer;
		this.color = color;
	}

}  

Спасибо, Элиэзер

Ответ №1:

Проблемной частью конфигурации является <constructionHeuristic> фаза. Вам нужно использовать расширенную конфигурацию, которая запускает одну эвристическую фазу построения для каждого типа объекта планирования. В вашем случае это должно выглядеть примерно так:

 <constructionHeuristic>
    <entitySorterManner>NONE</entitySorterManner>
    <valueSorterManner>NONE</valueSorterManner>
    <queuedEntityPlacer>
        <entitySelector id="jobAEntitySelector">
            <cacheType>PHASE</cacheType>
            <entityClass>com.myspace.wla.JobA</entityClass>
        </entitySelector>
        <changeMoveSelector>
            <entitySelector mimicSelectorRef="jobAEntitySelector"/>
        </changeMoveSelector>
    </queuedEntityPlacer>
</constructionHeuristic>
<constructionHeuristic>
    <entitySorterManner>NONE</entitySorterManner>
    <valueSorterManner>NONE</valueSorterManner>
    <queuedEntityPlacer>
        <entitySelector id="jobBEntitySelector">
            <cacheType>PHASE</cacheType>
            <entityClass>com.myspace.wla.JobB</entityClass>
        </entitySelector>
        <changeMoveSelector>
            <entitySelector mimicSelectorRef="jobBEntitySelector"/>
        </changeMoveSelector>
    </queuedEntityPlacer>
</constructionHeuristic>
  

Обратите внимание, что это невозможно использовать constructionHeuristicType=FIRST_FIT с расширенной конфигурацией, но использование entitySorterManner=NONE и valueSorterManner=NONE эквивалентно FIRST_FIT .

Также можно исключить entitySorterManner и valueSorterManner, и в этом случае по умолчанию они будут иметь значение entitySorterManner=DECREASING_DIFFICULTY_IF_AVAILABLE и valueSorterManner=INCREASING_STRENGTH_IF_AVAILABLE .

Комментарии:

1. Я попробовал это, но теперь я получаю следующее сообщение об ошибке: Ошибка создания фабрики решателей для решателя: constructionHeuristicType (FIRST_FIT) не должен быть настроен, если entityPlacerConfig (QueuedEntityPlacerConfig(EntitySelectorConfig(class com.myspace.wla.JobA), [ChangeMoveSelectorConfig ( EntitySelectorConfig(null), null)])) явно настроен.

2. @eliezerb Вы правы. Я допустил ошибку при тестировании конфигурации. Я обновил ответ.

3. В настоящее время моя система не работает, поэтому я проверю это решение позже. Спасибо