定制基因型用于嵌套的芯片
我正在使用Jenetics使用nofitpolygon嵌套多边形列表,
我的函数可以通过列表中的顺序来获得多边形列表。
我调整了Travellingsman问题,以具有代表多边形列表的基因型,并在进化过程中变化。
现在,我想将旋转添加到基因型中,以获得更好的结果,但我不知道如何将其添加到我的代码中。
当前,嵌套的顺序决定了适合度,我想做的是,对于每个巢道,将双重值(DoubleChromosomose?)添加到代表巢穴旋转的基因型。
NestPath是代表多边形
public class NFP_Nesting implements Problem<ISeq<NestPath>, EnumGene<NestPath>, Double>{
static Phenotype<EnumGene<NestPath>,Double> tmpBest = null;
static Result tmpBestResult =null;
private NestPath _binPolygon;
Map<String,List<NestPath>> nfpCache=new HashMap<>();
private final ISeq<NestPath> _list;
public NFP_Nesting(ISeq<NestPath> lista,NestPath binpolygon ,double binw, double binh)
{
_binPolygon = binpolygon;
_list=Objects.requireNonNull(lista);
}
@Override
public Codec<ISeq<NestPath>, EnumGene<NestPath>> codec() {
return Codecs.ofPermutation(_list);
}
@Override
public Function<ISeq<NestPath>, Double> fitness() {
return this::scalar_fitness;
}
/**
* @param seq_nestpath
* @return Fitness of the model
*/
Double scalar_fitness(final ISeq<NestPath> seq_nestpath) {
List<NestPath> paths = seq_nestpath.asList();
final Random random = RandomRegistry.random();
//TODO NOT RANDOM ROTATION
List<Integer> ids = new ArrayList<>();
for(int i = 0 ; i < paths.size(); i ++){
ids.add(paths.get(i).getId());
NestPath n = paths.get(i);
if(n.getPossibleRotations()!= null)
{
n.setRotation(n.getPossibleRotations()[random.nextInt(n.getPossibleRotations().length)]);
}
}
///复杂函数的类
return fitness;
}
private static NFP_Nesting of (List<NestPath> l, NestPath binpol, double binw, double binh)
{
final MSeq<NestPath> paths = MSeq.ofLength(l.size());
final Random random = RandomRegistry.random();
for ( int i = 0 ; i < l.size(); ++i ) {
paths.set(i, l.get(i));
}
//initial shuffle list of polygons
for(int j=paths.length()-1; j>0;--j)
{
final int i = random.nextInt(j+1);
final NestPath tmp=paths.get(i);
paths.set(i, paths.get(j));
paths.set(j, tmp);
}
return new NFP_Nesting(paths.toISeq(),binpol,binw,binh);
}
main:
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(1);
NFP_Nesting nst = NFP_Nesting.of(tree,binPolygon,binWidth,binHeight);
Engine<EnumGene<NestPath>,Double> engine = Engine
.builder(nst)
.optimize(Optimize.MINIMUM)
.populationSize(config.POPULATION_SIZE)
.executor(executor)
.alterers(
new SwapMutator<>(0.25),
new PartiallyMatchedCrossover<>(0.35)
)
.build();
final EvolutionStatistics<Double, ?> statistics = EvolutionStatistics.ofNumber();
Phenotype<EnumGene<NestPath>,Double> best=
engine.stream()
.limit(Limits.bySteadyFitness(5))
.limit(Limits.byExecutionTime(Duration.ofSeconds(MAX_SEC_DURATION)))
//.limit(10)
.peek(NFP_Nesting::update)
.peek(statistics)
.collect(toBestPhenotype());
System.out.println(statistics);
//System.out.println(best);
}
I'm using Jenetics to nest a list of polygons using NoFitPolygon
I have a function that gived a list of polygon nests them following the order in the list.
I adapted the TravellingSalesman problem in order to have a genotype that represent the list of polygons, and during evolution the order change.
Now I want to add the rotation to the genotype, in order to get better results, but I don't know how to add it to my code.
Currently the order of the nestpaths determines the fitness, what i want to do is add, for every nestpath, a double value (doubleChromosome?) to the genotype that represent the rotation of the nestpath.
Nestpath is the class that represent the polygon
public class NFP_Nesting implements Problem<ISeq<NestPath>, EnumGene<NestPath>, Double>{
static Phenotype<EnumGene<NestPath>,Double> tmpBest = null;
static Result tmpBestResult =null;
private NestPath _binPolygon;
Map<String,List<NestPath>> nfpCache=new HashMap<>();
private final ISeq<NestPath> _list;
public NFP_Nesting(ISeq<NestPath> lista,NestPath binpolygon ,double binw, double binh)
{
_binPolygon = binpolygon;
_list=Objects.requireNonNull(lista);
}
@Override
public Codec<ISeq<NestPath>, EnumGene<NestPath>> codec() {
return Codecs.ofPermutation(_list);
}
@Override
public Function<ISeq<NestPath>, Double> fitness() {
return this::scalar_fitness;
}
/**
* @param seq_nestpath
* @return Fitness of the model
*/
Double scalar_fitness(final ISeq<NestPath> seq_nestpath) {
List<NestPath> paths = seq_nestpath.asList();
final Random random = RandomRegistry.random();
//TODO NOT RANDOM ROTATION
List<Integer> ids = new ArrayList<>();
for(int i = 0 ; i < paths.size(); i ++){
ids.add(paths.get(i).getId());
NestPath n = paths.get(i);
if(n.getPossibleRotations()!= null)
{
n.setRotation(n.getPossibleRotations()[random.nextInt(n.getPossibleRotations().length)]);
}
}
///complicated function here
return fitness;
}
private static NFP_Nesting of (List<NestPath> l, NestPath binpol, double binw, double binh)
{
final MSeq<NestPath> paths = MSeq.ofLength(l.size());
final Random random = RandomRegistry.random();
for ( int i = 0 ; i < l.size(); ++i ) {
paths.set(i, l.get(i));
}
//initial shuffle list of polygons
for(int j=paths.length()-1; j>0;--j)
{
final int i = random.nextInt(j+1);
final NestPath tmp=paths.get(i);
paths.set(i, paths.get(j));
paths.set(j, tmp);
}
return new NFP_Nesting(paths.toISeq(),binpol,binw,binh);
}
Main:
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(1);
NFP_Nesting nst = NFP_Nesting.of(tree,binPolygon,binWidth,binHeight);
Engine<EnumGene<NestPath>,Double> engine = Engine
.builder(nst)
.optimize(Optimize.MINIMUM)
.populationSize(config.POPULATION_SIZE)
.executor(executor)
.alterers(
new SwapMutator<>(0.25),
new PartiallyMatchedCrossover<>(0.35)
)
.build();
final EvolutionStatistics<Double, ?> statistics = EvolutionStatistics.ofNumber();
Phenotype<EnumGene<NestPath>,Double> best=
engine.stream()
.limit(Limits.bySteadyFitness(5))
.limit(Limits.byExecutionTime(Duration.ofSeconds(MAX_SEC_DURATION)))
//.limit(10)
.peek(NFP_Nesting::update)
.peek(statistics)
.collect(toBestPhenotype());
System.out.println(statistics);
//System.out.println(best);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我想我现在了解你的问题。您要做的是在基因型中编码额外的旋转。但是二聚体仅允许每个基因型一种基因类型。使用置换式codec,您将基因类型修复到
enumgene
,并且为了旋转,您将需要doublegene
。通过一个简单的技巧,我们可以通过使用染色体内的基因顺序来表达路径置换为double -code
。以下代码将向您展示如何执行此操作。
I think I understand your problem now. What you want to do is to have an additional rotation encoded in the genotype. But Jenetics only allows one gene type per genotype. Using the permutation-codec, you fixed the gene-type to a
EnumGene
and for your rotation you will needDoubleGene
. With a simple trick we are able to express the path permutation also asDoubleGene
, by using the order of the genes within the chromosome.The following code will show you how to do this.
我不确定我是否完全了解您要解决的问题,但是置换编解码器(
codecs.ofpermunt(seq)
)用于给定对象序列的顺序确定它的问题健康。因此,只有nestPath的顺序
iSeq&lt; nestPath&gt;
的元素定义了健身,对吗?健身功能不负责通过副作用更改对象。我也不明白您对基因型旋转旋转的意思。 em> Jenetics 中的A
基因型
是 JUST 的一系列染色体。也许您可以更详细地解释您的优化问题。对您的代码本身的一些注释
nfp_nesting :: of
对给定的list&lt; nestpath&gt;
进行改组。这不是必需的。.peek(NFP_NESTING :: UPDATE)进行一些更新,
也看起来可疑。如果您需要更新NestPath
对象,则不再进行排列优化。NestPath
对象应该是不可变的。问题
实现中。问题
接口仅组合codec
和健身功能,应该是不可变的。因此,如果您可以更清楚地解释您的问题,我可以尝试帮助找到适当的编码。
I'm not sure whether I fully understand the problem you want to solve, but the permutation codec (
Codecs.ofPermutation(Seq)
) is used for problems where the order of a given sequence of objects determines it's fitness. So, only the order of theNestPath
elements inISeq<NestPath>
defines the fitness, right? The fitness function is not responsible for altering your objects, via side effects.I also don't understand what you mean with rotate the genotype. A
Genotype
in Jenetics is just a sequence of chromosomes. Maybe you can explain your optimization problem in a greater detail.Some comments to your code itself
NFP_Nesting::of
does a shuffling of the givenList<NestPath>
. This is not necessary..peek(NFP_Nesting::update)
also looks suspicious. If you need to update yourNestPath
objects, you no longer doing a permutation optimization. TheNestPath
object should be immutable.Problem
implementation. TheProblem
interface just combines theCodec
and the fitness function and should be immutable.So, if you can explane your problem more clearly, I can try to help to find a proper encoding.