Я использую SQL Server 2016 и Window 10.
Прежде всего, нужно разрешить удаленное подключение к SQL Сервер. Я сделал, чтобы ввести sqlservermanager13.msc в меню «Пуск», чтобы открыть диспетчер конфигурации SQL Server. Убедитесь, что статус TCP / IP включен.
Проверьте номер своего TCP-порта, дважды щелкнув имя протокола TCP / IP. Обычно это по умолчанию 1433.
Следующие процедуры настраивают брандмауэр Windows с помощью оснастки «Брандмауэр Windows с расширенной безопасностью» Microsoft Management Console (MMC) -в. Брандмауэр Windows с расширенной безопасностью настраивает только текущий профиль.
Чтобы открыть порт в брандмауэре Windows для доступа к TCP
- В меню «Пуск» выберите «Выполнить», введите WF.msc и нажмите «ОК».
- В брандмауэре Windows с расширенной безопасностью на левой панели щелкните правой кнопкой мыши Правила входящих сообщений и выберите «Новое правило» на панели действий.
- В диалоговом окне «Тип правила» выберите Порт, а затем нажмите «Далее».
- В диалоговом окне «Протокол и порты» выберите TCP. Выберите «Определенные локальные порты», а затем введите номер порта экземпляра Database Engine, например 1433 для экземпляра по умолчанию. Нажмите «Далее».
- В диалоговом окне «Действие» выберите «Разрешить подключение» и нажмите «Далее».
- В диалоговом окне «Профиль» выберите любые профили, описывающие среду подключения к компьютеру, когда вы хотите подключиться к механизму базы данных, а затем нажмите «Далее».
- В диалоговом окне «Имя» введите имя и описание этого правила и нажмите «Готово».
Еще одна вещь, которую нужно настроить.
Чтобы открыть доступ к SQL Server при использовании динамических портов
- В меню «Пуск» выберите «Выполнить», введите «WF» .msc, а затем нажмите «ОК».
- В брандмауэре Windows с расширенной безопасностью на левой панели щелкните правой кнопкой мыши «Правила входящих» и выберите «Новое правило» на панели действий.
- В диалоговом окне «Тип правила» выберите «Программа» и нажмите «Далее».
- В диалоговом окне «Программа» выберите «Путь к этой программе». Нажмите «Обзор» и перейдите к экземпляру SQL Server, к которому вы хотите получить доступ через брандмауэр, и нажмите «Открыть». По умолчанию SQL Server находится в папке C: \ Program Files \ Microsoft SQL Server \ MSSQL13.MSSQLSERVER \ MSSQL \ Binn \ Sqlservr.exe. Нажмите «Далее».
- В диалоговом окне «Действие» выберите «Разрешить подключение» и нажмите «Далее».
- В диалоговом окне «Профиль» выберите все профили, описывающие среду подключения к компьютеру, когда вы хотите подключиться к движку базы данных и нажмите «Далее».
- В диалоговом окне «Имя» введите имя и описание этого правила и нажмите «Готово».
Взгляните на Microsoft doucmentation Настройте брандмауэр Windows для доступа к базе данных
В стандарте C нет функции для рандомизации массива.
Обеспечение правильной перетасовки (где каждая перестановка исходного порядка одинаково вероятна).
просто, но не тривиально.
Я не видел этого среди ответов, поэтому предлагаю это решение, если оно может помочь кому угодно:
static inline void shuffle(size_t n, int arr[])
{
size_t rng;
size_t i;
int tmp[n];
int tmp2[n];
memcpy(tmp, arr, sizeof(int) * n);
bzero(tmp2, sizeof(int) * n);
srand(time(NULL));
i = 0;
while (i < n)
{
rng = rand() % (n - i);
while (tmp2[rng] == 1)
++rng;
tmp2[rng] = 1;
arr[i] = tmp[rng];
++i;
}
}
Здесь решение, которое использует memcpy вместо назначения, поэтому вы можете использовать его для массива по произвольным данным. Вам потребуется в два раза больше памяти исходного массива, а стоимость - линейная O (n):
void main ()
{
int elesize = sizeof (int);
int i;
int r;
int src [20];
int tgt [20];
for (i = 0; i < 20; src [i] = i++);
srand ( (unsigned int) time (0) );
for (i = 20; i > 0; i --)
{
r = rand () % i;
memcpy (&tgt [20 - i], &src [r], elesize);
memcpy (&src [r], &src [i - 1], elesize);
}
for (i = 0; i < 20; printf ("%d ", tgt [i++] ) );
}
void *
, чтобы снизить потребность в дополнительной памяти и ограничить копирование на отдельные значения - если это массив структур в стеке, это уменьшит количество создаваемых копий. Для еще более низких требований к пространству, смещение смещений в исходной позиции памяти, позволяющее использовать int или меньше (беззнаковое короткое устройство все еще управляет до 65.5k).
– Phil H
31 October 2012 в 10:40
Я просто отвечу на ответ Нила Баттерворта и укажу на некоторые проблемы с вашей первой мыслью:
Вы предложили
Итерацию через массив, скажем, 100 раз и обмениваться случайным индексом с другим случайным индексом
Сделайте это строгим. Я предполагаю существование
randn(int n)
, обертки вокруг некоторого RNG, создавая числа, равномерно распределенные в [0, n -1] иswap(int a[], size_t i, size_t j)
,swap(int a[], size_t i, size_t j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; }
, который меняет местами
a[i]
иa[j]
. Теперь давайте реализуем ваше предложение:void silly_shuffle(size_t n, int a[n]) { for (size_t i = 0; i < n; i++) swap(a, randn(n), randn(n)); // swap two random elements }
Обратите внимание, что это не лучше этой более простой (но все же неправильной) версии:
void bad_shuffle(size_t n, int a[n]) { for (size_t i = 0; i < n; i++) swap(a, i, randn(n)); }
Что ж, что случилось? Рассмотрим, сколько перестановок эти функции дают вам: с помощью n (или 2 × n для
silly_shuffle
) случайных выборок в [0, n - 1], код будет «справедливо» выбирать один из вариантов n ² (или 2 × n ²]), чтобы перетасовать колоду. Проблема в том, что есть n ! = n × ( n -1) × ⋯ × 2 × 1 возможных компоновки массива, и ни n ², ни 2 × n ² является кратным n !, доказывая, что некоторые перестановки более вероятны, чем другие.Shuffle Fisher-Yates на самом деле эквивалентен вашему второму предложению , только с некоторыми изменениями, которые меняются (производительность = 0, сложность = серьезная) до (производительность = очень хорошая, сложность = довольно простая). (На самом деле, я не уверен, что существует более быстрая или более простая версия.)
void fisher_yates_shuffle(size_t n, int a[n]) { for (size_t i = 0; i < n; i++) swap(a, i, i+randn(n-1-i)); // swap element with random later element }
ETA: См. Также этот пост в Coding Horror .
Следующий код гарантирует, что массив будет перетасован на основе случайного семени, взятого из времени usec. Также это реализует Fisher-Yates shuffle должным образом. Я тестировал вывод этой функции, и он выглядит хорошо (даже ожидание того, что любой элемент массива является первым элементом после тасования. Также даже ожидание для последнего).
void shuffle(int *array, size_t n) {
struct timeval tv;
gettimeofday(&tv, NULL);
int usec = tv.tv_usec;
srand48(usec);
if (n > 1) {
size_t i;
for (i = n - 1; i > 0; i--) {
size_t j = (unsigned int) (drand48()*(i+1));
int t = array[j];
array[j] = array[i];
array[i] = t;
}
}
}
int
, а не size_t
, в этом случае, потому что n
представляет количество int, а не размер блока памяти. Я предпочитаю использовать size_t
только для размеров в байтах.
– mk12
6 November 2012 в 20:13
sizeof
массив может быть намного больше, чем INT_MAX
. Использование size_t
здесь более надежный и переносимый подход.
– chux
26 April 2014 в 17:48
srand()
- Почему вы должны называть его только один раз .
– Jonathan Leffler
11 December 2016 в 02:05
array[i] += array[j]; array[j] = array[i] - array[j]; array[i] -= array[j];
, если вы не беспокоитесь о переполнении int. Я не хочу путать с новичком язык о том, почему XOR'ing работает, хотя ... – John Leehey 25 May 2011 в 17:44gcc -S
, и были только два i> модификации указателя стека, один раз в начале функции и один раз в конец.) Вы сохраняете nothing i>, используя ранееt
иj
в этой функции. – asveikau 25 May 2011 в 17:530
доi
, гдеi
идет отn
до1
? – ninjalj 25 May 2011 в 21:38rand
, если вы получите значение, которое вы должны отбросить). Есть способы сохранить и повторно использовать эту энтропию, а не полностью отбросить ее, но это больше работает и, вероятно, бесполезно, когда она просто псевдослучайна в любом случае. – R.. 25 May 2011 в 21:51i + r / (RAND_MAX / (n - i) + 1)
вводит дополнительное смещение. например j (i = 32, n = 61, RM = 2147483647) - & gt; {с 2147483648 различнымиr
,j
= 32 - 60 встречается 74051161 каждый, 61 - только 74051140}. TBD наихудший случайi,n,RAND_MAX
. Сi+ rnd%(n-i)
{j
= от 32 до 39 встречаются 74051161 каждый,j
= от 40 до 61 происходит 74051160, распределение худшего случая для различныхi,n,RAND_MAX
не более 1 раз. Поскольку другие сообщения ссылаются на этот популярный ответ, это было важно заметить. – chux 26 April 2014 в 17:36RAND_MAX
всего 32767, вам нужно получить лучшее PRNG. Одним простым шагом является семейство функцийdrand48()
; это стандартный набор функций POSIX. Вы можете обнаружить, что у вас естьrandom()
иsrandom()
илиarc4random()
, или, возможно, вы можете использовать/dev/random
или/dev/urandom
в качестве источника случайных значений. Есть много возможностей, но то, что вы задаете, - это действительно новый вопрос (или его следует задать по новому вопросу). – Jonathan Leffler 9 June 2018 в 18:15