QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 7734|回复: 1
打印 上一主题 下一主题

数学建模(5)——改良圈算法

[复制链接]
字体大小: 正常 放大
浅夏110 实名认证       

542

主题

15

听众

1万

积分

  • TA的每日心情
    开心
    2020-11-14 17:15
  • 签到天数: 74 天

    [LV.6]常住居民II

    邮箱绑定达人

    群组2019美赛冲刺课程

    群组站长地区赛培训

    群组2019考研数学 桃子老师

    群组2018教师培训(呼伦贝

    群组2019考研数学 站长系列

    跳转到指定楼层
    1#
    发表于 2018-11-17 09:23 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta |邮箱已经成功绑定
    摘要: 本文讲的是数学建模(5)——改良圈算法, 改良圈算法可得到旅行商问题的较好解,遗传算法那章就是利用该算法得到初始种群 基本原理 首先求得一个Hamilton圈,然后修改圈得到具有较小权的另一个Hamilton圈,直至无法改进则停止 构建新圈 。$ V( {! t" y! k
    改良圈算法可得到旅行商问题的较好解,遗传算法那章就是利用该算法得到初始种群 基本原理
    首先求得一个Hamilton圈,然后修改圈得到具有较小权的另一个Hamilton圈,直至无法改进则停止 构建新圈
    对于 1≤i<i+1<j≤n,构建新的Hamilton圈 2 h5 e' }$ t* c& U! R/ g
    Cij = v1v2…vivjvj-1vj-2…vi+1vJ+1vJ+2…vnv1 5 X( l3 }% b8 V& M; p5 k& C8 J
    它是由C中将vi和vj之间的边逆序得到的。
    6 _9 ~0 g  g) T: K# h- m% j若 w(vivj)+w(vi+1vj+1)<w(vivi+1)+w(vjvj+1) % C' \4 X' h/ \1 Q
    则该圈替换有效
    使用该算法得到的只是较好解,几乎可以肯定不是最优解 代码实例
    clear,clc a=[0 56 35 21 51 60 56 0 21 57 78 70 35 21 0 36 68 68 21 57 36 0 51 61 51 78 68 51 0 13 60 70 68 61 13 0]; L=size(a,1); c=[5 1:4 6 5];%选择初始圈 [circle,long]=modifycircle(a,L,c)function [circle,long]=modifycircle(a,L,c); for k=1 flag=0;%退出标志 for m=1-2 %m为算法中的i for n=m+2%n为算法中的j if a(c(m),c(n))+a(c(m+1),c(n+1))<a(c(m),c(m+1))+a(c(n),c(n+1)) c(m+1:n)=c(n:-1:m+1); flag=flag+1;%修改标志+1 end end end if flag==0%一条边也没修改,直接返回 long=0; for i=1 long=long+a(c(i),c(i+1)); end circle=c;%返回修改圈 return end end
    以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索matlab , 算法 , 数学建模 解优化 ,以便于您获取更多的相关知识。
    生命不止,继续 go go go !!!
    上一篇博客跟大家介绍了,如何实现一个简单的tcp服务器和客户端,那么在此基础上,继续深耕一点点,介绍一下如何创建一个聊天室。
    当然,还是还是一个要有一个服务端和若干个客户端。
    server . p1 C/ o3 d+ [0 I" @- N, D$ D3 r' `  |
    net.Listen ; k$ y. \. L* p; ^! F& W
    Accept
    9 ]6 V1 U; X* w这两个方法就不介绍了,之前都有提到过。
    声明一个net.Conn数组,用于存放连接服务器的客户端:
    var clients []net.Conn
    大部分跟之前提到的tcp的server/client没有区别,最大的区别就是服务端收到消息后需要通知各个客户端,所以可以通过遍历数组cliQue来完成消息的通知。这里用到了for…range循环:
    func notify(conn net.Conn, msg string) { for _, con := range clients { if con.RemoteAddr() != conn.RemoteAddr() { con.Write([]byte(msg)) } } }
    顺便介绍一下RemoteAddr
    func (c *IPConn) RemoteAddr() Addr
    作用:
    . ~+ d: C/ K/ o/ c0 `+ r- \RemoteAddr returns the remote network address. The Addr returned is shared by all invocations of RemoteAddr, so do not modify it.
    有一个客户端离开聊天室的时,要通知所有的客户端:
    func disconnect(conn net.Conn, name string) { for index, con := range clients { if con.RemoteAddr() == conn.RemoteAddr() { disMsg := name + " has left the room." fmt.Println(disMsg) clients = append(clients[:index], clients[index+1:]...) notify(conn, disMsg) } } }
    Go语言函数中有三个点…表示为可变参数,可以接受任意个数的参数。
    append主要用于给某个切片(slice)追加元素
    如果该切片存储空间(cap)足够,就直接追加,长度(len)变长;如果空间不足,就会重新开辟内存,并将之前的元素和新的元素一同拷贝进去
    第一个参数为切片,后面是该切片存储元素类型的可变参数
    client # j6 P; P+ G' ~* G1 ?; y& C  ^
    客户端的代码就相对简单了很多。net.Dial也不再赘述。   n: M5 U/ E6 u& f8 M& j4 C5 m
    注意就是从conn读数据,这里readStr[:length]用到了切片。
    func read(conn net.Conn) { for { length, err := conn.Read(readStr) if err != nil { fmt.Printf("Error when read from server. Error:%s\n", err) os.Exit(0) } fmt.Println(string(readStr[:length])) } }
    完整代码
    2 y& `7 r9 ^; h# n服务端:
    package main import ( "fmt" "net" "os" ) var clients []net.Conn func main() { var ( host = "localhost" port = "8000" remote = host + ":" + port data = make([]byte, 1024) ) fmt.Println("Initiating server...") lis, err := net.Listen("tcp", remote) defer lis.Close() if err != nil { fmt.Printf("Error when listen: %s, Err: %s\n", remote, err) os.Exit(-1) } for { var res string conn, err := lis.Accept() if err != nil { fmt.Println("Error accepting client: ", err.Error()) os.Exit(0) } clients = append(clients, conn) go func(con net.Conn) { fmt.Println("New connection: ", con.RemoteAddr()) // Get client's name length, err := con.Read(data) if err != nil { fmt.Printf("Client %v quit.\n", con.RemoteAddr()) con.Close() disconnect(con, con.RemoteAddr().String()) return } name := string(data[:length]) comeStr := name + " entered the room." notify(con, comeStr) // Begin recieve message from client for { length, err := con.Read(data) if err != nil { fmt.Printf("Client %s quit.\n", name) con.Close() disconnect(con, name) return } res = string(data[:length]) sprdMsg := name + " said: " + res fmt.Println(sprdMsg) res = "You said:" + res con.Write([]byte(res)) notify(con, sprdMsg) } }(conn) } } func notify(conn net.Conn, msg string) { for _, con := range clients { if con.RemoteAddr() != conn.RemoteAddr() { con.Write([]byte(msg)) } } func disconnect(conn net.Conn, name string) { for index, con := range clients { if con.RemoteAddr() == conn.RemoteAddr() { disMsg := name + " has left the room." fmt.Println(disMsg) clients = append(clients[:index], clients[index+1:]...) notify(conn, disMsg) } } }
    客户端:
    package main import ( "bufio" "fmt" "net" "os" ) var writeStr, readStr = make([]byte, 1024), make([]byte, 1024) func main() { var ( host = "localhost" port = "8000" remote = host + ":" + port reader = bufio.NewReader(os.Stdin) ) con, err := net.Dial("tcp", remote) defer con.Close() if err != nil { fmt.Println("Server not found.") os.Exit(-1) } fmt.Println("Connection OK.") fmt.Printf("Enter your name: ") fmt.Scanf("%s", &writeStr) in, err := con.Write([]byte(writeStr)) if err != nil { fmt.Printf("Error when send to server: %d\n", in) os.Exit(0) } fmt.Println("Now begin to talk!") go read(con) for writeStr, _, _ = reader.ReadLine() if string(writeStr) == "quit" { fmt.Println("Communication terminated.") os.Exit(1) } in, err := con.Write([]byte(writeStr)) if err != nil { fmt.Printf("Error when send to server: %d\n", in) os.Exit(0) } } } func read(conn net.Conn) { for { length, err := conn.Read(readStr) if err != nil { fmt.Printf("Error when read from server. Error:%s\n", err) os.Exit(0) } fmt.Println(string(readStr[:length])) } }
    创建一个本地代码库

    8 m3 ~9 R2 \) ~2 ]3 r7 w1 U
    切换到你需要创建的代码库的目录下:

    * Z: n  Z$ L, h4 l  ^# B
    运行如下git命令

    7 z1 w3 n8 x7 b$ f
    git --bare init

    4 a! ~8 R0 x- I% b* `3 M6 ~
    git下会出现一些隐藏的文件,这些文件时git本地库的描述文件
    , X- ~; `0 h7 ^7 I  ?2 d
    加载项目文件
    ' a1 K( w* n! U7 g0 R* p! A3 v

    7 ]2 X9 f1 B2 B) B2 r" |$ K. o
    git add .  
    最后的符号“.”是指 “所有的文件,文件夹,和子文件夹”。如果我们只想将特警的文件添加到库中去,我们可以指定它们:
    * [9 ^; {" c7 v' t% N3 c% e
    git add my_file,my_file2 ,my_file3
    + V" H$ a0 s; b. Q2 {
    提交添加的文件

    ( C- r! V. G6 X8 j6 i# Q7 G1 d9 B9 c5 Y+ @! ~
    git commit -m "initial commit"
    这个命令之后就提交了所有加载的文件,如果需要查看状态可以使用:git status

    + s: _" f# E- M8 r) N2 @
    推送到远程的代码库
    # i  F+ T5 v; g3 c4 Y' g7 r
    如果你想将你的本地代码推送到远程代码库,你需要将它添加到你的项目配置里,如下:
    git remote add  <name> https://<your_userName>@<center_address>/<your_userName>/<remote_repository_name>.git
    5 k$ i' f* ?; E) x4 f
    然后运行如下代码推送到远程库:
    % [2 W# {0 J2 a9 ^! L/ \' w
    git push <name>  <分支名称>

    6 \# S0 d% k4 T$ H) l
    & |! _3 h5 I, X% r2 `# P
    克隆远程库到本地
    9 p; V& O6 G. x0 a" y" f; W

    1 D: J$ \, a3 ^+ o/ Y# x" p# F7 S" Q! \5 Z% n

    - V9 K/ }  S) z+ T1 C1 f8 ~- h9 ^
    : ?; j$ p: F8 Z/ \4 a$ K

    * k- O+ i7 p- W5 F8 v4 |7 x
      R; x5 t% i. d6 `0 G0 w$ K. ]" K

    # I' b6 n: U% T$ j+ _* n+ L( W: U4 q
    + w% p/ z+ [; g% B; m' R  c2 r1 _
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    柒七日        

    0

    主题

    2

    听众

    2

    积分

    升级  40%

    该用户从未签到

    自我介绍
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-7-29 10:10 , Processed in 0.574469 second(s), 63 queries .

    回顶部