Hitung berapa banyak urutan jarak yang jauh dari yang lainnya

13

The Hamming jarak antara dua string dengan panjang yang sama adalah jumlah posisi di mana yang sesuai simbol yang berbeda.

Membiarkan Pmenjadi string biner panjang ndan Tmenjadi string biner panjang 2n-1. Kita dapat menghitung njarak Hamming antara Pdan setiap nsubstring Tdengan panjang dari kiri ke kanan dan menempatkannya ke dalam array (atau daftar).

Contoh urutan jarak Hamming

Biarkan P = 101dan T = 01100. Urutan jarak Hamming yang Anda dapatkan dari pasangan ini adalah 2,2,1.

Definisi kedekatan

Sekarang mari kita perhatikan dua urutan jarak Hamming tersebut. Katakan x = (0, 2, 2, 3, 0)dan y = (2, 1, 4, 4, 2)sebagai contoh. Kami mengatakan bahwa xdan yadalah closejika y <= x <= 2*yatau jika x <= y <= 2*x. Di sini, perkalian skalar dan ketidaksetaraan diambil secara elemen. Artinya, untuk dua urutan Adan B, A <= B iff A[i] <= B[i]untuk semua indeks i.

Perhatikan bahwa urutan jarak Hamming membentuk urutan parsial dengan cara membandingkannya. Dengan kata lain, banyak pasangan urutan tidak lebih besar atau sama atau lebih kecil dari atau sama satu sama lain. Sebagai contoh (1,2)dan (2,1).

Jadi menggunakan contoh di atas, (0, 2, 2, 3, 0) <= 2*(2, 1, 4, 4, 2) = (4, 2, 8, 8, 4)tetapi (0, 2, 2, 3, 0)tidak lebih besar dari (2, 1, 4, 4, 2). Juga (2, 1, 4, 4, 2)tidak lebih kecil dari atau sama dengan 2*(0, 2, 2, 3, 0) = (0, 4, 4, 6, 0). Akibatnya xdan ytidak dekat satu sama lain.

Tugas

Untuk meningkatkan nmulai dari n=1, pertimbangkan semua pasangan yang mungkin dari string biner Ppanjang ndan Tpanjang 2n-1. Ada 2^(n+2n-1)pasangan seperti itu dan karenanya banyak urutan jarak Hamming. Namun banyak dari sekuens tersebut akan identik. Tugasnya adalah menemukan ukuran rangkaian urutan Hamming terbesar sehingga tidak ada dua urutan yang saling berdekatan.

Kode Anda harus menampilkan satu nomor per nilai n.

Skor

Skor Anda secara umum adalah tertinggi yang dicapai nkode Anda di komputer saya dalam 5 menit (tapi baca terus). Waktunya adalah total waktu berjalan, bukan hanya waktu untuk itu n.

Untuk memberikan skor untuk jawaban yang tidak optimal, karena menemukan jawaban yang optimal kemungkinan akan sulit, kita akan membutuhkan sistem penilaian yang agak halus. Skor Anda adalah nilai tertinggi di nmana tidak ada orang lain yang memposting jawaban yang benar lebih tinggi untuk ukuran apa pun yang lebih kecil dari sama dengan ini. Misalnya, jika Anda menghasilkan 2, 4, 21dan orang lain mengeluarkan 2, 5, 15maka Anda hanya akan skor 1karena orang lain memiliki jawaban yang lebih baik n = 2. Jika Anda menghasilkan 2, 5, 21maka Anda akan mencetak skor 3tidak peduli apa yang orang lain hasilkan karena semua jawaban itu optimal. Jelas jika Anda memiliki semua jawaban optimal maka Anda akan mendapatkan skor untuk tertinggi yang nAnda posting. Namun, bahkan jika jawaban Anda tidak optimal, Anda masih bisa mendapatkan skor jika tidak ada orang lain yang bisa mengalahkannya.

Contoh jawaban dan contoh yang berhasil

(Jawaban ini belum dicentang. Verifikasi independen akan diterima dengan penuh syukur.)

Terima kasih untuk produk ETH:

  • n = 1 memberi 2.
  • n = 2 memberi 5.
  • n = 3 memberi 21.

Mari kita lihat n = 2lebih detail. Dalam hal ini daftar lengkap urutan jarak Hamming (diwakili oleh tuple di sini) adalah:

