1. 程式人生 > >遺傳演算法解決揹包問題

遺傳演算法解決揹包問題

//總體思想與之前的相似,評價函式就是物品的價值之和,但要注意一旦物品的重量大於揹包的重量,那麼該條染色體的倖存概率為0
//基因就是每一個物品是否選擇,這裡預設有10條染色體在比較,並且每一條染色體上的第i個基因就是代表第i個物品是否選擇
//突變就是隨機選擇的染色體的隨機位置由0變1,由1變0
//另外建議把變異的概率調高點,否則有可能會陷入區域性最優
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#define num 10//種群的大小
#define pm 0.1//變異的概率
#define pc  0.8//交配的概率
#define MAX 100//最大迭代次數
int n,m;//n為物品種類,m為揹包容積大小
int v[10];//每一個物品的價值
int w[10];//每一個物品的重量
typedef struct node
{
    int beibao[10];//描述每一個物品的狀態
    int adapt;//表示這種裝入方法的適應值
    double p;//倖存的概率
}node;
node group[num],grouptemp[num];
void groupproduce()
{
    int i,j,t,wsum;
    srand(time(NULL));
    for (i=0;i<num;i++)
    {
        wsum=0;
     for (j=0;j<n;j++)
     {
         t=rand()%100;
         if (t<=49)
           group[i].beibao[j]=0;
         else
           group[i].beibao[j]=1;
        wsum=wsum+group[i].beibao[j]*w[j];
      }
      if (wsum>m)
      i--;
     }
    printf("初始狀態為:\n");
    for (i=0;i<num;i++)
    {
      for (j=0;j<n;j++)
        printf("%d",group[i].beibao[j]);
        printf("\n");
    }
}
void pingjia()
{
    int i,j,vsum,wsum,sum;
    sum=0;
    for (i=0;i<num;i++)
    {
        vsum=0;//物品的總價值
        wsum=0;//物品的總容積(只要超過m一律認為適應性為0)
        for (j=0;j<n;j++)
         {
             vsum=vsum+group[i].beibao[j]*v[j];
             wsum=wsum+group[i].beibao[j]*w[j];
         }
         if (wsum>m)
            group[i].adapt=0;
         else
            group[i].adapt=vsum;
            sum=sum+group[i].adapt;
     }
     for (i=0;i<num;i++)
     group[i].p=group[i].adapt*1.0/sum;//計算倖存概率
     for (i=0;i<num;i++)
        printf("第%d條染色體價值為%d,倖存概率為%.4f\n",i,group[i].adapt,group[i].p);
}
void xuanze()
{
   int i,j,temp;
   double gradient[num];
   double t;
   int xuan[num];
   for (i=0;i<num;i++)
    gradient[i]=0.0;
    gradient[0]=group[0].p;
    for (i=1;i<num;i++)
    gradient[i]=gradient[i-1]+group[i].p;
    srand(time(NULL));
    for (i=0;i<num;i++)
    {
        t=rand()%100;
        t=t/100;
        for (j=0;j<num;j++)
            if (gradient[j]>t)
            {
                xuan[i]=j;
                break;
            }
    }
   for (i=0;i<num;i++)
        {
        for (j=0;j<n;j++)
        grouptemp[i].beibao[j]=group[i].beibao[j];
        grouptemp[i].adapt=group[i].adapt;
        grouptemp[i].p=group[i].p;
        }
        for (i=0;i<num;i++)
        {
            temp=xuan[i];
            group[i].adapt=grouptemp[temp].adapt;
            group[i].p=grouptemp[temp].p;
            for (j=0;j<n;j++)
            group[i].beibao[j]=grouptemp[temp].beibao[j];
        }
}
void jiaopei()
{
  int i,j,t,c,d;
  double jiaopeip[num];
  int jiaopeiflag[num],temp,temp1,temp2,duan;
  srand(time(NULL));
  t=0;
  for (i=0;i<num;i++)
  {
      jiaopeip[i]=rand()%100;
      jiaopeip[i]=jiaopeip[i]/100;
      if (jiaopeip[i]<pc)
       jiaopeiflag[t]=i;
       t++;
  }
  t=t/2*2;
  srand(time(NULL));
  c=0;
  d=1;
  printf("%d\n",t);
  for (i=0;i<t/2;i++)
  {
     temp1=jiaopeiflag[c];
     temp2=jiaopeiflag[d];
     c=c+2;
     d=d+2;
     duan=rand()%num;//隨機斷點
     for (i=0;i<duan;i++)//斷點之前的部分交換基因
     {
         temp=group[temp1].beibao[i];
         group[temp1].beibao[i]=group[temp2].beibao[i];
         group[temp2].beibao[i]=temp;
     }
    }

}
void bianyi()
{
    int i,j,t;
    double bianyip[num];
    int bianyiflag[num];
    srand(time(NULL));
    memset(bianyiflag,0,sizeof(bianyiflag));
    for (i=0;i<num;i++)
    {
        bianyip[i]=rand()%100;
        bianyip[i]=bianyip[i]/100;
        if (bianyip[i]<pm)
            bianyiflag[i]=1;
    }
    srand(time(NULL));
    for (i=0;i<num;i++)
        if (bianyiflag[i]==1)
    {
        t=rand()%num;//隨機生成變異基因
        group[i].beibao[t]=1-group[i].beibao[t];//0變為1,1變為0
    }
}
void shuaixuan()
{
    int i,j;
    double max=group[0].p;
    for (i=1;i<num;i++)
    if (max<group[i].p)
    {
        max=group[i].p;
        j=i;
    }
    printf("最優選擇為:\n");
    for (i=0;i<n;i++)
    printf("%d ",group[j].beibao[i]);
    printf("\n");
    printf("最多獲利為:%d\n",group[j].adapt);
}
int main()
{
    int i,t;
    printf("請輸入揹包種類n\n");
    scanf("%d",&n);
    printf("請輸入每一個揹包的重量和價值\n");
    for (i=0;i<n;i++)
    scanf("%d%d",&w[i],&v[i]);
    printf("請輸入揹包容積\n");
    scanf("%d",&m);
    groupproduce();//生成初始種群
    t=0;
    while(t<MAX)
    {
        pingjia();
        xuanze();
        jiaopei();
        bianyi();
        t++;
    }
    pingjia();//最後還要進行一次評價,因為之前交配時更改過beibao(與adapt不對應)
    shuaixuan();
    return 0;
}

