遗传算法java(中国外运杯)

遗传算法Java

背景:因为参加中国外运杯的比赛,写了遗传算法参加比赛,可惜最后只是校二等奖,止步在校赛,这篇文章仅争对个人对遗传算法的理解和编写,因为java比较熟练,所以选择用java编写。

个人理解:遗传算法差不多就是一种蛮力法,然后加上一些优化,因为这个比赛不可能把所有可能都遍历一遍,情况太多,天文数字,所以在合理的情况进行蛮力,结果不一定是最优的,但也差不多了

具体步骤
1.合理的条件下生成初始种群(即生成符合一定规范的编码情况对应数组,合理的条件需要一个函数去限制)
2.对初始种群,在一定概率下进行交换对方的编码(前提是要都能通过约束条件,不通过说明不能进行这种编码)
3.每个都要概率进行变异(随机选一个编码,也要通过约束条件)
4.计算适应度,每次都淘汰最末尾的几个
5.重复2-4的操作,最后剩下一个。

废话不多说,直接上代码:(代码中有文件输出的函数,不用记得注释)

这个是未加时间窗约束,需要时间窗约束的可以找我,程序应该是可以是运行的,
数据是比赛提供的真实数据。

package zhongguowaiyunbei.First;


import sun.reflect.generics.tree.Tree;

import java.io.*;
import java.util.*;


/*
* 转载请标明出处哦,嘿嘿。
*
*
*
* 
* */


public class Solution1 {
    //车的参数,每种类型的车三辆
    static Double Gcar [] = {2D,2D,3D,3D,6D,6D,10D,10D,13D,13D,15D,15D,25D,25D};//代表每个车的承载重量
    static Double Vcar [] = {4D,4D,6D,6D,15D,15D,17D,17D,30D,30D,40D,40D,50D,50D};//代表每个车的装载体积
    static Double qibujia [] ={350D,350D,350D,350D,450D,450D,550D,550D,650D,650D,650D,650D,850D,850D};//代表每个车的起步价
    static Double dianweifei [] ={50D,50D,50D,50D,100D,100D,110D,110D,140D,140D,140D,140D,180D,180D};//代表每个车点位费用
    //6.6单子的参数
    //static Double Gdanzi [] = {0.5597D,6.138602D,1.42693D,0.399823D,0.2255D,0.49656D,2.5D,0.3D,0.2D,0.2D,1.1348D,0.09D,0.11D,0.38D,0.111D,0.603665D,0.03D,2.163812D,1.06D,0.4D,0.0392D,0.096325D,2.71604D,0.117D,9.063596D,0.0897D,0.29608D,0.69946D,0.29564D,0.17608D,0.39518D,0.59132D,0.8696D,0.5435D,2.07044D,0.66D,0.02D,0.02D,0.02D,0.56D,0.24D,0.56D,0.02D,0.16D,0.96D,0.04D,4.98D,0.11D,3.9D,0.025D,0.04D,0.15D,0.32D,0.01D,0.18D,0.01D,0.75D,0.0144D,0.02D,0.175D,0.1404D,0.025D,0.0144D,0.010138D,0.077332D,0.353682D,0.246588D,0.236082D,0.712828D,0.1025D,0.322735D,1.074886D,0.0214D,7.296219D,0.32994D,0.06768D,0.119052D,0.00846D,0.00846D,0.01692D,0.01692D,0.040552D,0.0913D,0.6D,3.943932D,16.201054D,0.06279D,0.02158D,0.205656D,0.442516D,0.111D,1.528D,0.84116D,0.11608D,0.0852D,0.04174D,0.18478D,3.00834D,0.04D,0.08D,0.34D,0.06D,0.06D,0.02D,0.14D,3.44D,3.2D,0.024D,0.0135D,0.025D,0.025D,0.025D,0.012D,0.012D,0.05D,0.03D,0.345D,0.18D,0.0576D,0.025D,0.065D,0.175D,0.0144D,0.5424D,0.0855D,0.02D,0.02D,0.025D,0.3576D,0.036D,0.05D,0.06845D,0.409271D,0.077332D,0.348288D,0.406316D,0.385181D,0.1785D,1.143686D,0.038666D,7.708166D,0.17766D,0.010138D,0.14382D,0.067194D,0.00846D,0.00846D,0.271835D,0.101558D,14.465328D,0.00897D,0.046992D,0.278655D,0.29762D,0.398047D,0.05085D,0.03652D,2.6664D,1.61039D,};//单子的重量
    //static Double Vdanzi [] = {1.34885D,11.735988D,4.376124D,0.770263D,0.24948D,0.89292D,0D,0D,0D,0D,0D,0D,0D,0D,0.237615D,1.17099D,0.072D,6.453989D,0D,0D,0D,0D,5.08166D,0.21986D,16.22385D,0.048D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0.0024D,0.1344D,0.708114D,0.488076D,0.466114D,1.620996D,0.18D,0.871153D,1.867382D,0.043D,16.635296D,0.82485D,0.1692D,0.1026D,0.02115D,0.02115D,0.0423D,0.0423D,0.0096D,0.36D,0D,6.12D,29.142288D,0.0336D,0.034D,0.348D,0.972546D,0.237615D,2.8644D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0.149206D,0.88407D,0.1344D,0.803986D,0.886024D,0.905024D,0.315D,2.063382D,0.0672D,18.14792D,0.44415D,0.0024D,0.35955D,0.093D,0.02115D,0.02115D,0.635568D,0.190986D,26.605396D,0.0048D,0.074844D,0.460705D,0.49654D,0.586161D,0.090843D,0.144D,7.059873D,5.881277D};//单子的体积
    //static Double jingdu [] = {116.722967D,116.722967D,116.606476D,116.42768D,116.471384D,116.471384D,116.277783D,116.277783D,116.277783D,116.277783D,116.170499D,116.345488D,116.345488D,116.345488D,116.460962D,116.460962D,116.460962D,116.186757D,116.590903D,116.590903D,116.590903D,116.590903D,116.597232D,116.597232D,116.597232D,116.597232D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.454616D,116.264293D,116.264293D,116.264293D,116.397809D,116.397809D,116.474093D,116.474093D,116.618021D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.815496D,116.815496D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.815496D,116.815496D,116.706691D,116.706691D,116.706691D,116.74613D,116.74613D};
    //static Double weidu  [] = {40.047705D,40.047705D,39.842024D,39.993319D,39.871168D,39.871168D,39.950124D,39.950124D,39.950124D,39.950124D,39.816625D,39.796036D,39.796036D,39.796036D,39.819879D,39.819879D,39.819879D,39.745945D,40.14285D,40.14285D,40.14285D,40.14285D,40.204182D,40.204182D,40.204182D,40.204182D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,39.953421D,40.122599D,40.122599D,40.122599D,39.989379D,39.989379D,40.000481D,40.000481D,40.135315D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.752241D,39.752241D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.752241D,39.752241D,39.924245D,39.924245D,39.924245D,39.685362D,39.685362D};
    //6.23单子参数
    static Double Gdanzi [] = {9.515859D,3.87756D,3.28661D,0.02D,0.04174D,0.06D,0.34D,0.14172D,0.52D,0.04D,0.04D,0.06D,0.04D,0.26D,0.02D,0.02D,0.04D,0.0711D,0.055D,0.04D,0.025D,0.125D,0.0768D,0.1344D,0.05D,0.0144D,0.66D,0.12D,0.0423D,0.048D,0.05D,0.025D,0.3D,0.02D,0.0144D,7.56D,0.01692D,0.058753D,0.018D,0.038666D,0.019333D,0.057999D,0.028463D,0.045797D,0.022044D,0.0185D,0.0171D,0.019333D,0.015664D,0.015664D,0.02589D,0.04719D,0.0205D,0.0205D,0.24D,0.12D,0.37D,0.06D,0.4444D,0.02D,0.12D,0.1544D,0.54D,0.776231D,0.88036D,0.4275D,0.19D,0.04D,0.2382D,1.34D,0.02D,0.29D,0.7666D,0.0288D,0.05005D,0.12D,0.18D,0.2D,0.24D,0.1376D,1.29903D,0.198D,0.14D,0.09D,0.0144D,0.12D,0.216211D,2.410667D,2.697567D,0.143074D,0.342D,0.224D,1D,0.21D,0.09D,0.06D,0.2544D,0.1951D,1.6D,2.153D,1.497784D,0.764D,1.9333D,0.3041D,0.5D,0.399784D,0.042344D,0.1216D,0.033D,0.98491D,1.2D,0.3D,1D,0.36D,0.12D,0.02D,0.28D,0.26D,0.24D,0.04D,0.16D,0.1D,0.28D,0.88D,0.2D,1.5D,0.0576D,0.0984D,0.072D,0.095D,0.36D,0.104D,0.0288D,0.3854D,0.0344D,0.0528D,0.02D,0.0788D,0.025D,0.2D,0.1D,0.04174D,0.02D,0.12D,0.2343D,0.02D,0.14696D,0.48D,0.06D,0.02D,0.02D,0.5D,0.08D,0.06D,0.02D,0.08D,0.04D,0.06D,0.24D,20D,0.1152D,0.0384D,0.01D,0.3336D,0.18D,0.6D,0.072D,0.1D,0.012D,0.025D,0.02D,0.252D,0.0288D,0.444D,0.04D,7.728D,0.00846D,0.038666D,0.038666D,0.037D,0.053628D,0.015664D,1.11D,0.35118D,0.2739D,0.42375D,0.5382D,4.714008D,0.486D,0.8475D,0.339625D,0.108D,0.963D,1.063315D,0.2D,0.12D,0.4488D,0.21D,0.2D,0.09D,0.1344D,0.104D,0.13D,0.5646D,0.066672D,1.2648D,3.37692D};//单子的重量
    static Double Vdanzi [] = {16.059768D,7.6132D,5.70197D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0.0423D,0.125763D,0.035D,0.1D,0.05D,0.15D,0.069541D,0.087711D,0.048907D,0.033D,0.018D,0.05D,0.024948D,0.024948D,0.0471D,0.099869D,0.036D,0.036D,0D,0D,0D,0D,0D,0D,0D,0D,0D,1.374257D,2.030125D,0.45D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,2.629492D,0.33D,0D,0D,0D,0D,0.216211D,2.410667D,2.697567D,0.143074D,0.36D,0.336D,0D,0D,0D,0D,0D,0.3D,2.7648D,3.7D,3.579384D,1.4322D,3.3541D,0.76439D,0D,0.74102D,0.056D,0.290615D,0.003D,1.8108D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0D,0.02115D,0.1D,0.1D,0.066D,0.105634D,0.024948D,2.37615D,0.54D,1.08D,0.7344D,0.288D,7.577016D,0.75D,1.4688D,0.339625D,0.2742D,1.1742D,1.65D,0D,0D,0D,0D,0D,0D,0D,1.044D,1.305D,2.806442D,0.34272D,4.751742D,9.815185D};//单子的体积
    static Double jingdu [] ={116.208528D,116.693362D,116.693362D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.681114D,116.305266D,116.305266D,116.305266D,116.32393D,116.32393D,116.55298D,116.55298D,116.55298D,116.462614D,116.29553D,116.29553D,116.29553D,116.393876D,116.393876D,116.393876D,116.623584D,116.623584D,116.623584D,116.623584D,116.623584D,116.623584D,116.42768D,116.42768D,116.42768D,116.235119D,116.235119D,116.173707D,116.173707D,116.149782D,116.149782D,116.149782D,116.149782D,116.575517D,116.575517D,116.575517D,116.575517D,116.277783D,116.277783D,116.468347D,116.548831D,116.548831D,116.548831D,116.548831D,116.722967D,116.722967D,116.722967D,116.618021D,116.618021D,116.707086D,116.40795D,116.501258D,116.474093D,116.474093D,116.317673D,116.317673D,116.365799D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.687361D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.528726D,116.264293D,116.264293D,116.264293D,116.264293D,116.264293D,116.264293D,116.264293D,116.276408D,116.582038D,116.582038D,116.582038D,116.345488D,116.345488D,116.345488D,116.648115D,116.648115D,116.648115D,116.648115D,116.459369D,116.459369D,116.459369D,116.459369D,116.459369D,116.74613D,};
    static Double weidu  [] ={39.806135D,39.827286D,39.827286D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.709432D,39.830486D,39.830486D,39.830486D,39.884716D,39.884716D,39.743074D,39.743074D,39.743074D,39.889724D,39.841836D,39.841836D,39.841836D,39.847288D,39.847288D,39.847288D,39.898194D,39.898194D,39.898194D,39.898194D,39.898194D,39.898194D,39.993319D,39.993319D,39.993319D,39.913078D,39.913078D,39.658515D,39.658515D,39.752031D,39.752031D,39.752031D,39.752031D,40.002602D,40.002602D,40.002602D,40.002602D,39.950124D,39.950124D,39.97404D,40.112143D,40.112143D,40.112143D,40.112143D,40.047705D,40.047705D,40.047705D,40.135315D,40.135315D,40.09755D,39.977541D,39.967768D,40.000481D,40.000481D,40.033358D,40.033358D,39.98338D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,39.978994D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.011064D,40.122599D,40.122599D,40.122599D,40.122599D,40.122599D,40.122599D,40.122599D,40.105792D,39.928952D,39.928952D,39.928952D,39.796036D,39.796036D,39.796036D,39.911458D,39.911458D,39.911458D,39.911458D,39.843247D,39.843247D,39.843247D,39.843247D,39.843247D,39.685362D,};