[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

Kita bisa melihat bahwa (0,0)itu tidak dekat dengan tuple lainnya. Bahkan jika kita mengambil (0, 0), (0, 1), (1, 0), (2, 1), (1,2)maka tidak satupun dari mereka tupel yang dekat dengan apa pun yang lain. Ini memberi skor 5untuk n = 2.

Untuk n = 3daftar lengkap urutan jarak Hamming yang berbeda adalah:

 [(0, 0, 0), (0, 0, 1), (0, 1, 1), (0, 1, 2), (0, 1, 3), (0, 2, 1), (0, 2, 2), (0, 2, 3), (0, 3, 0), (0, 3, 1), (1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 1, 0), (1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 2, 0), (1, 2, 1), (1, 2, 2), (1, 2, 3), (1, 3, 0), (1, 3, 1), (1, 3, 2), (2, 0, 1), (2, 0, 2), (2, 0, 3), (2, 1, 0), (2, 1, 1), (2, 1, 2), (2, 1, 3), (2, 2, 0), (2, 2, 1), (2, 2, 2), (2, 2, 3), (2, 3, 1), (2, 3, 2), (2, 3, 3), (3, 0, 2), (3, 0, 3), (3, 1, 0), (3, 1, 1), (3, 1, 2), (3, 2, 0), (3, 2, 1), (3, 2, 2), (3, 3, 2), (3, 3, 3)]

Dari 48sekuens tersebut, kita dapat memilih satu set ukuran 21sehingga tidak ada pasangan dalam set yang dekat satu sama lain.

Bahasa dan perpustakaan

Anda dapat menggunakan bahasa dan perpustakaan yang tersedia yang Anda suka. Jika memungkinkan, alangkah baiknya untuk dapat menjalankan kode Anda, jadi harap sertakan penjelasan lengkap tentang cara menjalankan / kompilasi kode Anda di Linux jika memungkinkan.

Mesin saya Pengaturan waktu akan dijalankan pada mesin 64-bit saya. Ini adalah instalasi ubuntu standar dengan RAM 8GB, Prosesor Delapan-Core AMD FX-8350 dan Radeon HD 4250. Ini juga berarti saya harus dapat menjalankan kode Anda.

Jawaban utama

  • Skor 4 untuk 2, 5, 21, 83, 361 oleh Christian Sievers. C ++
  • Skor 5 untuk 2, 5, 21, 83, 372 oleh fəˈnɛtɪk. Javascript

sumber
Setelah melihat pertanyaan Anda, itu menunjukkan beberapa kesamaan dengan mata - mata, direvisi pada hackerrank, yang merupakan masalah NP-lengkap
fəˈnɛtɪk
@ fəˈnɛtɪk Hebat! Perhatikan bahwa pertanyaan saya tidak memerlukan solusi optimal untuk mendapatkan skor yang baik.
@ fəˈnɛtɪk Bisakah Anda juga mengkonfirmasi jawaban 1,2,3 dalam pertanyaan?
@ fəˈnɛtɪk Saya sangat meragukan itu NP-keras. Anda harus menyandikan Set Packing atau masalah NP-complete lainnya ke dalam integer tunggal dengan hanya perubahan polinomial dalam ukuran masalah.
297 array hamming unik untuk 4, 2040 array unik untuk 5
fəˈnɛtɪk

Jawaban:

5

C ++ menggunakan perpustakaan igraph

Terima kasih atas kesempatan yang bagus untuk mempelajari perpustakaan baru!

Program ini sekarang menghitung dengan 2, 5, 21, 83, 361cepat. Anda dapat mengontrol pencetakan node dengan PRINTNODESkonstanta.

Grafik yang digunakan memiliki tepi ekstra antara node yang sesuai dengan vektor jarak di mana satu dekat (tetapi tidak sama) dengan yang lainnya terbalik. Yang mempercepat perhitungan, dan setiap set independen yang ditemukan tentu saja juga salah satu dari grafik asli. Juga, bahkan jika itu tidak sepenuhnya ditegakkan, set independen yang dihitung ditutup dalam pembalikan. Saya percaya selalu ada set independen maksimal dengan properti itu. Setidaknya ada satu untuk n<=4. (Saya yakin saya dapat menunjukkan bahwa 83 itu optimal.)

#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
#include<igraph.h>

using vect = std::vector<int>;

constexpr int MAXDIRECT=100;
constexpr int PRINTNODES=1;

std::set<int> avoid{};
igraph_t graph;
std::vector<vect> distance_vectors{};
int count;

int close_h(const vect &a, const vect &b ){
  // check one direction of the closeness condition
  for(auto i=a.begin(), j=b.begin(); i!=a.end(); i++,j++)
    if ( (*i > *j) || (*j > 2 * *i))
      return 0;
  return 1;
}

int close(const vect &a, const vect &b ){
  return close_h(a,b) || close_h(b,a);
}

vect distances(int n, int p, int t){
  vect res{};
  for (int i=0; i<n; ++i){
    int count = 0;
    for (int j=0; j<n; ++j)
      count += 1 & ((p>>j)^(t>>j));
    res.push_back(count);
    t >>= 1;
  }
  return res;
}

void print_vect( vect &v ){
  std::cout << "(";
  auto i=v.begin();
  std::cout << *i++;
  for( ; i!=v.end(); ++i)
    std::cout << "," << *i ;
  std::cout << ")\n";
}

void use_node( int n ){
  if(PRINTNODES)
    print_vect( distance_vectors[n] );
  ++count;
  avoid.insert( n );
  igraph_vector_t neighs;
  igraph_vector_init( &neighs, 0 );
  igraph_neighbors( &graph , &neighs, n, IGRAPH_OUT );
  for(int i=0; i<igraph_vector_size( &neighs ); ++i)
    avoid.insert( VECTOR(neighs)[i] );
  igraph_vector_destroy( &neighs );
}

void construct(int n){
  std::set<vect> dist_vects;
  for(int p=0; p>>n == 0; ++p)
    for(int t=0; t>>(2*n-2) == 0; ++t)   // sic! (because 0/1-symmetry)
      dist_vects.insert(distances(n,p,t));
  int nodes = dist_vects.size();
  std::cout << "distinct distance vectors: " << nodes << "\n";

  distance_vectors.clear();
  distance_vectors.reserve(nodes);
  std::copy(dist_vects.begin(), dist_vects.end(),
            back_inserter(distance_vectors));

  igraph_vector_t edges;
  igraph_vector_init( &edges, 0 );
  igraph_vector_t reversed;
  igraph_vector_init_seq( &reversed, 0, nodes-1 );
  for (int i=0; i<nodes-1; ++i){
    vect &x = distance_vectors[i];
    vect xr ( x.rbegin(), x.rend() );
    for(int j=i+1; j<nodes; ++j){
      vect &y = distance_vectors[j];
      if( xr==y ){
        VECTOR(reversed)[i] = j;
        VECTOR(reversed)[j] = i;
      }else if( close( x, y ) || close( xr, y) ){
        igraph_vector_push_back(&edges,i);
        igraph_vector_push_back(&edges,j);
      }
    }
  }
  std::cout << "edges: " << igraph_vector_size(&edges)/2 << "\n";

  igraph_create( &graph, &edges, nodes, IGRAPH_UNDIRECTED);
  igraph_vector_destroy( &edges );

  igraph_cattribute_VAN_setv( &graph, "r", &reversed );
  igraph_vector_destroy( &reversed );

  igraph_vector_t names;
  igraph_vector_init_seq( &names, 0, nodes-1 );
  igraph_cattribute_VAN_setv( &graph, "n", &names );
  igraph_vector_destroy( &names );

}

void max_independent( igraph_t *g ){
  igraph_vector_ptr_t livs;
  igraph_vector_ptr_init( &livs , 0 );
  igraph_largest_independent_vertex_sets( g, &livs );

  igraph_vector_t *nodes = (igraph_vector_t *) VECTOR(livs)[0];
  igraph_vector_t names;
  igraph_vector_init( &names, 0 );
  igraph_cattribute_VANV( g, "n", igraph_vss_vector( nodes ), &names );

  for(int i=0; i<igraph_vector_size(&names); ++i)
    use_node( VECTOR(names)[i] );
  igraph_vector_destroy( &names );
  igraph_vector_ptr_destroy_all( &livs );
}

void independent_comp( igraph_t *g );

void independent( igraph_t *g ){
  if(igraph_vcount( g ) < MAXDIRECT){
    max_independent( g );
    return;
  }
  igraph_vector_ptr_t components;
  igraph_vector_ptr_init( &components, 0 );
  igraph_decompose( g, &components, IGRAPH_WEAK, -1, 1);
  for(int i=0; i<igraph_vector_ptr_size( &components ); ++i)
    independent_comp( (igraph_t *) VECTOR(components)[i] );
  igraph_decompose_destroy( &components );
}

void independent_comp( igraph_t *g ){
  if (igraph_vcount( g ) < MAXDIRECT){
    max_independent( g );
    return;
  }
  igraph_vector_t degs;
  igraph_vector_init( &degs, 0 );
  igraph_degree( g, &degs, igraph_vss_all(), IGRAPH_OUT, 1 );
  int maxpos = igraph_vector_which_max( &degs );
  igraph_vector_destroy( &degs );  

  int name = igraph_cattribute_VAN( g, "n", maxpos );
  int revname = igraph_cattribute_VAN( g, "r", maxpos );
  int rev = -1;
  if(name!=revname){
    igraph_vector_ptr_t reversed_candidates_singleton;
    igraph_vector_ptr_init( &reversed_candidates_singleton, 0 );
    igraph_neighborhood( g, &reversed_candidates_singleton,
                         igraph_vss_1(maxpos), 2, IGRAPH_OUT );
    igraph_vector_t * reversed_candidates =
      (igraph_vector_t *) VECTOR(reversed_candidates_singleton)[0];
    igraph_vector_t names;
    igraph_vector_init( &names, 0 );
    igraph_cattribute_VANV( g, "n", igraph_vss_vector( reversed_candidates ),
                        &names );
    long int pos;
    igraph_vector_search( &names, 0, revname, &pos );
    rev = VECTOR(*reversed_candidates)[pos];
    igraph_vector_destroy( &names );
    igraph_vector_ptr_destroy( &reversed_candidates_singleton );
  }
  igraph_vs_t delnodes;
  igraph_vs_vector_small( &delnodes, maxpos, rev, -1 );
  igraph_delete_vertices( g, delnodes );
  igraph_vs_destroy( &delnodes );

  independent( g );
}

void handle(int n){
  std::cout << "n=" << n << "\n";
  avoid.clear();
  count = 0;
  construct( n );
  independent( &graph );
  // try all nodes again:
  for(int node=0; node<igraph_vcount( &graph ); ++node)
    if(avoid.count(node)==0)
      use_node(node);
  std::cout << "result: " << count << "\n\n";
  igraph_destroy( &graph );
}

int main(){
  igraph_i_set_attribute_table( &igraph_cattribute_table );
  for(int i=1; i<6; ++i)
    handle(i);
}

Untuk mengkompilasi di debian, instal libigraph0-devdan lakukan g++ -std=c++11 -Wall -O3 -I/usr/include/igraph -o ig ig.cpp -ligraph.

Deskripsi lama:

Perpustakaan igraph memiliki fungsi untuk menghitung ukuran maksimal dari set vertex independen dari grafik. Ini dapat menangani masalah ini hingga n=3kurang dari satu detik dan tidak berakhir dalam beberapa harin=4 .

Jadi yang saya lakukan adalah menguraikan grafik menjadi komponen yang terhubung, dan biarkan perpustakaan menangani yang kecil (kurang dari MAXDIRECT node). Untuk komponen lain, saya memilih titik dan menghapusnya. Dalam kasus terbaik, ini membagi grafik menjadi beberapa komponen, tetapi biasanya tidak. Bagaimanapun, komponen (mungkin hanya satu) lebih kecil, dan kita dapat menggunakan rekursi.

Jelas pemilihan titik penting. Saya hanya mengambil satu tingkat maksimal. Saya menemukan bahwa saya mendapatkan hasil yang lebih baik (tetapi hanya untuk n=4) ketika saya menggunakan daftar simpul terbalik. Itu menjelaskan bagian ajaib dari construct fungsi tersebut.

Mungkin bernilai sambil meningkatkan seleksi. Tetapi tampaknya lebih penting untuk mempertimbangkan kembali node yang dihapus. Saat ini, saya tidak pernah melihat mereka lagi. Beberapa dari mereka mungkin tidak terhubung ke node yang dipilih. Masalahnya adalah saya tidak tahu node mana yang membentuk set independen. Untuk satu, menghapus node menambah jumlah node yang tersisa. Itu bisa ditangani dengan melampirkan attribtes kepada mereka. Tapi lebih buruknya, perhitungan angka kemerdekaan hanya memberikan angka ini. Alternatif terbaik yang ditawarkan perpustakaan adalah untuk menghitung semua set independen terbesar, yang lebih lambat (berapa banyak tampaknya tergantung pada ukuran grafik). Namun, ini sepertinya cara yang harus segera ditempuh. Jauh lebih samar, saya juga berpikir mungkin berguna untuk mempertimbangkan jika kita dapat menggunakan cara khusus grafik didefinisikan.

Kasus n=6 mungkin dapat dijangkau (sama sekali, tidak harus dalam 5 menit) jika saya mengganti rekursi dengan loop menggunakan antrian untuk komponen yang tersisa.

Saya menemukan hal menarik untuk melihat komponen grafik. Sebab n=4, ukurannya adalah 168, 2*29, 2*28, 3, 4*2, 4*1. Hanya yang terbesar tidak bisa ditangani secara langsung.

Sebab n=5, ukurannya adalah 1376, 2*128, 2*120, 119, several <=6.

Saya perkirakan ukuran ganda tersebut sesuai dengan grafik isomorfik, tetapi menggunakan ini tampaknya tidak bernilai sementara karena selalu ada satu komponen yang mendominasi terbesar:

Sebab n=6, komponen terbesar berisi 11941node (dari total 15425), dua komponen terbesar berikutnya memiliki ukuran 596.

Sebab n=7, angka-angka ini adalah 107593 (125232), 2647.

Sievers Kristen
sumber
Bisakah Anda memberi tahu saya apa set untuk 83, saya ingin tahu mengapa algoritme saya tidak mendapatkan yang tinggi untuk 4 tetapi entah bagaimana menjadi lebih tinggi untuk 5: P
fəˈnɛtɪk
Itu harus g++ -std=c++11 -Wall -O3 -I/usr/include/igraph -o sievers sievers.cpp -ligraph. Itu penting di mana -ligraph.
@ChristianSievers Bagaimana cara kerja generasi edge dalam kode?
fəˈnɛtɪk
@ChristianSievers Saya bertanya-tanya bagaimana ia menentukan apa yang harus disambungkan oleh setiap simpul. Membalikkan array mungkin mengacaukannya.
fəˈnɛtɪk
@ fəˈnɛtɪk Vektor jarak tampaknya datang disortir dari yang setsaya gunakan untuk menghindari duplikat, tapi saya bahkan tidak berpikir tentang pemesanan mereka ketika saya menulis kode itu. Loop dalam mulai i+1hanya menghindari melihat pasangan dan juga versi bertukar yang tidak diperlukan, dan merupakan cara termudah untuk menghindari loop (tepi (a,a)). Itu tidak tergantung pada urutan di mana node datang, saya tidak peduli apakah saya mendapatkan (a,b)atau (b,a).
Christian Sievers
3

Javascript, Seq: 2,5,21, 81 83,372 67,349

Berhasil meningkatkan nilai untuk 4 dengan menggunakan penghapusan acak elemen pada awal pencarian saya. Anehnya, menghapus 20 elemen dengan lebih dari 6 koneksi lebih cepat daripada menghapus 5 elemen dengan lebih dari 8 koneksi ...

Urutan ini mungkin tidak optimal untuk 5 dan mungkin tidak optimal untuk 4. Tidak ada node yang dekat dengan yang lain di set.

Kode:

input=4;
maxConnections=6;
numRand=20;

hammings=[];
h=(x,y)=>{retVal=0;while(x||y){if(x%2!=y%2)retVal++;x>>=1;y>>=1}return retVal};
for(i=1<<(input-1);i<1<<input;i++){
  for(j=0;j<1<<(2*input);j++){
    hamming=[];
    for(k=0;k<input;k++){
      hamming.push(h((j>>k)%(1<<input),i));
    }
    equal=0;
    for(k=0;k<hammings.length;k++){
      if(hamming.join("")==hammings[k].join("")){
        equal=1;
        break;
      }
    }
    if(!equal)hammings.push(hamming);
  }
}
adjMat=[];
for(i=0;i<Math.pow(input+1,input);i++){
  row=[];
  for(j=0;j<Math.pow(input+1,input);j++){
    row.push(0);
  }
  adjMat.push(row);
}
nodes=[]
for(i=0;i<Math.pow(input+1,input);i++){
  nodes[i]=0;
}
for(i=0;i<hammings.length;i++){
  sum=0;
  chkNodes=[[]];
  for(j=0;j<input;j++){
    chkVal=[];
    t=Math.pow(input+1,j);
    sum+=t*hammings[i][j];
    tmp=[];
    for(r=0;r<chkNodes.length;r++){
      for(k=hammings[i][j];k<=Math.min(hammings[i][j]*2,input);k++){
        stor=[]
        for(s=0;s<chkNodes[r].length;s++){
          stor.push(chkNodes[r][s])
        }
        stor.push(k)
        tmp.push(stor);
      }
    }
    chkNodes=[];
    for(r=0;r<tmp.length;r++){
      chkNodes.push(tmp[r])
    }
  }
  nodes[sum]=1;
  for(j=0;j<chkNodes.length;j++){
    adjSum=0
    for(k=0;k<input;k++){
      adjSum+=Math.pow(input+1,k)*chkNodes[j][k]
    }
    if(adjSum!=sum)adjMat[sum][adjSum]=adjMat[adjSum][sum]=1
  }
}
t=nodes.length;
for(i=0;i<t;i++){
  if(!nodes[i]){
    for(k=0;k<t;k++){
      adjMat[i][k]=adjMat[k][i]=0
    }
  }
}
sum=(a,b)=>a+b;
console.log(nodes.reduce(sum))
connections=x=>x.reduce(sum)
counts=adjMat.map(connections);
stor=[];
for(i=0;i<t;i++){
  stor.push(nodes[i]);
}
maxRemainder=0;

greater=[]
for(i=0;i<t;i++){
  if(nodes[i]&&counts[i]>maxConnections){
    greater.push(i);
  }
}

if(input==4){
  for(w=0;w<greater.length*numRand;w++){
    for(i=0;i<t;i++){
      nodes[i]=stor[i];
    }
    counts=adjMat.map(connections);
    toRemove=Math.floor(Math.random()*numRand*2)
    for(i=0;i<toRemove&&i<greater.length;i++){
      rand=Math.floor(Math.random()*greater.length);
      if(nodes[greater[rand]]){
        nodes[greater[rand]]=0;
        for(j=0;j<t;j++){
          if(adjMat[rand][j]){
            counts[j]--;
          }
        }
      }
    }

    for(i=0;i<t*t;i++){
      max=0;
      maxLoc=0;
      for(j=0;j<t;j++){
        if(counts[j]>=max&&nodes[j]){
          max=counts[j];
          maxLoc=j;
        }
      }
      if(max>0){
        for(j=0;j<t;j++){
          if(adjMat[maxLoc][j]){
            counts[j]--;
            if(counts[j]<max-1&&stor[j]&&!nodes[j]){
              nodes[j]=1;
              for(k=0;k<t;k++){
                if(adjMat[j][k])counts[k]++;
              }
            }
          }
          nodes[maxLoc]=0;
        }
      }
      else{
        break;
      }
    }
    maxRemainder=Math.max(maxRemainder,nodes.reduce(sum))
    //console.log(nodes.reduce(sum));
  }
  console.log(maxRemainder);
}
else{
  for(i=0;i<t*t;i++){
    max=0;
    maxLoc=0;
    for(j=0;j<t;j++){
      if(counts[j]>=max&&nodes[j]){
        max=counts[j];
        maxLoc=j;
      }
    }
    if(max>0){
      for(j=0;j<t;j++){
        if(adjMat[maxLoc][j]){
          counts[j]--;
          if(counts[j]<max-1&&stor[j]&&!nodes[j]){
            nodes[j]=1;
            for(k=0;k<t;k++){
              if(adjMat[j][k])counts[k]++;
            }
          }
        }
        nodes[maxLoc]=0;
      }
    }
    else{
      break;
    }
  }
  console.log(nodes.reduce(sum));
}

Cobalah online!

Cuplikan yang dapat ditambahkan akhir program untuk menunjukkan apa urutan jarak Hamming setiap urutan jarak Hamming yang dipilih

for(i=0;i<t;i++){
  if(nodes[i]){
    tmp=[]
    for(j=0;j<input;j++){
      tmp.unshift(Math.floor(i/Math.pow(input+1,j))%(input+1))
    }
    console.log(tmp.join(""))
    output=""
    for(j=0;j<t;j++){
      if(adjMat[i][j]&&stor[j]){
        outArr=[]
        for(k=0;k<input;k++){
          outArr.unshift(Math.floor(j/Math.pow(input+1,k))%(input+1))
        }
        output+=" "+outArr.join("");
      }
    }
    console.log(output)
  }
}

Penjelasan:

Pertama, kode menghasilkan semua jarak hamming unik dari substring.

input=3;
hammings=[];
h=(x,y)=>{retVal=0;while(x||y){if(x%2!=y%2)retVal++;x>>=1;y>>=1}return retVal};
for(i=1<<(input-1);i<1<<input;i++){
  for(j=0;j<1<<(2*input);j++){
    hamming=[];
    for(k=0;k<input;k++){
      hamming.push(h((j>>k)%(1<<input),i));
    }
    equal=0;
    for(k=0;k<hammings.length;k++){
      if(hamming.join("")==hammings[k].join("")){
        equal=1;
        break;
      }
    }
    if(!equal)hammings.push(hamming);
  }
}

Selanjutnya, kode mengubah daftar ini menjadi grafik yang tidak terarah

adjMat=[];
for(i=0;i<Math.pow(input+1,input);i++){
  row=[];
  for(j=0;j<Math.pow(input+1,input);j++){
    row.push(0);
  }
  adjMat.push(row);
}
nodes=[]
for(i=0;i<Math.pow(input+1,input);i++){
  nodes[i]=0;
}
for(i=0;i<hammings.length;i++){
  sum=0;
  chkNodes=[[]];
  for(j=0;j<input;j++){
    chkVal=[];
    t=Math.pow(input+1,j);
    sum+=t*hammings[i][j];
    tmp=[];
    for(r=0;r<chkNodes.length;r++){
      for(k=hammings[i][j];k<=Math.min(hammings[i][j]*2,input);k++){
        stor=[]
        for(s=0;s<chkNodes[r].length;s++){
          stor.push(chkNodes[r][s])
        }
        stor.push(k)
        tmp.push(stor);
      }
    }
    chkNodes=[];
    for(r=0;r<tmp.length;r++){
      chkNodes.push(tmp[r])
    }
  }
  nodes[sum]=1;
  for(j=0;j<chkNodes.length;j++){
    adjSum=0
    for(k=0;k<input;k++){
      adjSum+=Math.pow(input+1,k)*chkNodes[j][k]
    }
    if(adjSum!=sum)adjMat[sum][adjSum]=adjMat[adjSum][sum]=1
  }
}

Akhirnya, kode siklus melalui grafik ini, menghapus simpul dengan koneksi paling banyak setiap siklus sebelum mengembalikan node yang sekarang akan memiliki koneksi lebih sedikit daripada maksimum saat ini. Setelah selesai dengan siklus ini, ia menghasilkan jumlah node yang tersisa

t=nodes.length;
for(i=0;i<t;i++){
  if(!nodes[i]){
    for(k=0;k<t;k++){
      adjMat[i][k]=adjMat[k][i]=0
    }
  }
}
sum=(a,b)=>a+b;
counts=adjMat.map(x=>x.reduce(sum));
stor=[];
for(i=0;i<t;i++){
  stor.push(nodes[i]);
}
for(i=0;i<t*t;i++){
  max=0;
  maxLoc=0;
  for(j=0;j<t;j++){
    if(counts[j]>=max&&nodes[j]){
      max=counts[j];
      maxLoc=j;
    }
  }
  if(max>0){
    for(j=0;j<t;j++){
      if(adjMat[maxLoc][j]){
        counts[j]--;
        if(counts[j]<max-1&&stor[j]&&!nodes[j]){
          nodes[j]=1;
          for(k=0;k<t;k++){
            if(adjMat[j][k])counts[k]++;
          }
        }
      }
      nodes[maxLoc]=0;
    }
  }
  else{
    break;
  }
}
console.log(nodes.reduce(sum));

Set:

1:

0 1

2:

00 01 10 12 21

3:

000 001 011 013 030 031 100 101 110 111 123 130 132 203 213 231 302 310 312 
321 333

4:

0000 0001 0011 0111 0124 0133 0223 0230 0232 0241 0313 0320 0322 0331 0403 
0412 1000 1001 1013 1021 1100 1102 1110 1111 1134 1201 1224 1233 1243 1304 
1314 1323 1330 1332 1342 1403 1413 1420 1422 2011 2033 2124 2133 2140 2142 
2214 2230 2241 2303 2313 2320 2331 2411 3023 3032 3040 3041 3101 3114 3123 
3130 3132 3141 3203 3213 3220 3231 3302 3310 3312 3321 3334 3343 3433 4031 
4113 4122 4131 4210 4212 4221 4311 4333

5:

00000 00001 00011 00111 00123 01112 01235 01244 01324 01343 02111 02230 
02234 02333 02342 02432 02441 02522 02530 02531 03134 03142 03220 03224 
03233 03241 03314 03323 03331 03403 03412 03421 03520 04133 04141 04214 
04223 04232 04303 04313 04322 05042 05050 05051 05132 10000 10001 10011 
10122 10212 10221 10245 11000 11001 11013 11022 11100 11112 11120 11121 
11202 11211 11345 11353 11443 12012 12111 12201 12245 12253 12335 12344 
12352 12425 12430 12434 12442 12513 12532 13033 13042 13244 13252 13325 
13330 13334 13342 13404 13424 13433 13441 13520 13522 13531 14032 14051 
14140 14152 14225 14230 14234 14241 14243 14304 14315 14324 14332 14413 
14420 14422 14431 15041 15050 15125 15133 15142 15215 15223 15232 20112 
20135 20211 20253 20334 20352 21012 21021 21102 21110 21111 21201 21245 
21344 21352 21430 21433 21442 21514 21523 22011 22101 22135 22244 22252 
22325 22334 22340 22343 22405 22415 22424 22441 22520 22522 22531 23041 
23144 23150 23152 23225 23234 23240 23243 23251 23304 23315 23324 23333 
23341 23403 23413 23420 23432 23521 24031 24050 24125 24130 24134 24142 
24151 24215 24224 24233 24303 24314 24320 24323 24331 24412 24421 25123 
25132 25141 25203 25214 25222 25231 25302 25312 25321 30234 30243 30252 
30324 30333 30340 30342 30414 30423 30430 30432 31011 31235 31244 31253 
31325 31334 31340 31343 31405 31415 31424 31432 31441 31504 31521 32025 
32034 32100 32144 32152 32225 32234 32240 32243 32251 32304 32315 32324 
32330 32333 32342 32403 32414 32423 32512 33024 33031 33033 33125 33134 
33140 33143 33151 33215 33224 33230 33233 33242 33303 33314 33320 33323 
33332 33412 33431 34124 34133 34203 34214 34223 34232 34241 34310 34313 
34322 34411 35202 35213 35221 35311 40323 40332 40341 40431 40505 40513 
41135 41144 41240 41243 41252 41324 41330 41333 41342 41403 41414 41423 
41512 42033 42134 42143 42230 42233 42242 42303 42310 42314 42323 42332 
42341 42413 42422 42431 43023 43124 43130 43133 43142 43203 43220 43223 
43232 43241 43302 43313 43322 43331 43421 44114 44123 44132 44210 44213 
44222 44231 44312 44321 50413 50422 50504 51233 51242 51251 51323 51332 
51341 51413 51422 52023 52133 52142 52151 52223 52232 52241 52313 52322 
52331 52421 53102 53114 53122 53210 53213 53321 54201 54212 54221 54311
fəˈnɛtɪk
sumber
Terima kasih telah memberikan jawaban pertama! Bisakah Anda memberikan panduan langkah demi langkah untuk para idiot tentang cara menjalankan kode Anda di Linux?
Mungkin fəˈnɛtɪk dapat mengubah kodenya menjadi snippet stack?
mbomb007
@ mbomb007 karena suatu alasan, menjadikannya sebagai cuplikan menyebabkan kesalahan 0 bukanlah fungsi ... pada baris untuk (j = 0; j <t; j ++)
fəˈnɛtɪk
Mungkin Anda bisa mencoba JSFiddle?
mbomb007
Jika Anda memiliki chrome, Anda dapat menyalin tempel kode ke konsol dan menjalankannya dengan menekan enter. Tidak sepenuhnya yakin tentang browser lain. Chrome menjalankan kode lebih cepat daripada sistem online untuk saya. Berhasil mendapatkan nilai 5 dari 349
fəˈnɛtɪk