相關推薦

遺傳演算法解決揹包問題

//總體思想與之前的相似,評價函式就是物品的價值之和,但要注意一旦物品的重量大於揹包的重量,那麼該條染色體的倖存概率為0 //基因就是每一個物品是否選擇,這裡預設有10條染色體在比較,並且每一條染色體上的第i個基因就是代表第i個物品是否選擇 //突變就是隨機選擇的染色體的隨

遺傳演算法解決推箱子問題

遺傳演算法 遺傳演算法(Genetic Algorithm)是一類借鑑生物界的進化規律(適者生存,優勝劣汰遺傳機制)演化而來的隨機化搜尋方法。最早聽說這個演算法是在一門公選課上,當時瞭解的還包括蟻群演算法等。總之,這種演算法通過模擬自然界物種的繁衍,來尋找適宜生存的種群,達到尋找相

遺傳演算法解決尋路問題——Python描述

概要 我的上一篇寫遺傳演算法解決排序問題,當中思想借鑑了遺傳演算法解決TSP問題,本質上可以認為這是一類問題,就是這樣認為:尋找到一個序列X,使F(X)最大。 詳解介紹 排序問題:尋找一個序列,使得這個序列的逆序對的倒數最大。 TSP問題:尋找一個序列,使得這個序列的總路徑長的倒數最大。 這兩個問題

【資料結構與演算法】貪心演算法解決揹包問題。java程式碼實現

揹包問題(貪心演算法) 貪心演算法思想 簡單的說,就是將大問題轉化為最優子問題,例如本題所要求的,揹包容量有限,要想使物品的總價值最高,那麼,我們必須儘可能的選擇權重高的(即單位價值更高)的物品進行裝載。 在揹包問題中,物品是可拆的,即可以分成任意部分進行裝載,而最終實現的目標是

數學建模 of python(用遺傳演算法解決TSP問題)

吉吉: 在這個問題中,我們的個體就是一條一條的路線了,其目的就是找到一條總距離最短的路線。基本步驟與前兩篇文章基本類似,不過在本問題中,我們用城市路線中每個城市的經緯度來表示個體(城市路線)的DNA。 在產生後代的過程中,需要注意的是,因為我們的個體是路線,所以不能將兩個

matlab手寫遺傳演算法解決一元函式最值問題(例項)

問題:找出y=x4-4x3+3x+5 (xÎ[0,6])在[0,6]之間的最小值。 思路:用33位0,1變數來編碼x,3位編碼整數,30位編碼小數。理論上30位編碼小數可以將最小值對應的x精確到小數點後九位. 下面是我解決這個問題所有的函式,複製就可以運行了,不明白可以私

遺傳演算法解決TSP旅行商問題(附:Python實現)

前言 我先囉嗦一下:不是很喜歡寫計算智慧的演算法,因為一個演算法就要寫好久。前前後後將近有兩天的時間。 好啦,現在進入正題。 巡迴旅行商問題(TSP)是一個組合優化方面的問題,已經成為測試組合優化新演算法的標準問題。應用遺傳演算法解決 TSP 問題,首先對訪問

遺傳演算法解決單變數函式值得優化問題

      最近稍微學習一下智慧演算法的設計,就滿Internet搜尋,最終發現遺傳演算法是大家學習最多的,也是在各個領域內進行函式優化,解析解求解過程中很重要的一種方法! 學習遺傳演算法,首先為了上手較快,我推薦大家先使用Matlab,這個工具進行矩陣分析有應用,真的很管

初學遺傳演算法解決tsp問題(C++)

前言 斷斷續續學遺傳到現在快一個禮拜了,之前一直在看思想,死想活想,始終不敢去自己程式碼實現。 今天硬著頭皮開始寫,寫不下去就找博文看,總算是初步的實現了,邁出了智慧演算法學習的第一小步,心情不可謂不激動。 好吧,說正經的。 tsp&

使用遺傳演算法解決多變數函式優化問題!

        很多朋友在碰到多變數值優化的問題的時候不能很好的將問題轉化,利用有效編碼的方法將解的個數,解的編碼很好的很合理的進行設計,因此不能利用遺傳演算法進行問題的求解!        其實,簡單的來說,就是將多個變數的數值編碼編排進去,進行組合,只需要增長基因個體的

遺傳演算法解決TSP問題

讀了原作者mylovestart用遺傳演算法實現的tsp問題,學習了ga演算法。 但發現原作者mylovestart的jiaopei()函式寫的有問題,交叉後要確保每個城市有且僅走了一次,修改了jiaopei()的程式碼如下: //交配,對每個染色體產生交配概率,滿足交配

遺傳演算法解決TSP問題實現以及與最小生成樹的對比

摘要: 本實驗採用遺傳演算法實現了旅行商問題的模擬求解,並在同等規模問題上用最小生成樹演算法做了一定的對比工作。遺傳演算法在計算時間和佔用記憶體上,都遠遠優於最小生成樹演算法。 程式採用Microsoft visual studio 2008 結合MFC基本對話方塊類庫開發。32位windows 7系統下除

物流路徑規劃用遺傳演算法解決例項

網上有很多關於遺傳演算法的教程,但基本千篇一律。這次物流課做了一個跟路徑規劃相關的案例,拿出來與大家分享。 先貼案例。案例摘自《企業物流管理》。 《 R&T批發公司》 R&T批發公司給全印度的零售商批發日用商品。公司在全國有很

遺傳演算法解決路線規劃問題(Vehicle Routing Problem based on GA)

I.問題描述 車輛路徑問題(Vehicle Routing Problem,VRP),車輛路徑問題是一種組合優化問題,它由Dantzig 和 Ramser在1959年共同提出。VRP是指一定數量的客戶,各自有不同數量的貨物需求,配送中心向客戶提供貨物,由一個車隊負責分送貨物

遺傳演算法解決車輛路徑問題

車輛路徑問題車輛路線問題(VRP)最早是由Dantzig和Ramser於1959年首次提出,它是指一定數量的客戶,各自有不同數量的貨物需求,配送中心向客戶提供貨物,由一個車隊負責分送貨物,組織適當的行車路線,目標是使得客戶的需求得到滿足,並能在一定的約束下,達到諸如路程最短、

遺傳演算法解決迷宮尋路問題(Java實現)

1.什麼是遺傳演算法? 就個人理解,遺傳演算法是模擬神奇的大自然中生物“優勝劣汰”原則指導下的進化過程,好的基因有更多的機會得到繁衍,這樣一來,隨著繁衍的進行,生物種群會朝著一個趨勢收斂。而生物繁衍過程中的基因雜交和變異會給種群提供更好的基因序列,這樣種群的繁

人工智慧-遺傳演算法解決推箱子問題現實

由於各種原因,可能存在諸多不足,歡迎斧正! 一、研究背景    推箱子游戲中的路徑查詢問題—給定一方格,求兩點最短距離。    傳統求兩點最短路徑的演算法有:      1.通用的搜尋演算法      2.解決無負權邊的帶權有向圖的單源最短路問題的Dijkstra演算

C語言編寫遺傳演算法解決TSP旅行商問題

最近在上計算智慧的課,老師剛剛教了遺傳演算法,佈置了用遺傳演算法解決TSP的問題的作業,於是經過幾小時的奮戰,終於編寫完成。 首先先對TSP問題進行分析。TSP問題,也就是旅行商問題,題目的大題內容是 一位旅行商,要遍遊N座城市(城市數量記為NUM_CITY), 已知每兩座

Java描述貪心演算法解決揹包問題

思路: 首先將物品根據價效比排好序在一個集合裡,價效比=價格/重量... 然後根據價效比從大到小依次依次放入揹包,如果沒辦法放入這個物品的全部,就放入一部分,如果可以放入全量物品,就放入全量物品。 Main.java的程式碼 import java.util.ArrayL

【搞搞演算法】用遺傳演算法解決多目標規劃問題_論文閱讀筆記

這是2014年4月在其他部落格寫的,轉帖到CSDN的部落格上。 許老師給了很多多目標GA的論文,全英文讀起來比較慢,用Google翻譯+靈格斯詞典解決了詞彙問題,理解起來並不是很難,這也是GA演算法的特點——演算法本身容易理解,演算法知識不全的人(比如我)也能比較快地運用