    static Integer car_num = Gcar.length;//车的数量
    static Integer danzi_num = Gdanzi.length;//单子的数量
    static int first_num = 1000;//初始化种群个数
    static int Maxgen = 999;//迭代次数
    static Double jiaochapro = 0.7D;//单点交叉概率
    static Double bianyipro = 0.01D;//单点变异概率

    static int ansflag = 0;//记录是否需要输出钱

    public static void main(String[] args) {

        System.out.println(Gcar.length);
        System.out.println(Vcar.length);
        System.out.println(qibujia.length);
        System.out.println(dianweifei.length);
        System.out.println(Gdanzi.length);
        System.out.println(Vdanzi.length);
        System.out.println(jingdu.length);
        System.out.println(weidu.length);
        //Set<ArrayList<Integer>> Lists = new HashSet<>();
        HashMap<Integer, ArrayList<Integer>> hm = new HashMap<>();//存储1000个符合条件的个体 此即为种群
        Random rand = new Random();
        System.out.println("初始化种群:");
        //获取初始种群
        int index = 0;
        while (hm.size()<first_num)
        {
            //方法1:随机生成单子数的编码,判断是否符合条件,不符合就不添加到种群中,时间复杂度太慢了!!!!
//            ArrayList<Integer> list = new ArrayList<>();//暂时保存一个初始化的编码
//            //赋予单子数量的数组,每个对应的数,代表第几个单由第几个车去运算
//            for (Integer i = 0; i < danzi_num; i++) {
//                int randNumber =rand.nextInt(car_num) + 1; // randNumber 将被赋值为1-21范围内的随机整数
//                list.add(randNumber);
//            }
//
//            //System.out.println(list);
//            //检查这个编码是否通过约束
//            if (isPass(list))
//            {
//                hm.put(index,list);
//                index++;
//                System.out.print(index+" ");
//            }
            //方法2:数组每添加一个,就进行判断,是否合理,如果不合理换新得添加进去,直到满足了单子每个都送了,就添加到种群中
//            ArrayList<Integer> list = new ArrayList<>();//暂时保存一个初始化的编码
//            while(list.size()!=danzi_num)
//            {
//                int randNumber =rand.nextInt(car_num) + 1; // randNumber 将被赋值为1-21范围内的随机整数
//                list.add(randNumber);
//                if (isPass(list))//通过了约束
//                {
//                    ;
//                } else  {//没通过就移除
//                    list.remove(list.size()-1);
//                }
//            }
//            hm.put(index,list);
//            index++;
//            System.out.print(index+" ");

            int flag = 0;//记录如果超过一定次数,则认为当前的不可靠,创建新的数组
            //方法3:动态找出大于它的添加
            ArrayList<Integer> list = new ArrayList<>();//暂时保存一个初始化的编码
            int i = 0;//代表第几个订单的索引
            while(list.size()!=danzi_num && flag < 10000)
            {
                int carIndex = getCarIndex(i);//得到符合刚好的车型的索引
                carIndex++;//对应车的编号
                int randNumber =getRandomNumberFrom(carIndex,car_num);// randNumber 将被赋值为编号车到最大车范围内的随机整数
                //System.out.println(randNumber);
                list.add(randNumber);
                if (isPass(list))//通过了约束
                {
                    i++;
                    //System.out.print(list);
                    //System.out.print("list"+i+" "+carIndex+" "+randNumber+"\n");
                } else  {//没通过就移除
                    //System.out.println("==");
                    list.remove(list.size()-1);
                }
                flag++;
            }
            //System.out.println();
            if(flag<10000)
            {
                hm.put(index,list);
                index++;
                System.out.print(index+" ");
            }

        }

        //输出初始种群
        for (Integer integer : hm.keySet()) {
            System.out.println(integer+" "+" "+getShiYing(hm.get(integer)));
        }


        int gen = 0;
        System.out.println("开始迭代:");
        while (gen<Maxgen) {
            /*
             *
             * 找到交换的两个编码数组
             *
             * */
            //将当前种群的所有适应度算出,并放在shiying集合
            Double shiyingsum = 0D;//记录当前适应度的总和
            Double []shiying = new Double[hm.size()];//存储种群中每个编码适应度
            int [] key = new int[hm.size()];//map中key的集合
            int kI = 0;
            for (Integer integer : hm.keySet()) {
                key[kI] = integer;
                kI++;
            }



            int i = 0;
            for (Integer integer : hm.keySet()) {
                Double shiYing = getShiYing(hm.get(integer));//计算出适应度
                shiying[i] = shiYing;//适应度放在集合中
                shiyingsum = shiyingsum+shiYing;//存储总的适应度
                i++;
            }
            double r1 = nextDouble(0, shiyingsum);//第一个数组所在赌盘位置
            double r2 = nextDouble(0, shiyingsum);//第二个数组所在赌盘位置

            int index1 = -1;//存储第一个数组在map集合中的索引
            int index2 = -1;//存储第二个数组在map集合中的索引
            Double temp = 0D;//存储当前转的位置
            //找到两个数组的索引
            for (int i1 = 0; i1 < shiying.length; i1++) {
                temp = temp + shiying[i1];
                if(index1 == -1)//没找到就继续找
                {
                    if(r1 <= temp)
                    {
                        index1 = key[i1];//找到就赋予索引
                    }
                }
                if (index2 == -1)//没找到就继续找
                {
                    if (r2 <=temp)
                    {
                        index2 = key[i1];//找到就赋予索引
                    }
                }


            }


            //取出两个数组
            ArrayList<Integer> list1 = hm.get(index1);
            ArrayList<Integer> list2 = hm.get(index2);
            //System.out.println("index1:"+index1+" index2:"+index2);
            //遍历两个数组 先执行交叉操作,再执行变异操作
            for (int i1 = 0; i1 < list1.size(); i1++) {
                //交叉操作
                double v = nextDouble(0, 1);//获取单点交换概率
                int l1 ;//存储交换的数组1的值
                int l2 ;//存储交换的数组2的值
                if(v<jiaochapro)//发生交叉
                {
                    //获取当前循环索引的值
                    l1 = list1.get(i1);
                    l2 = list2.get(i1);
                    //交换两个数组的值
                    list1.set(i1,l2);
                    list2.set(i1,l1);
                    if(isPass(list1)&&isPass(list2))
                    {
                        ;//如果都通过则交换成功
                    }else {
                        //如果没通过还原值
                        list1.set(i1,l1);
                        list2.set(i1,l2);
                    }

                }
                //变异操作
                //第一个编码变异
                double v1 = nextDouble(0, 1);//获取单点变异的概率
                if(v1<bianyipro)//发生变异
                {
                    int i2 = rand.nextInt(car_num)+1;// randNumber 将被赋值为1-14范围内的随机整数
                    //获取当前循环索引的值
                    int tmp1 = list1.get(i1);
                    list1.set(i1,i2);
                    if (isPass(list1))
                    {
                        ;
                    }else {
                        list1.set(i1,tmp1);
                    }
                }
                //第二个变异
                double v2 = nextDouble(0, 1);//获取单点变异的概率
                if(v2<bianyipro)//发生变异
                {
                    int i2 = rand.nextInt(car_num)+1;// randNumber 将被赋值为1-14范围内的随机整数
                    //获取当前循环索引的值
                    int tmp2 = list2.get(i1);
                    list2.set(i1,i2);
                    if (isPass(list2))
                    {
                        ;
                    }else {
                        list2.set(i1,tmp2);
                    }
                }


            }

            //向map中放回两个数组
            hm.put(index1,list1);
            hm.put(index2,list2);

            //找出适应度最差的 去除掉
            int shiyingIndex = -1;//记录最少的适应度的编码
            Double shiyingless = 1000D;//记录当前最少的适应度
            int j = 0;
            for (Integer integer : hm.keySet()) {
                Double shiYingDu = getShiYing(hm.get(integer));//计算出适应度
                if(shiYingDu<shiyingless)//迭代适应度 小于 最小适应度  就 把这个值赋予最小,并给出索引值
                {
                    shiyingless = shiYingDu;
                    shiyingIndex = j;//记录最小的索引,排第几个
                }
                j++;
            }
            System.out.print(gen+" ");
            //换行
            System.out.println();
            // System.out.println("remove:"+key[shiyingIndex]);
            hm.remove(key[shiyingIndex]);//通过前面的key集合,放入索引找到最小适应度的编码,删除
            //System.out.print("rest key:");
//            for (Integer integer : hm.keySet()) {
//                System.out.print(integer);
//            }
            //System.out.println("hm size:" +hm.size());



            gen++;//迭代完成后增加一次次数

        }
        //System.out.println();
        //输出结果
        ansflag = 1;//可以输出钱的数量了
        double[] Gtmp=new double[car_num];//
        double[] Vtmp=new double[car_num];//

        for (Integer integer : hm.keySet()) {
            System.out.println("最开始的编号"+integer+" "+"适应度:"+getShiYing(hm.get(integer))+" "+hm.get(integer));
            ArrayList<Integer> list = hm.get(integer);//获取到最后一个生者的数组
            HashMap<Integer, String> anshm = new HashMap<>();//存储最后的结果
            //初始化结果map
            for (Integer i = 0; i < car_num; i++) {
                anshm.put(i+1,"");
            }
            //遍历list
            for (int i = 0; i < list.size(); i++) {
                Gtmp[list.get(i)-1]=Gtmp[list.get(i)-1]+Gdanzi[i];
                Vtmp[list.get(i)-1]=Vtmp[list.get(i)-1]+Vdanzi[i];
                anshm.put(list.get(i),anshm.get(list.get(i))+(i+1)+" ");

            }
            //输出最后的结果
            for (Integer integer1 : anshm.keySet()) {
                System.out.println(integer1+"车:"+anshm.get(integer1));
            }
            System.out.println();
            int ii=0;
            for (double g : Gtmp) {
                ii++;
                System.out.print(ii+":"+g+";");
            }
            ii=0;
            System.out.println();
            for (double v : Vtmp) {
                ii++;
                System.out.print(ii+":"+v+";");
            }


        }

    }


    //约束条件
    static public boolean isPass(ArrayList<Integer> list){
        Double Gsum = 0D;
        Double Vsum = 0D;
        //System.out.println(list);
        for (int i = 0; i < list.size(); i++) {//每次循环进入带按着顺序的数据,车号
            for (int i1 = 0; i1 < list.size(); i1++) {//叠加相同值,求其加起来的重量和体积,如果超过车的重量或者体积,则不可
                if (list.get(i).equals(list.get(i1))){
                    Gsum = Gsum + Gdanzi[i1];
                    Vsum = Vsum + Vdanzi[i1];
                }
            }
            if (Gsum > Gcar[list.get(i)-1] || Vsum > Vcar[list.get(i)-1])
            {
                //System.out.println(Gsum+" "+Vsum+" "+Gcar[list.get(i)-1]+" "+Vcar[list.get(i)-1]);
                return false;
            }
            Gsum = 0D;
            Vsum = 0D;
        }
        //全部通过,返回可以
        //System.out.println(list);
        return  true;
    }
    //算适应度
    static public Double getShiYing(ArrayList<Integer> list){
        Double monsum = 0D;
        int [] count = new int[car_num];//记录是否该车出现过
        for(int i=0; i<car_num; i++)
        {
            count[i]=0;
        }
        //开始算钱,不是第一次,则换另外的加钱
//        for (Integer integer : list) {
//            if (count[integer-1]==0)
//            {
//                monsum = monsum+qibujia[integer-1];
//                count[integer-1]++;
//            }else {
//                monsum = monsum+dianweifei[integer-1];
//            }
//        }
        //*****
        //开始算钱,遍历
//        ArrayList<TreeSet<Double>> jings = new ArrayList<>();//保留不同的经度
//        ArrayList<TreeSet<Double>> weis = new ArrayList<>();//保留不同的纬度
//
//        //chushihua
//        for (Integer i = 0; i < car_num; i++) {
//            TreeSet<Double> jing = new TreeSet<>();
//            TreeSet<Double> wei = new TreeSet<>();
//            jings.add(i,jing);
//            weis.add(i,wei);
//        }
//        //tianjiashuju
//        int i = 0;//diedai
//        for (Integer integer : list) {
//            jings.get(integer-1).add(jingdu[i]);
//            weis.get(integer-1).add(weidu[i]);
//            i++;
//        }
//
//        //tianjiawancheng
//        //suanqian
//        int j = 0;//dijiliang
//
//        for (TreeSet<Double> jing : jings) {
//            int flag = 0;//biaojishifoujiadiyici
//            Double  tmpSum = 0D;
//            Double  befSum =monsum;
//            for (Double aDouble : jing) {
//                if (flag==0)
//                {
//                    flag=1;
//                    monsum=monsum+qibujia[j];
//                }else monsum=monsum+dianweifei[j];
//            }
//            tmpSum = monsum - befSum;
//            if(ansflag==1)
//            {
//                System.out.print("***"+tmpSum+" ");
//            }
//            j++;
//        }
//
//
//        //最后输出结果了 可以输出总金额
//        if(ansflag == 1)
//        {
//            System.out.println();
//            for (TreeSet<Double> jing : jings) {
//                System.out.print(jing);
//                System.out.println(" "+jing.size()+" ");
//            }
//            System.out.println();
//            for (TreeSet<Double> wei : weis) {
//                System.out.print(wei);
//                System.out.println(" "+wei.size()+" ");
//            }
//            System.out.println();
//            System.out.print("总金额为:"+monsum+" ");
//        }
        //********
        ArrayList<ArrayList<Double>> jings = new ArrayList<>();//保留不同的经度
        ArrayList<ArrayList<Double>> weis = new ArrayList<>();//保留不同的纬度

        //chushihua
        for (Integer i = 0; i < car_num; i++) {
            ArrayList<Double> jing = new ArrayList<>();
            ArrayList<Double> wei = new ArrayList<>();
            jings.add(i,jing);
            weis.add(i,wei);
        }
        //tianjiashuju
        int i = 0;//diedai
        for (Integer integer : list) {
            jings.get(integer-1).add(jingdu[i]);
            weis.get(integer-1).add(weidu[i]);
            i++;
        }

        //tianjiawancheng
        //suanqian
        int j = 0;//dijiliang

        for (ArrayList<Double> jing : jings) {
            jing = new ArrayList<Double>(new LinkedHashSet<Double>(jing));//quchong
            jings.set(j,jing);//huanxinde
            int flag = 0;//biaojishifoujiadiyici
            Double  tmpSum = 0D;
            Double  befSum =monsum;
            for (Double aDouble : jing) {
                if (flag==0)
                {
                    flag=1;
                    monsum=monsum+qibujia[j];
                }else monsum=monsum+dianweifei[j];
            }
            tmpSum = monsum - befSum;
            if(ansflag==1)
            {
                System.out.print("***"+tmpSum+" ");
            }
            j++;
        }
        j=0;
        for (ArrayList<Double> wei : weis) {
            wei=new ArrayList<Double>(new LinkedHashSet<Double>(wei));//quchong
            weis.set(j,wei);//huanxinde
            j++;
        }
        //最后输出结果了 可以输出总金额
        if(ansflag == 1)
        {
            System.out.println();
            for (ArrayList<Double> jing : jings) {
                System.out.print(jing);
                System.out.println(" "+jing.size()+" ");
            }
            System.out.println();
            for (ArrayList<Double> wei : weis) {
                System.out.print(wei);
                System.out.println(" "+wei.size()+" ");
            }
            putAnsIntoTxt(jings,weis);
            System.out.println();
            System.out.print("总金额为:"+monsum+" ");
        }








        //适应度为钱的倒数
        return 1/monsum;
    }
    //生成min到max的随机double类的数字
    static public  double nextDouble(final double min, final double max) {
        return min + ((max - min) * new Random().nextDouble());
    }
    //得到刚好重量与体积都大于该订单的车型索引
    static public  int getCarIndex(int DanziIndex)
    {
        //遍历车型,如果找到就返回索引
        for (int i = 0; i < car_num; i++) {
            if((Gdanzi[DanziIndex]<=Gcar[i])&&(Vdanzi[DanziIndex]<=Vcar[i]))
            {
                return i;
            }
        }
        //如果没有就返回-1
        return -1;

    }
    //生成int min到max 的int值 都包含
    public static int getRandomNumberFrom(int min, int max) {
        Random foo = new Random();
        int randomNumber = foo.nextInt((max + 1) - min) + min;

        return randomNumber;
    }
    //将每个车到的经纬度输出到文本中
    public static void  putAnsIntoTxt( ArrayList<ArrayList<Double>> jings,ArrayList<ArrayList<Double>> weis)
    {
        ArrayList<Double> list = new ArrayList<>();
        for (ArrayList<Double> jing : jings) {
            for (Double aDouble : jing) {
                list.add(aDouble);
            }
        }
        list = new ArrayList<Double>(new LinkedHashSet<Double>(list));//quchong

        System.out.println("总共点数:"+list.size());
        try(//创建输入和输出流  结束自动销毁
            FileOutputStream fos = new FileOutputStream("D:\\zhongguowaiyunbei\\全国物流设计大赛资料\\中外运杯设计大赛案例(1)(1)\\中外运案例发布稿10.1\\附件\\中国外运杯案例附件\\配载地点经度.txt");
            BufferedWriter bs = new BufferedWriter(new OutputStreamWriter(fos,"utf-8"));
            FileOutputStream fos1 = new FileOutputStream("D:\\zhongguowaiyunbei\\全国物流设计大赛资料\\中外运杯设计大赛案例(1)(1)\\中外运案例发布稿10.1\\附件\\中国外运杯案例附件\\配载地点纬度.txt");
            BufferedWriter bs1 = new BufferedWriter(new OutputStreamWriter(fos1,"utf-8"));
        ) {
            //xunhuanshuchu

                for (ArrayList<Double> jing : jings) {
                    for (Double aDouble : jing) {
                     bs.write(String.valueOf(aDouble)+" ");
                    }
                    bs.newLine();
                    bs.flush();
                }
                for (ArrayList<Double> wei : weis) {
                    for (Double aDouble : wei) {
                        bs1.write(String.valueOf(aDouble)+" ");
                    }
                    bs1.newLine();
                    bs1.flush();
                }




        }catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

结果
在这里插入图片描述
通过生成的经纬度,使用高德地图的api在html上画行驶的图,动态的,这里放个截图,哈哈
在这里插入图片描述

感想:还是挺可惜的,如果能进行比赛就好了,比赛要求是做算法,网站或者app,app前端已经差不多胡出来了,网站本来也可以写,但是没时间了,后端本来想进了才写,可惜没进,打算是用百度地图或者其他地图进行经纬度定位,反馈数据,实时监控位置信息,但是好像个人申请不了这么多的请求,就一直会有错,也还没去解决,可惜,写下这篇文章来记录下大三上努力过的比赛。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值