Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Fortran] Задача на экзамен (найти радиусы), Задача на экзамен  
:(
    Опции темы
Svetko
  Дата 31.5.2010, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 31.5.2010

Репутация: нет
Всего: нет



Ребята помогите smile 
Заданы m точек (m>=10)
Найти радиусы описанной окружности вокруг треугольника. Выбрать максимальный радиус описанной окружности. Преподаватель сказал что надо использовать подпрограмму.

Это сообщение отредактировал(а) Svetko - 31.5.2010, 20:53
PM MAIL   Вверх
Svetko
Дата 1.6.2010, 00:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 31.5.2010

Репутация: нет
Всего: нет



Использую функцию описанной окружности около треугольника с тремя точками-вершинами.
Код

Real Function R(X,Y,Z)
TYPE(TPoint) :: X,Y,Z
Real a,b,c,d
a = Dist(X,Y);
b = Dist(Y,Z);
c = Dist(X,Z);
d = S(a,b,c);
if(d>1e-5) then
  R = a*b*c / (4*S(a,b,c))
else
  R = 0
end if
END FUNCTION

S — площадь треугольника со сторонами-аргументами, например,
Код

Real Function S(a,b,c)
real :: a,b,c,p
p = (a+b+c) / 2
S = Sqrt(p*(p-a)*(p-b)*(p-c)); !Формула Герона
END function

и Dist — расстояние между точками
Код

Type TPoint
  REAL :: X,Y
End TYPE
 
Real Function Dist(A,B)
Type(TPoint) :: A,B
Dist = Sqrt((A%X-B%X)**2 + (A%Y-B%Y)**2)
END FUNCTION

Помогите найти наибольшую описанную окружность и если есть возможность проверти эту и подкорректируйте.  smile 
PM MAIL   Вверх
FCM
Дата 1.6.2010, 13:36 (ссылка)  | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: нет
Всего: 9



Цитата(Svetko @  31.5.2010,  20:51 Найти цитируемый пост)

Заданы m точек (m>=10)
Найти радиусы описанной окружности вокруг треугольника. Выбрать максимальный радиус описанной окружности.


Какая связь между m точками и треугольником?

Если предположить, что 
1) нужно выбрать треугольник с вершинами из m-точек
2) ваша формулы в функции R правильны
то это может выглядеть так:

Код

MODULE TPOINT_DEF          !     Модуль с определением типа TPOINT
   TYPE TPOINT   
      REAL :: X,Y
   END TYPE TPOINT  
END MODULE TPOINT_DEF

PROGRAM OKR                     !   Главная программа
   USE TPOINT_DEF
   IMPLICIT NONE
   REAL :: R, R0, R1
   INTEGER :: I, J, K, I0, J0, K0
   INTEGER, PARAMETER :: M = 10
   TYPE(TPOINT) :: T(M)                        !  Определяем массив из M 2D-точек
   DO I = 1,M                                        !  Инициализация массива
      CALL RANDOM_NUMBER(T(I)%X)       !  случайными числами из (-5.,5.)
      T(I)%X = 10*(T(I)%X - 0.5)
      CALL RANDOM_NUMBER(T(I)%Y)
      T(I)%Y = 10*(T(I)%Y - 0.5)
   END DO
   I0 = 0; J0 = 0; K0 = 0; R0 = 0.0        ! "Затравка"
   DO I = 1, M-2                                    !  Перебираем несовпадающие треугольники     
      DO J = I+1, M-1            
         DO K =  J+1, M
            R1 = R( T(I), T(J), T(K) )
            IF( R1 >= R0 ) THEN                   !  Выбираем треугольник с максимальным   R
               R0 = R1; I0 = I; J0 = J; K0 = K;
            END IF
            !   WRITE(*,*) I,J,K, ":: R = ", R( T(I), T(J), T(K) )     ! Отладочный вывод
         END DO
      END DO
   END DO
   WRITE(*,'(3(A,I0),A,G12.6)') &
      "R_max = R(", I0, ",", J0, ",", K0, ") =  ", R0
   WRITE(*,*) "Treugolnik ABC:"
   WRITE(*,*) "           A = ", T(I0)
   WRITE(*,*) "           B = ", T(J0)
   WRITE(*,*) "           C = ", T(K0)
END PROGRAM OKR 

