"Cogito ergo sum."

"Remember, remember The fifth of November The gunpowder treason and plot. I know of no reason Why the gunpowder treason Should ever be forgot." - V for Vendetta

Friss topikok

Linkblog

N királynő probléma

2012.03.17. 20:28 Painkiller19910110

Hát rég volt már poszt, de ezzel együtt ihlet is rég szállt meg.... :) Most viszont új erőre kapva a Mesterséges Intelligencia tárgytól a következő posztot ennek szentelem.  A poszt témája az N királynő probléma. Tömören annyi a lényege hogy adott egy NxN-es sakktábla, ahova úgy kell felhelyezni N darab királynőt hogy nem üthetik egymást. Más szóval oszloponként és átlónként és soronként is csak 1 darab megengedett a királynőkből, ez szükséges de nem elégséges feltétele a dolognak!

A programom úgy működik hogy, elindul a sakktábla bal felső sarkából és N darab esetén NxN tesztesetet generál ami abból áll hogy leteszi az első helyre a királynőt és aztán az ütött mezők értékét 1-esre állítja. Utána megkeresi hogy melyek a szabad mezők, majd azok közül választ véletlenszerűen 1-et és oda rak le egy királynőt, és az általa ütött mezőket is 1-esre állítja, és megint keresi a szabadon maradt mezőket... Ez mind addig meg míg el nem fogynak a szabad mezők. Ha elfogyott a szabad mezők száma és N darab királynő van a táblán akkor talált egy megoldást a program és meg előre csak a soron következő  mezőre rakja a királynőt és kezdi az egészet elölről, mindaddig míg nincs meg a megfelelő számú megoldás...Van viszont egy kis szépség hibája a proginak, mégpedig hogy semmi garancia nincs hogy a megoldások amiket talál nem egyeznek meg mert nincsenek rögzítve a megoldások az ellenőrzésre. Viszont kb 10 királynő esetén már elég kis eséllyel járja be ugyan azt az utat 2x, és a királynők számával ez még radikálisabban csökken. :)

4 Királynő esetén:

./nkir 4 2 <paraméterekkel indítva>

Ez a megoldas a 1. kör 3. teszesetében van!
Ez a 1. megoldasa a feladatnak!!
1 1 9 1
9 1 1 1
1 1 1 9
1 9 1 1

Ez a megoldas a 1. kör 9. teszesetében van!
Ez a 2. megoldasa a feladatnak!!
1 9 1 1
1 1 1 9
9 1 1 1
1 1 9 1
 

10 királynő esetén:

Ez a megoldas a 1. kör 16. teszesetében van!
Ez a 1. megoldasa a feladatnak!!
1 1 9 1 1 1 1 1 1 1
1 1 1 1 1 9 1 1 1 1
1 1 1 1 1 1 1 1 9 1
9 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 9 1 1
1 1 1 9 1 1 1 1 1 1
1 9 1 1 1 1 1 1 1 1
1 1 1 1 1 1 9 1 1 1
1 1 1 1 9 1 1 1 1 1
1 1 1 1 1 1 1 1 1 9

Ez a megoldas a 1. kör 24. teszesetében van!
Ez a 2. megoldasa a feladatnak!!
1 1 1 1 9 1 1 1 1 1
1 1 1 1 1 1 1 1 1 9
1 1 1 9 1 1 1 1 1 1
1 1 1 1 1 1 1 1 9 1
1 1 9 1 1 1 1 1 1 1
1 1 1 1 1 1 1 9 1 1
1 9 1 1 1 1 1 1 1 1
1 1 1 1 1 1 9 1 1 1
9 1 1 1 1 1 1 1 1 1
1 1 1 1 1 9 1 1 1 1
 

 

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int **sakktabla;
int *szabad_poz;
int kinok_szama;

int
lefoglal (int db)//létrehozzuk a sakktáblát
{
  int i;
  sakktabla = (int **) malloc (db * sizeof (int *));
  for (i = 0; i < db; i++)
    sakktabla[i] = (int *) malloc (db * sizeof (int));
  return **sakktabla;
}

void
lenullaz (int db)//inicializáljuk a sakktáblát a kinullázással
{
  int i, j;
  for (i = 0; i < db; i++)
    for (j = 0; j < db; j++)
      {
    sakktabla[i][j] = 0;
      }
}

void
kiirat (int db)//kiprinteljük  a sakktáblát!!!
{
  int i, j;
  for (i = 0; i < db; i++)
    {
      for (j = 0; j < db; j++)
    printf ("%d ", sakktabla[i][j]);
      printf ("\n");
    }
}

void
kiloves (int ut, int db)//az ütött mezők "kilövése"
{
  int sor, oszlop;
  if (ut % db == 0)
    {
      sor = ((int) ut / db) - 1;
      oszlop = ut - (sor * db) - 1;
    }
  else
    {
      sor = (int) ut / db;
      oszlop = ut - (sor * db) - 1;
    }
  int i, j;
  for (i = 0; i < db; i++)
    sakktabla[sor][i] = 1;

  for (i = 0; i < db; i++)
    sakktabla[i][oszlop] = 1;
  i = sor;
  j = oszlop;
  while (i < db && j < db)
    {
      sakktabla[i][j] = 1;
      i++;
      j++;
    }
  i = sor;
  j = oszlop;
  while (i >= 0 && j >= 0)
    {
      sakktabla[i][j] = 1;
      i--;
      j--;
    }
  i = sor;
  j = oszlop;
  while (i >= 0 && j < db)
    {
      sakktabla[i][j] = 1;
      i--;
      j++;
    }
  i = sor;
  j = oszlop;
  while (i < db && j >= 0)
    {
      sakktabla[i][j] = 1;
      i++;
      j--;
    }
  sakktabla[sor][oszlop] = 9;
}

void
szabad_nullaz (int db)//kinullázzunk a szabad elemeket tartalmazó tömböt
{
  int i;
  for (i = 0; i < (db * db); i++)
    szabad_poz[i] = 0;
}

void
szabad_e (int db) //kigyűjtjük a szabad elemek pozícióját
{
  int i, j, m;
  m = 0;
  for (i = 0; i < db; i++)
    for (j = 0; j < db; j++)
      if (sakktabla[i][j] == 0)
    {
      szabad_poz[m] = ((i * db) + j + 1);
      m++;
    }

}

void
szabad_kiirat (int db)//kiíratjuk a szabad pozíciókat
{
  int i;
  printf ("A szabadon maradt pozíciók: ");
  for (i = 0; i < (db * db); i++)
    if (szabad_poz[i] != 0)
      printf ("%d ", szabad_poz[i]);
}

int
kiralynok_szama (int db)// a táblán lévő királynők számának meghatározása
{
  int kinok_szama = 0;
  int i, j;
  for (i = 0; i < db; i++)
    for (j = 0; j < db; j++)
      if (sakktabla[i][j] == 9)
    kinok_szama++;
  return kinok_szama;
}

int
szabad_merete ()//megnézzük hány elem van a szabad_pozíciók tömbjében
{
  int i = 0;
  while (szabad_poz[i] != 0)
    i++;
  return i;
}

int
main (int argc, char *argv[])
{
  int db, flag;
  int s;
  int veletlen;

  int korok = 1;
  int darabszam = 0;
  unsigned int seed = (unsigned int) time (NULL);

  srand (seed);

  db = atoi (argv[1]);
  flag = atoi (argv[2]);

  szabad_poz = (int *) malloc ((db * db) * sizeof (int));

  lefoglal (db);

  printf    ("Tehát akkor %d db. királynő ne üsse egymást a %d*%d-s táblán!\n", db, db, db);

  while (1)
    {
     for (s = 1; s <= (db * db); s++)
    {
      lenullaz (db);
      kiloves (s, db);
      szabad_nullaz (db);
      szabad_e (db);
     
      while (szabad_poz[0] != 0)
        {
          veletlen = rand () % szabad_merete ();
          kiloves (szabad_poz[veletlen], db);
          szabad_nullaz (db);     
          szabad_e (db);
        }
      if (db == kiralynok_szama (db))
        {
          printf ("\nEz a megoldas a %d. kör %d. teszesetében van!\n", korok, s);
          darabszam++;
          printf ("Ez a %d. megoldasa a feladatnak!!\n", darabszam);
          kiirat (db);
        }
      if (darabszam == flag)
        break;
    }
      korok++;
      if (darabszam == flag)
    {
      printf("Megvan az összes kívánt megoldás!!! Vége a programnak!!!\n\n");
      break;
    }
    }
  return 0;
}

Szólj hozzá!

A bejegyzés trackback címe:

https://painkillerblogja.blog.hu/api/trackback/id/tr934322731

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása