15

平面グラフとC++での色付けについて学んでいます。しかし、私はこの作業を行うためのアルゴリズムをインストールすることを知りません。誰か助けてくれませんか?

ここに私はあなたのためにいくつかの情報を持っています!これが私のコードです!そして、それはまだ機能が終了していません。誰かが「平面グラフ」とは何かを知っている場合は、以下のPlanar_Graph関数を修正してください。:Dどうもありがとう!:バツ

# define MAX 100

int kt[MAX];
int tk=0;

int my_array[MAX][MAX];      // Graph
FILE *f;
int n,m;            //m: Edge, n: Vertex
int index[MAX];            
int ke[MAX];      
int Color[MAX]   ;      //Color Array
int colors_max;      
char filename[MAX];

int input(char filename[MAX])   
{
    int i,j;

    f = fopen(filename,"r");
    if (f== NULL)
    {
        printf("\n Error \n");
        return 1;
    }
    else
    {
        printf("File mane: %s \n",filename);
        printf("Content   :\n");
        fscanf(f,"%d",&n);
        fscanf(f,"%d",&m);

        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                fscanf(f,"%d",&my_array[i][j]);
                printf("%d   ",my_array[i][j]);
            }
            printf("\n");
        }      
        return 0;
    }   
}

void Default()   

{
    for(int i=0;i<colors_max;i++)
    Color[i]= i;
}

void Init()             
{
    filename[0]=NULL;
    n = 0;
}


int Planar_Graph(int my_array[MAX][MAX],int n, int m) // This is my problem
{

    /* for(int i=0;i<n;i++)

        if(n>=2 && (int)(n+1)*(n-2)/(n-1)>=m)
        return 1;
    }
    else
    {
        return 0;
    } */

}

int max()
{
    int max;
    int count=0;
    for(int i=0;i<n;i++)
    {       
        count = 0;
        for(int j=0;j<n;j++)   
            if (my_array[i][j] > 0)   
                count++ ;
        if (max < count)      
            max = count;
    }
    return max+1;
}

void Check(int x,int y)      // Check around
{
    int i;
    Default();         
    for(i=0;i<n;i++)
    {
        if (my_array[x][i] != -1)   // if edge [x,ke[i]] is color t
            Color[my_array[x][i]] = -1;   // then Color[t] = 0
    }

    for(i=0;i<n;i++)
    {
        if (my_array[y][i] != -1)
            Color[my_array[y][i]] = -1;

    }
}

void Coloring()
{
    int t;
    for(int i=0;i<n;i++)
      for(int j=0;j<n;j++)
         if (my_array[i][j] > 0)
         {
            Check(i,j) ;
            for(t=0;t < colors_max;t++)
               if (Color[t] == t)
               {
                  my_array[i][j] = t;
                  my_array[j][i] = t;
                  break;
               }
         }
}

void main()
{

    if(input("input.txt")!=1)
    {
         Default();
         colors_max =  max()    ;
         Coloring();
         printf("\n Result:\n\n");
         Planar_Graph(my_array,n,m);
         for(int i=0;i<n;i++)
         {
              for(int j=0;j<n;j++)
                if (my_array[i][j]>0)
                {
                    printf(" %c,%c] coloring %d \n",i + 'A',j + 'A',my_array[i][j]) ;
                    my_array[i][j] = -1;
                    my_array[j][i] = -1; 
                }
                printf("\n") ;
         }

    }

}

入力ファイルの例:

10 18
0 1 0 1 1 1 0 0 0 0
1 0 1 0 0 0 0 0 0 0
0 1 0 0 1 0 0 0 0 0
1 0 0 0 1 0 1 1 0 0
1 0 1 1 0 1 1 0 1 0
1 0 0 0 1 0 1 0 1 0
0 0 0 1 1 1 0 1 0 0
0 0 0 1 0 0 1 0 1 1
0 0 0 0 1 1 0 1 0 1
0 0 0 0 0 0 0 1 1 0
4

4 に答える 4

42

平面性について...

ここで言及されているEullerによるよく知られているe<=3v-6基準は、グラフが平面である場合、その条件が成立する必要があることを示しています。ただし、その条件が当てはまるすべてのグラフが必ずしも平面であるとは限りません。そのため、実際には平面性テストアルゴリズムが必要です。

注意すべき点は、平面性テストアルゴリズムの実装は簡単ではないということです。サブグラフの検索と削除に基づく非常に古いものがあります。現在、元の作者を思い出せませんが、彼らのアルゴリズムの問​​題は、O(n³)の複雑さがあることです。

効率的であると考えられる最初の平面性テストアルゴリズム(この場合はO(n))は、HopcroftとTarjanによるものです。これは、YinZhuによる投稿ですでに言及されています。元の論文はここにあります

今回のアルゴリズムの問​​題点は、多くの人が理解しにくく、実装すら難しいと感じていたことです。そのため、元の論文のポイントを明確にすることだけを目的とした論文があります。たとえば、コケイ紙

Hopcraft-Tarjanの論文は古典的であり、それを実装しようとする場合、私が持っている最良の参考資料は、C++実装と一緒に理論を提示するこの他の論文です。これは、 LEDAライブラリにアルゴリズムを実装した人々によって書かれました。

Hopcroft-Tarjanの論文(1974年)の数年後、他のO(n)アルゴリズムが公開されました。それらについてはよくわかりませんが、PC/PQツリーを使用しているものもあります。しかし、私が読んで非常に興味深いものが1つあります。これはBoyerとMyrvoldによるもので、2004年のものです。ここで見つけることができます。もちろん、アルゴリズム自体に加えて、このペーパーの良い点は、平面性テストアルゴリズムに関する厳密な履歴リファレンスを提供することです。

ごく最近、Tarjanが著者の1人である2008年の別の論文を発見しました。まだチェックしていません。

さて、この投稿を読んだだけで疲れたら、独自のアルゴリズムを実装したくないと思います。:)この場合、私はいくつかのC++ライブラリをお勧めできます。

  • ブースト
  • GDToolkit
  • LEDA
  • OGDF
  • GTAD-これは私自身のグラフライブラリです(残念ながら、最近は作業できませんでした)。私が言及したその論文に基づいて書いたHopcroft-Tarjanアルゴリズムの実装があります。論文はすでに実際のコードを提供しているので、物事ははるかに簡単です。
于 2009-12-06T12:27:29.887 に答える
6

無向グラフを平面でテストするかどうかは十分に解決されており、効率的なアルゴリズムが存在します。これは実際にはR.タージャンの1986年チューリング賞作品の一部です。

最初にこのメモを確認できます。http://bkocay.cs.umanitoba.ca/G&G/articles/Planarity.pdf

TarjanとHopcraftの元の論文を確認することもできます:http://portal.acm.org/citation.cfm?id = 321852

アルゴリズムに大きな進歩があったかどうかはわかりません。しかし、T&Hのアルゴリズムはすでに非常に高速です。

ところで、アルゴリズムの実装は非常に難しく、wikiページの定理は効率的な実装の手がかりを与えません(簡単ですが)。

于 2009-12-06T08:17:51.090 に答える
1

あなたの質問は2つのトピックをカバーしているようです:-グラフは平面ですか?(あなたのタイトル)-(もしそうなら?)どうすればそれを着色できますか(あなたは何色かは言いません)。

最初の部分では、ウィキペディアに役立つセクションがあります:http: //en.wikipedia.org/wiki/Planar_graph

あなたはそれを完全に読むべきです、しかしそれは平面性のための2つの簡単な要件を与えます:

v個の頂点とe個のエッジを持つ単純な接続された平面グラフの場合、次の単純な平面性基準が成り立ちます。

定理1.v≥3の場合、e≤3v− 6;
定理2。v >3で、長さ3のサイクルがない場合、e≤2v−4。

頂点とエッジを保持できるデータ構造を作成する必要があります。次に、長さ3(三角形)のサイクルを決定できる必要があります。

于 2009-12-06T08:17:11.280 に答える
0

Graphanalyzer(http://grafoanalizator.unick-soft.ru/program/indexen.php)を使用してみることができます。または、プログラムのAutorに質問を送信します。

于 2010-02-15T21:49:07.803 に答える