REAL FUNCTION R(A,B,C)        ! Ваша функция R
   USE TPOINT_DEF
   IMPLICIT NONE
   TYPE(TPOINT) :: A,B,C
   REAL :: AB,BC,AC,D
   REAL :: S, DIST
   AB = DIST(A,B);
   BC = DIST(B,C);
   AC = DIST(A,C);
   D = S(AB,BC,AC);
   IF( D > 1E-5 ) THEN
      R = AB*BC*AC / (4*D)
   ELSE
      R = 0
   END IF
END FUNCTION  R

REAL FUNCTION S(a,b,c)                  ! Ваша функция S
   IMPLICIT NONE
   REAL :: a,b,c,P
   P = (a+b+c) / 2
   S = SQRT(P*(P-a)*(P-b)*(P-c)); ! 
END FUNCTION S

REAL FUNCTION DIST(A,B)                   ! Ваша функция DIST
   USE TPOINT_DEF
   IMPLICIT NONE
   TYPE(TPOINT) :: A,B
   DIST = SQRT((A%X-B%X)**2 + (A%Y-B%Y)**2)
END FUNCTION  DIST



Это сообщение отредактировал(а) FCM - 7.6.2010, 09:36
PM MAIL   Вверх
Svetko
Дата 1.6.2010, 19:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 31.5.2010

Репутация: нет
Всего: нет



FCM, Спасибо , осталось только проверить в программе  smile  
Может у кого есть возможность?

PM MAIL   Вверх
FCM
Дата 1.6.2010, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: нет
Всего: 9



В каком смысле проверить?
У тебя есть заданный набор точек и ответ?
PM MAIL   Вверх
Svetko
Дата 1.6.2010, 19:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 31.5.2010

Репутация: нет
Всего: нет



Нет только это задание и всё. Просто если он мне задаст набор точек,чтоб проверить правильность программы , как я смогу смогу их внести в код ?
PM MAIL   Вверх
FCM
Дата 1.6.2010, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: нет
Всего: 9



Ну можешь "тупо" вбить, например,
T(1) = TPOINT(1.,2.)
...
T(M) = TPOINT(3.,4.)
или
T = (/ TPOINT(1.,2.), ...,  TPOINT(3.,4.) /)

Возможно он даст файл из которого нужно считать - счас посмотрю, как это работате для производных типов...

Добавлено @ 20:31
Если даст файл, с содержимым вида
1.1  2.2
1.3  3.1
...    ...

то вместо инициализации случайными числами надо вставить следующее

Код

   OPEN(11,FILE = "полный_путь_к_файлу")
   READ(11,*) T
   CLOSE(11)


но нужно проверить, чтобы длина массива Т была согласована с количеством пар значений в файле.

(Возможно он попросит использовать динамическиq массив, размер которого следует определить по  количеству пар значений в файле...)


Или запрограммировать ввод с клавиатуры, например, так

Код

   ...
   INTEGER :: M                                            ! вместо  INTEGER, PARAMETER :: M
   TYPE(TPOINT), ALLOCATABLE :: T(:)        ! вместо  TYPE(TPOINT) ::    T(M)  
   ...
   WRITE(*,'(A,\)')   "ENTER NUMBER OF POINTS : "
   READ(*,*)  M
   ALLOCATE( T(M) )                 ! Размещение дин. массива
   DO I = 1, M
      WRITE(*,'(A,I0,A,\)')   "ENTER ", I, " POINT :  "
      READ(*,*)    T(I)
   END DO
   ...


и вводить точки парами значений 

(PS
но вообще в вашей функции R критерий D > 1E-5 требует отдельных "размышлений")

Это сообщение отредактировал(а) FCM - 6.6.2010, 10:42
PM MAIL   Вверх
Svetko
Дата 6.6.2010, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 31.5.2010

Репутация: нет
Всего: нет



FCM, мдааа. Преподаватель сказал переписать всё программу попроще , вот эти вот моменты особенно 
 CALL RANDOM_NUMBER(T%X)       !  случайными числами из (-5.,5.)
      T%X = 10*(T%X - 0.5)
      CALL RANDOM_NUMBER(T%Y)
      T%Y = 10*(T%Y - 0.5)

Еще вопрос IMPLICIT NONE что это?

PM MAIL   Вверх
kemiisto
Дата 6.6.2010, 22:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 16
Всего: 160




M
kemiisto
Для домашних заданий, курсовых и т.п. существует \"Центр Помощи\".




Тема перенесена. 


--------------------
PM MAIL WWW GTalk Jabber   Вверх
FCM
Дата 7.6.2010, 09:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: нет
Всего: 9



Svetko

Цитата(Svetko @  6.6.2010,  22:03 Найти цитируемый пост)

     DO I = 1,M 
          CALL RANDOM_NUMBER(T%X)       !  случайными числами из (-5.,5.)
        T%X = 10*(T%X - 0.5)
        CALL RANDOM_NUMBER(T%Y)
        T%Y = 10*(T%Y - 0.5)
      ENDDO 

Там у меня была неточность (получаются лишние вычисления) -
 надо либо так
Код

      DO I = 1,M            !    T
          CALL RANDOM_NUMBER(T(I)%X)      ! инициализация T(I)%X случайным числом из (0.,1.)
          T(I)%X = 10*(T(I)%X - 0.5)              ! "растяжка" до (-5., 5.)       
          CALL RANDOM_NUMBER(T(I)%Y)      ! инициализация T(I)%Y  случайным числом из (0.,1.)
          T(I)%Y = 10*(T(I)%Y - 0.5)              ! "растяжка" до (-5., 5.)
      END DO


либо так (без цикла)

Код

       CALL RANDOM_NUMBER(T%X)       ! инициализация всех T%X случайными числами из (0.,1.)
       T%X = 10*(T%X - 0.5)                   ! "растяжка" до (-5., 5.)       
       CALL RANDOM_NUMBER(T%Y)        ! инициализация всех T%Y случайными числами из (0.,1.)
       T%Y = 10*(T%Y - 0.5)                    ! "растяжка" до (-5., 5.)    


Это всего лишь вариант инициализации массива T - инициализация  случайными числами из диапазона (-5.,5.). Можно убрать "растяжку" (масштабирование) и ограничиться диапазоном (0.,1.)

Другие варианты (инициализация заданными числами в тексте программы, считывание из файла, считывание с клавиатуры) приведены выше.


Цитата(Svetko @  6.6.2010,  22:03 Найти цитируемый пост)
Еще вопрос IMPLICIT NONE что это?

Это инструкция отмены используемой в Фортране по умолчанию неявной типизации (согласно которой все переменные и функции, начинающиеся с I, J,K,L,M,N, имеют тип INTEGER, остальные - тип REAL). Неявная типизация может приводить к трудновыявляемым ошибкам, связанными с опечатками и т.п. и не рекомендуется в современном Фортране.
Ну если преподавателю это не нравится удали эту инструкцию везде.

Если же преподавателя смущает и использование модуля. То можешь удалить и его, но при этом определение производного типа должно быть включено в каждую программную единицу (главную программу или внешнюю процедуру), где используются переменные данного типа.

Это сообщение отредактировал(а) FCM - 7.6.2010, 09:51
PM MAIL   Вверх
Svetko
Дата 7.6.2010, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 31.5.2010

Репутация: нет
Всего: нет



FCM, CALL RANDOM_NUMBER эту программу мы ведь используем для вызыва подпрограммы , а у нас они должны быть записаны отдельно , 
% - это значок "растяжка" ??


Это сообщение отредактировал(а) Svetko - 7.6.2010, 17:06
PM MAIL   Вверх
FCM
Дата 7.6.2010, 20:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: нет
Всего: 9



Цитата(Svetko @  7.6.2010,  17:06 Найти цитируемый пост)
FCM, CALL RANDOM_NUMBER эту программу мы ведь используем для вызыва подпрограммы , а у нас они должны быть записаны отдельно ,

Не совсем понял это предложение.
RANDOM_NUMBER  стандартная подпрограмма. Т.е. тебе заботиться о ней не надо - просто вызываешь ее и все.

Цитата(Svetko @  7.6.2010,  17:06 Найти цитируемый пост)
% - это значок "растяжка" ??

% - это не "растяжка"! 
% - это"селектор", с помощью которого обращаются к тому или иному полю переменной производного типа. У тебя TPOINT производный тип из двух полей. Если Q - переменная типа TPOINT, то Q%X и Q%Y означают обращения  к соответсвующим полям Q. (В Visual Fortran вместо % может использоваться точка.)

Растяжка заключается в инструкциях вида 
Код

t = 10*(t - 0.5) 


Это просто линейное отображение отрезка (0.,1.) в (-5.,5.)

(Если это напрягает, выбери другой способ инициализации)

Это сообщение отредактировал(а) FCM - 8.6.2010, 08:03
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.1232 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.