Optaplanner介绍及使用

前言一、optaplanner是什么?二、使用步骤1.直接使用例程2.编译源代码

总结

前言

`

OptaPlanner是一个轻量级的、可嵌入的约束满足引擎,可求解规划问题,它巧妙的跟分数相结合,用分数来对比每一个解决方案,最高分作为最优解决方案。它使日常程序员能够有效地解决优化问题。约束适用于普通域对象并且可以调用现有代码。它对面向对象编程 (OOP) 和函数式编程 (FP) 友好。无需将约束输入为数学方程式。

在底层,OptaPlanner 将复杂的人工智能优化算法(例如禁忌搜索、模拟退火、延迟接受和其他元启发式算法)与非常有效的分数计算和其他最先进的 NP-complete 或 NP-约束求解技术相结合。

一、optaplanner是什么?

OptaPlanner是一款开源软件,100%由Java编写,可以在任何JVM上运行,也可以在Maven中央存储库中使用。它让普通的Java工程师能够有效地解决优化问题,它还与其他JVM语言(如Kotlin和Scala)兼容。

二、使用步骤

1.直接使用例程

准备:JDK 11 及以上,Maven(若需自己编译)

1.下载 链接:下载软件包 2.解压 解压之后如下图所示: 点击runExamples可直接运行程序: 可以看到optaplanner中有许多例程,比较经典的N皇后、排班、路径规划、JSP都有。可以随便选择一个例程运行,以JSP为例,选中之后出现如下界面: 左上角为需要解决问题的数据,随机选择一个求解,optalanner便会为我们自动求解,使用起来非常方便: 当然,其他例子也可运行,这里就不赘述了。

2.编译源代码

有人会想,我不想跑里面的例程,我想建立自己的模型怎么办呢?当然可以,可以参照optaplanner官方手册 自己编译需要下载源码,源码下载链接:optaplanner源码 下载解压之后如下图: 打开cmd,进行编译:

mvn compile

第一次编译需要下载许多依赖包,花费的时间较长,之后就好了。编译之后执行:

mvn exec:java

总的来说,optaplanner主要包含规划变量、规划实体、规划方案三类变量,以云资源平衡规划为例: 这三类变量是optaplanner建模的基础,其中的真意就要靠大家自己去参悟了。 以排课表为例,其基于python的源码如下:

from optapy import problem_fact, planning_id

from optapy import planning_entity, planning_variable

from datetime import time

@problem_fact

class Room:

def __init__(self, id, name):

self.id = id

self.name = name

@planning_id

def get_id(self):

return self.id

def __str__(self):

return f"Room(id={self.id}, name={self.name})"

@problem_fact

class Timeslot:

def __init__(self, id, day_of_week, start_time, end_time):

self.id = id

self.day_of_week = day_of_week

self.start_time = start_time

self.end_time = end_time

@planning_id

def get_id(self):

return self.id

def __str__(self):

return (

f"Timeslot("

f"id={self.id}, "

f"day_of_week={self.day_of_week}, "

f"start_time={self.start_time}, "

f"end_time={self.end_time})"

)

@planning_entity

class Lesson:

def __init__(self, id, subject, teacher, student_group, timeslot=None, room=None):

self.id = id

self.subject = subject

self.teacher = teacher

self.student_group = student_group

self.timeslot = timeslot

self.room = room

@planning_id

def get_id(self):

return self.id

@planning_variable(Timeslot, ["timeslotRange"])

def get_timeslot(self):

return self.timeslot

def set_timeslot(self, new_timeslot):

self.timeslot = new_timeslot

@planning_variable(Room, ["roomRange"])

def get_room(self):

return self.room

def set_room(self, new_room):

self.room = new_room

def __str__(self):

return (

f"Lesson("

f"id={self.id}, "

f"timeslot={self.timeslot}, "

f"room={self.room}, "

f"teacher={self.teacher}, "

f"subject={self.subject}, "

f"student_group={self.student_group}"

f")"

)

from optapy import planning_solution, planning_entity_collection_property, \

problem_fact_collection_property, \

value_range_provider, planning_score

from optapy.score import HardSoftScore

def format_list(a_list):

return ',\n'.join(map(str, a_list))

@planning_solution

class TimeTable:

def __init__(self, timeslot_list, room_list, lesson_list, score=None):

self.timeslot_list = timeslot_list

self.room_list = room_list

self.lesson_list = lesson_list

self.score = score

@problem_fact_collection_property(Timeslot)

@value_range_provider("timeslotRange")

def get_timeslot_list(self):

return self.timeslot_list

@problem_fact_collection_property(Room)

@value_range_provider("roomRange")

def get_room_list(self):

return self.room_list

@planning_entity_collection_property(Lesson)

def get_lesson_list(self):

return self.lesson_list

@planning_score(HardSoftScore)

def get_score(self):

return self.score

def set_score(self, score):

self.score = score

def __str__(self):

return (

f"TimeTable("

f"timeslot_list={format_list(self.timeslot_list)},\n"

f"room_list={format_list(self.room_list)},\n"

f"lesson_list={format_list(self.lesson_list)},\n"

f"score={str(self.score.toString()) if self.score is not None else 'None'}"

f")"

)

def generate_problem():

timeslot_list = [

Timeslot(1, "MONDAY", time(hour=8, minute=30), time(hour=9, minute=30)),

Timeslot(2, "MONDAY", time(hour=9, minute=30), time(hour=10, minute=30)),

Timeslot(3, "MONDAY", time(hour=10, minute=30), time(hour=11, minute=30)),

Timeslot(4, "MONDAY", time(hour=13, minute=30), time(hour=14, minute=30)),

Timeslot(5, "MONDAY", time(hour=14, minute=30), time(hour=15, minute=30)),

Timeslot(6, "TUESDAY", time(hour=8, minute=30), time(hour=9, minute=30)),

Timeslot(7, "TUESDAY", time(hour=9, minute=30), time(hour=10, minute=30)),

Timeslot(8, "TUESDAY", time(hour=10, minute=30), time(hour=11, minute=30)),

Timeslot(9, "TUESDAY", time(hour=13, minute=30), time(hour=14, minute=30)),

Timeslot(10, "TUESDAY", time(hour=14, minute=30), time(hour=15, minute=30)),

]

room_list = [

Room(1, "Room A"),

Room(2, "Room B"),

Room(3, "Room C")

]

lesson_list = [

Lesson(1, "Math", "A. Turing", "9th grade"),

Lesson(2, "Math", "A. Turing", "9th grade"),

Lesson(3, "Physics", "M. Curie", "9th grade"),

Lesson(4, "Chemistry", "M. Curie", "9th grade"),

Lesson(5, "Biology", "C. Darwin", "9th grade"),

Lesson(6, "History", "I. Jones", "9th grade"),

Lesson(7, "English", "I. Jones", "9th grade"),

Lesson(8, "English", "I. Jones", "9th grade"),

Lesson(9, "Spanish", "P. Cruz", "9th grade"),

Lesson(10, "Spanish", "P. Cruz", "9th grade"),

Lesson(11, "Math", "A. Turing", "10th grade"),

Lesson(12, "Math", "A. Turing", "10th grade"),

Lesson(13, "Math", "A. Turing", "10th grade"),

Lesson(14, "Physics", "M. Curie", "10th grade"),

Lesson(15, "Chemistry", "M. Curie", "10th grade"),

Lesson(16, "French", "M. Curie", "10th grade"),

Lesson(17, "Geography", "C. Darwin", "10th grade"),

Lesson(18, "History", "I. Jones", "10th grade"),

Lesson(19, "English", "P. Cruz", "10th grade"),

Lesson(20, "Spanish", "P. Cruz", "10th grade"),

]

lesson = lesson_list[0]

lesson.set_timeslot(timeslot_list[0])

lesson.set_room(room_list[0])

return TimeTable(timeslot_list, room_list, lesson_list)

注:optaplanner支持python,但速度会比java慢20倍左右。 当我们建立好模型之后,就可以进行求解了。当然还有一些基础的配置我们可以修改。所有的配置都在projectJobSchedulingSolverConfig.xml中,每一个工程都有一个配置文件,也不一定是projectJobScheduling。 上图为配置文件的部分内容, 1 用于配置求解器最长求解时间, org/optaplanner/examples/projectjobscheduling/optional/score/projectJobSchedulingConstraints.drl ,用于配置所建模型的记分规则。optaplanner除支持java api的记分方式外,还支持Drools,对传统的建模人员非常友好。

总结

以上就是今天要讲的内容,本文仅仅简单介绍了optaplanner的使用,而optaplanner提供了大量能使我们快速求解优化问题的方法,需要我们去进一步探索。

精彩文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: