云计算机
接下来试着自己解决一下云平衡的问题,在官方例子中,假设您的公司拥有多台云计算计算机,并且需要在这些计算机上运行多个进程。将每个进程分配给计算机。
每台计算机有不同的cpu,ram,以及带宽,花费开销。如何将进程分配到计算机中呢。
第一步创建模型。分析可得,问题中,电脑资源是问题事实,而进程在那台电脑上运行是规划事实。
创建Computer类
public class Computer extends AbstractPersistable {
Integer cpu;
Integer ram;
Integer net;
Integer cost;
public Computer() {
}
public Computer(long id, Integer cpu, Integer ram, Integer net, Integer cost) {
super(id);
this.cpu = cpu;
this.ram = ram;
this.net = net;
this.cost = cost;
}
public Integer getCpu() {
return cpu;
}
public void setCpu(Integer cpu) {
this.cpu = cpu;
}
public Integer getRam() {
return ram;
}
public void setRam(Integer ram) {
this.ram = ram;
}
public Integer getNet() {
return net;
}
public void setNet(Integer net) {
this.net = net;
}
public Integer getCost() {
return cost;
}
public void setCost(Integer cost) {
this.cost = cost;
}
}
进程Process类
public class Process extends AbstractPersistable {
public Integer reqcpu;
public Integer reqram;
public Integer reqnet;
public Process() {
}
public Process(long id, Integer reqcpu, Integer reqram, Integer reqnet) {
super(id);
this.reqcpu = reqcpu;
this.reqram = reqram;
this.reqnet = reqnet;
}
public Integer getReqcpu() {
return reqcpu;
}
public void setReqcpu(Integer reqcpu) {
this.reqcpu = reqcpu;
}
public Integer getReqram() {
return reqram;
}
public void setReqram(Integer reqram) {
this.reqram = reqram;
}
public Integer getReqnet() {
return reqnet;
}
public void setReqnet(Integer reqnet) {
this.reqnet = reqnet;
}
}
进程展示类ComputerWorking
@PlanningEntity
public class ComputerWorking extends AbstractPersistable {
public Computer computer;
public Process process;
public ComputerWorking() {
}
public ComputerWorking(long id) {
super(id);
}
public ComputerWorking(long id, Computer computer, Process process) {
super(id);
this.computer = computer;
this.process = process;
}
@PlanningVariable(valueRangeProviderRefs={"computerRange"})
public Computer getComputer() {
return computer;
}
public void setComputer(Computer computer) {
this.computer = computer;
}
@PlanningVariable(valueRangeProviderRefs={"processRange"})
public Process getProcess() {
return process;
}
public void setProcess(Process process) {
this.process = process;
}
}
CloudBalance类
@PlanningSolution
public class CloudBalance extends AbstractPersistable {
public List<Computer> computerList;
public List<Process> processList;
public List<ComputerWorking> computerWorkingList;
public HardSoftScore score;
public CloudBalance() {}
public CloudBalance(List<Computer> computerList, List<Process> processList, List<ComputerWorking> computerWorkingList) {
this.computerList = computerList;
this.processList = processList;
this.computerWorkingList = computerWorkingList;
}
@PlanningScore
public HardSoftScore getScore() {
return score;
}
public void setScore(HardSoftScore score) {
this.score = score;
}
@ProblemFactCollectionProperty
@ValueRangeProvider(id = "computerRange")
public List<Computer> getComputerList() {
return computerList;
}
public void setComputerList(List<Computer> computerList) {
this.computerList = computerList;
}
@ProblemFactCollectionProperty
@ValueRangeProvider(id = "processRange")
public List<Process> getProcessList() {
return processList;
}
public void setProcessList(List<Process> processList) {
this.processList = processList;
}
@PlanningEntityCollectionProperty
@ValueRangeProvider(id = "ComputerWorkingRange")
public List<ComputerWorking> getComputerWorkingList() {
return computerWorkingList;
}
public void setComputerWorkingList(List<ComputerWorking> computerWorkingList) {
this.computerWorkingList = computerWorkingList;
}
}
App类
public class App {
public static void main(String[] args) {
startPlan();
}
private static void startPlan(){
InputStream ins = App.class.getResourceAsStream("/taskassignmentConfiguration3.xml");
SolverFactory<CloudBalance> solverFactory = SolverFactory.createFromXmlInputStream(ins);
Solver<CloudBalance> solver = solverFactory.buildSolver();
List<Computer> computerList = new ArrayList<>();
computerList.add(new Computer(1L,7,6,100,150));
computerList.add(new Computer(2L,6,6,200,100));
computerList.add(new Computer(3L,8,8,100,80));
List<Process> processList = new ArrayList<>();
processList.add(new Process(1L,5,5,1));
processList.add(new Process(2L,4,3,1));
processList.add(new Process(3L,2,3,1));
processList.add(new Process(4L,2,1,1));
List<ComputerWorking> computerWorkingList = new ArrayList<>();
computerWorkingList.add(new ComputerWorking(1L));
computerWorkingList.add(new ComputerWorking(2L));
computerWorkingList.add(new ComputerWorking(3L));
computerWorkingList.add(new ComputerWorking(4L));
CloudBalance unassignment = new CloudBalance(computerList,processList,computerWorkingList);
CloudBalance assigned = solver.solve(unassignment);//启动引擎
System.out.println("exit!");
}
}
taskassignmentConfiguration3.xml
package com.example.demo.solver;
import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScoreHolder;
import com.example.demo.optaPlanner.cloud.Computer;
import com.example.demo.optaPlanner.cloud.CloudBalance;
import com.example.demo.optaPlanner.cloud.ComputerWorking;
import com.example.demo.optaPlanner.cloud.Process;
global HardSoftScoreHolder scoreHolder;
//一个进程只能分配一次 并且只能分配到一台电脑
rule "processLimit"
when
Process($pid:getId())
accumulate(
$c:ComputerWorking(process != null,
process.getId() ==$pid );
$count : count($c);
$count > 1
)
then
scoreHolder.addHardConstraintMatch(kcontext, -10000);
end
//cpu不能超过总的cpu
rule "cpu"
when
Computer($cpu:getCpu(),$id:getId())
accumulate(
ComputerWorking(computer != null,
computer.getId() == $id,
$requiredCpuPower:getProcess().getReqcpu() );
$requiredCpuPowerTotal : sum($requiredCpuPower);
$requiredCpuPowerTotal > $cpu
)
then
scoreHolder.addHardConstraintMatch(kcontext, -10000);
end
//ram不能超过总的ram
rule "ram"
when
Computer($ram:getRam(),$id:getId())
accumulate(
ComputerWorking(computer != null,
computer.getId() == $id,
$requiredRamPower:getProcess().getReqram() );
$requiredRamPowerTotal : sum($requiredRamPower);
$requiredRamPowerTotal > $ram
)
then
scoreHolder.addHardConstraintMatch(kcontext, -10000);
end
//软约束 尽可能少花费
rule "cost"
when
Computer($cost:getCost(),$id:getId())
exists ComputerWorking(getComputer() != null,$id == getComputer().getId())
then
scoreHolder.addSoftConstraintMatch(kcontext,-$cost ); //是一个负数,代表违反硬约束
end
该方法与官网中的例子有一点区别,建模思路不一致,但是在创建规则时,注意硬约束和软约束就好。